Imported Upstream version 3.3.1
[debian/amanda] / perl / Amanda / Config.swg
index ddeab5ed986896767c140d86138c6cb783d1847f..4780ce934d412c8a99aea00d5806acfdea923718 100644 (file)
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2007, 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
  *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
  *
- * This library is distributed in the hope that it will be useful, but
+ * 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 Lesser General Public
- * License for more details.
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
+ * 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
  *
- * Contact information: Zmanda Inc., 505 N Mathlida Ave, Suite 120
+ * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
  */
 
 %include "amglue/amglue.swg"
 %include "exception.i"
 
+%include "Amanda/Config.pod"
+
 %{
 #include "conffile.h"
 %}
 
-%perlcode %{
-=head1 NAME
-
-Amanda::Config - access to Amanda configuration parameters
-
-=head1 SYNOPSIS
-
-  use Amanda::Config qw( :init :getconf );
-
-  config_init($CONFIG_INIT_EXPLICIT_NAME, $ARGV[1])
-    or die("errors processing config file " . $Amanda::Config::get_config_filename());
-
-  print "tape device is ", getconf($CNF_TAPEDEV), "\n";
-
-This API closely parallels the C API.  See F<conffile.h> for details
-on the functions and constants available here.
-
-=head1 API STATUS
-
-Stable
-
-=head1 INITIALIZATION
-
-The Amanda configuration is treated as a global state for the
-application.  It is not possible to load two configurations
-simultaneously.
-
-All initialization-related symbols can be imported with the tag
-C<:init>.
-
-=head2 LOADING CONFIGURATION
-
-The Amanda configuration is loaded with the aptly named
-C<config_init($flags, $name)>.  Because of the great variety in
-invocation method among Amanda applications, this function has a number
-of flags that affect its behavior.  These flags can be OR'd together.
-
-=over
-
-=item If C<CONFIG_INIT_EXPLICIT_NAME> is given, then the C<$name>
-parameter can contain the name of a configuration to load.
-
-=item If C<CONFIG_INIT_USE_CWD> is given, and if the current directory
-contains C<amanda.conf>, then that file is loaded.
-
-=item If C<CONFIG_INIT_CLIENT> is given, then a client configuration
-is loaded.
-
-=item If C<CONFIG_INIT_OVERLAY> is given, then any existing
-configuration is not reset.
-
-=item If C<CONFIG_INIT_FATAL> is given, then any errors are considered
-fatal, and C<config_init> does not return.
-
-=back
-
-See C<conffile.h> for more detailed information on these flags and
-their interactions.
-
-C<config_uninit()> reverses the effects of C<config_init>.  It is
-not often used.
-
-Once the configuration is loaded, the configuration name
-(e.g., "DailySet1"), directory (C</etc/amanda/DailySet1>),
-and filename (C</etc/amanda/DailySet1/amanda.conf>) are
-available from C<get_config_name()>, C<get_config_dir()>, and
-C<get_config_filename()>, respectively.
-
-=head2 CONFIG OVERWRITES
-
-Most Amanda applications accept the command-line option C<-o>
-to "overwrite" configuration values in C<amanda.conf>.  In Perl
-applications, these options should be parsed with L<Getopt::Long|Getopt::Long>, with
-the action being a call to C<add_config_overwrite_opt>.  For example:
-
-  my $config_overwrites = new_config_overwrites($#ARGV+1);
-    GetOptions(
-       # ...
-       'o=s' => sub { add_config_overwrite_opt($config_overwrites, $_[1]); },
-    ) or usage();
-  my $cfg_ok = config_init($CONFIG_INIT_EXPLICIT_NAME | $CONFIG_INIT_USE_CWD, $config_name);
-  apply_config_overwrites($config_overwrites);
-
-C<new_config_overwrites($size_estimate)> creates a new
-overwrites object, using the given size as an estimate of
-the number of items it will contain (C<$#ARGC/2> is a good
-estimate).  Individual configuration options are then added via
-C<add_config_overwrite($co, $key, $value)> (which takes a key/value
-pair) or C<add_config_overwrite_opt($co, $optarg)>, which parses a
-string following C<-o> on the command line.
-
-Once the overwrites are gathered, they are applied with
-C<apply_config_overwrites($co)>, which applies the overwrites to the
-active configuration.  No further operations can be performed on the
-overwrites object after C<apply_config_overwrites> has been called.
-
-The utility function C<get_config_options()> returns a list of
-command-line arguments to represent any overwrites that were used
-to generate the current configuration.  (TODO: this function isn't
-available yet)
-
-=head1 PARAMETER ACCESS
-
-Amanda configurations consist of "global" parameters and several
-sets of "subsections" -- one set for dumptypes, one for tapetypes,
-and so on.
-
-All of the global parameters are represented by a constant beginning
-with C<$CNF_>, e.g., C<$CNF_LABELSTR>.  The function C<getconf($cnf)>
-returns the value of parameter C<$cnf>, in whatever format is
-appropriate for the parameter.  C<getconf_seen($cnf)> returns a true
-value if C<$cnf> was seen in the configuration file.  If it was not
-seen, then it will have its default value.
-
-Some parameters have enumerated types.  The values for those
-enumerations are available from this module with the same name as
-in C<conffile.h>.  For example, C<$CNF_TAPERALGO> will yield a value
-from the enumeration C<taperalgo_t>, the constants for which all
-begin with C<$ALGO_>.  See C<conffile.h> for the details.
-
-Each subsection type has the following functions:
-
-=over
-
-=item C<lookup_TYP($subsec_name)>
-
-which returns an opaque object
-(C<$ss>) representing the subsection, or C<undef> if no subsection
-with that name exists;
-
-=item C<TYP_name($ss)>
-
-returning the name of the subsection;
-
-=item C<TYP_getconf($ss, $cnf)>
-
-which fetches a parameter value from C<$ss>; and
-
-=item C<TYP_seen($ss, $cnf)>
-
-which returns a true value if <$cnf> was seen in the subsection.
-
-=back
-
-The subsections are:
-
-=over
-
-=item C<tapetype>
-
-with constants beginning with C<$TAPETYPE_>
-
-=item C<dumptype>
-
-with constants beginning with C<$DUMPTYPE_>
-
-=item C<holdingdisk>
-
-with constants beginning with C<$HOLDING_>
-
-=item C<application>
-
-with constants beginning with C<$APPLICATION_>
-
-=item C<script>
-
-with constants beginning with C<$PP_SCRIPT_>
-
-=back
-
-See C<conffile.h> for the names of the constants themselves.
-
-Parameter values are available by name from C<getconf_byname($name)>.
-This function implements the C<TYP:NAME:PARAM> syntax advertised by
-C<amgetconf> to access values in subsections.  C<getconf_list($typ)>
-returns a list of the names of all subsections of the given type.
-
-The C<$CNF_DISPLAYUNIT> implies a certain divisor to convert from
-kilobytes to the desired unit.  This divisor is available from
-C<getconf_unit_divisor()>.  Note carefully that it is a I<divisor>
-for a value in I<kilobytes>!
-
-Finally, various subsections of Amanda enable verbose debugging via
-configuration parameters.  The status of each parameter is available
-a similarly-named variable, e.g., C<$debug_auth>.
-
-All parameter access functions and constants can be imported with
-the tag C<:getconf>.
-
-=head1 MISCELLANEOUS
+/*
+ * Documentation Macro
+ */
 
-These functions defy categorization.
+%define constant_pod(DESCRIPTION, FORALL_FN)
+%perlcode %{
 
-The function C<config_dir_relative> will interpret a path relative to
-the current configuration directory.  Absolute paths are passed through
-unchanged, while relative paths are converted to absolute paths.
+use Amanda::Config::FoldingHash;
 
-C<dump_configuration()> dumps the current configuration, in a format
-suitable for re-evaluation for this module, to standard output.
-This function may be revised to return a string.
+=pod
 
-Several parts of Amanda need to convert unit modifier value like
-"gbytes" to a multiplier.  The function C<find_multiplier($str)>
-returns the unit multiplier for such a string.  For example, "mbytes"
-is converted to 1048576 (1024*1024).
+DESCRIPTION: amglue_constants_list(FORALL_FN)
 
 =cut
 %}
+%enddef
 
 /*
  * Parameter access
@@ -241,152 +51,267 @@ is converted to 1048576 (1024*1024).
 
 /* All of the CNF_ flags from conffile.h */
 
+#define FOR_ALL_CONFPARM_KEY(APPLY)\
+APPLY(CNF_ORG)\
+APPLY(CNF_CONF)\
+APPLY(CNF_AMDUMP_SERVER)\
+APPLY(CNF_INDEX_SERVER)\
+APPLY(CNF_TAPE_SERVER)\
+APPLY(CNF_AUTH)\
+APPLY(CNF_SSH_KEYS)\
+APPLY(CNF_AMANDAD_PATH)\
+APPLY(CNF_CLIENT_USERNAME)\
+APPLY(CNF_CLIENT_PORT)\
+APPLY(CNF_GNUTAR_LIST_DIR)\
+APPLY(CNF_AMANDATES)\
+APPLY(CNF_MAILER)\
+APPLY(CNF_MAILTO)\
+APPLY(CNF_DUMPUSER)\
+APPLY(CNF_TAPEDEV)\
+APPLY(CNF_DEVICE_PROPERTY)\
+APPLY(CNF_PROPERTY)\
+APPLY(CNF_CHANGERDEV)\
+APPLY(CNF_CHANGERFILE)\
+APPLY(CNF_LABELSTR)\
+APPLY(CNF_AUTOLABEL)\
+APPLY(CNF_META_AUTOLABEL)\
+APPLY(CNF_TAPELIST)\
+APPLY(CNF_DISKFILE)\
+APPLY(CNF_INFOFILE)\
+APPLY(CNF_LOGDIR)\
+APPLY(CNF_INDEXDIR)\
+APPLY(CNF_TAPETYPE)\
+APPLY(CNF_DUMPCYCLE)\
+APPLY(CNF_RUNSPERCYCLE)\
+APPLY(CNF_TAPECYCLE)\
+APPLY(CNF_NETUSAGE)\
+APPLY(CNF_INPARALLEL)\
+APPLY(CNF_DUMPORDER)\
+APPLY(CNF_BUMPPERCENT)\
+APPLY(CNF_BUMPSIZE)\
+APPLY(CNF_BUMPMULT)\
+APPLY(CNF_BUMPDAYS)\
+APPLY(CNF_TPCHANGER)\
+APPLY(CNF_RUNTAPES)\
+APPLY(CNF_MAX_DLE_BY_VOLUME)\
+APPLY(CNF_MAXDUMPS)\
+APPLY(CNF_ETIMEOUT)\
+APPLY(CNF_DTIMEOUT)\
+APPLY(CNF_CTIMEOUT)\
+APPLY(CNF_DEVICE_OUTPUT_BUFFER_SIZE)\
+APPLY(CNF_PRINTER)\
+APPLY(CNF_AUTOFLUSH)\
+APPLY(CNF_RESERVE)\
+APPLY(CNF_MAXDUMPSIZE)\
+APPLY(CNF_COLUMNSPEC)\
+APPLY(CNF_AMRECOVER_DO_FSF)\
+APPLY(CNF_AMRECOVER_CHECK_LABEL)\
+APPLY(CNF_AMRECOVER_CHANGER)\
+APPLY(CNF_TAPERALGO)\
+APPLY(CNF_FLUSH_THRESHOLD_DUMPED)\
+APPLY(CNF_FLUSH_THRESHOLD_SCHEDULED)\
+APPLY(CNF_TAPERFLUSH)\
+APPLY(CNF_DISPLAYUNIT)\
+APPLY(CNF_KRB5KEYTAB)\
+APPLY(CNF_KRB5PRINCIPAL)\
+APPLY(CNF_LABEL_NEW_TAPES)\
+APPLY(CNF_USETIMESTAMPS)\
+APPLY(CNF_REP_TRIES)\
+APPLY(CNF_CONNECT_TRIES)\
+APPLY(CNF_REQ_TRIES)\
+APPLY(CNF_DEBUG_AMANDAD)\
+APPLY(CNF_DEBUG_RECOVERY)\
+APPLY(CNF_DEBUG_AMIDXTAPED)\
+APPLY(CNF_DEBUG_AMINDEXD)\
+APPLY(CNF_DEBUG_AMRECOVER)\
+APPLY(CNF_DEBUG_AUTH)\
+APPLY(CNF_DEBUG_EVENT)\
+APPLY(CNF_DEBUG_HOLDING)\
+APPLY(CNF_DEBUG_PROTOCOL)\
+APPLY(CNF_DEBUG_PLANNER)\
+APPLY(CNF_DEBUG_DRIVER)\
+APPLY(CNF_DEBUG_DUMPER)\
+APPLY(CNF_DEBUG_CHUNKER)\
+APPLY(CNF_DEBUG_TAPER)\
+APPLY(CNF_DEBUG_SELFCHECK)\
+APPLY(CNF_DEBUG_SENDSIZE)\
+APPLY(CNF_DEBUG_SENDBACKUP)\
+APPLY(CNF_RESERVED_UDP_PORT)\
+APPLY(CNF_RESERVED_TCP_PORT)\
+APPLY(CNF_UNRESERVED_TCP_PORT)\
+APPLY(CNF_HOLDINGDISK)\
+APPLY(CNF_SEND_AMREPORT_ON)\
+APPLY(CNF_TAPER_PARALLEL_WRITE)\
+APPLY(CNF_RECOVERY_LIMIT) \
+APPLY(CNF_INTERACTIVITY) \
+APPLY(CNF_TAPERSCAN) \
+APPLY(CNF_EJECT_VOLUME)
+
 amglue_add_enum_tag_fns(confparm_key);
-amglue_add_constant(CNF_ORG, confparm_key);
-amglue_add_constant(CNF_CONF, confparm_key);
-amglue_add_constant(CNF_INDEX_SERVER, confparm_key);
-amglue_add_constant(CNF_TAPE_SERVER, confparm_key);
-amglue_add_constant(CNF_AUTH, confparm_key);
-amglue_add_constant(CNF_SSH_KEYS, confparm_key);
-amglue_add_constant(CNF_AMANDAD_PATH, confparm_key);
-amglue_add_constant(CNF_CLIENT_USERNAME, confparm_key);
-amglue_add_constant(CNF_GNUTAR_LIST_DIR, confparm_key);
-amglue_add_constant(CNF_AMANDATES, confparm_key);
-amglue_add_constant(CNF_MAILTO, confparm_key);
-amglue_add_constant(CNF_DUMPUSER, confparm_key);
-amglue_add_constant(CNF_TAPEDEV, confparm_key);
-amglue_add_constant(CNF_DEVICE_PROPERTY, confparm_key);
-amglue_add_constant(CNF_CHANGERDEV, confparm_key);
-amglue_add_constant(CNF_CHANGERFILE, confparm_key);
-amglue_add_constant(CNF_LABELSTR, confparm_key);
-amglue_add_constant(CNF_TAPELIST, confparm_key);
-amglue_add_constant(CNF_DISKFILE, confparm_key);
-amglue_add_constant(CNF_INFOFILE, confparm_key);
-amglue_add_constant(CNF_LOGDIR, confparm_key);
-amglue_add_constant(CNF_INDEXDIR, confparm_key);
-amglue_add_constant(CNF_TAPETYPE, confparm_key);
-amglue_add_constant(CNF_DUMPCYCLE, confparm_key);
-amglue_add_constant(CNF_RUNSPERCYCLE, confparm_key);
-amglue_add_constant(CNF_TAPECYCLE, confparm_key);
-amglue_add_constant(CNF_NETUSAGE, confparm_key);
-amglue_add_constant(CNF_INPARALLEL, confparm_key);
-amglue_add_constant(CNF_DUMPORDER, confparm_key);
-amglue_add_constant(CNF_BUMPPERCENT, confparm_key);
-amglue_add_constant(CNF_BUMPSIZE, confparm_key);
-amglue_add_constant(CNF_BUMPMULT, confparm_key);
-amglue_add_constant(CNF_BUMPDAYS, confparm_key);
-amglue_add_constant(CNF_TPCHANGER, confparm_key);
-amglue_add_constant(CNF_RUNTAPES, confparm_key);
-amglue_add_constant(CNF_MAXDUMPS, confparm_key);
-amglue_add_constant(CNF_ETIMEOUT, confparm_key);
-amglue_add_constant(CNF_DTIMEOUT, confparm_key);
-amglue_add_constant(CNF_CTIMEOUT, confparm_key);
-amglue_add_constant(CNF_TAPEBUFS, confparm_key);
-amglue_add_constant(CNF_DEVICE_OUTPUT_BUFFER_SIZE, confparm_key);
-amglue_add_constant(CNF_PRINTER, confparm_key);
-amglue_add_constant(CNF_AUTOFLUSH, confparm_key);
-amglue_add_constant(CNF_RESERVE, confparm_key);
-amglue_add_constant(CNF_MAXDUMPSIZE, confparm_key);
-amglue_add_constant(CNF_COLUMNSPEC, confparm_key);
-amglue_add_constant(CNF_AMRECOVER_DO_FSF, confparm_key);
-amglue_add_constant(CNF_AMRECOVER_CHECK_LABEL, confparm_key);
-amglue_add_constant(CNF_AMRECOVER_CHANGER, confparm_key);
-amglue_add_constant(CNF_TAPERALGO, confparm_key);
-amglue_add_constant(CNF_FLUSH_THRESHOLD_DUMPED, confparm_key);
-amglue_add_constant(CNF_FLUSH_THRESHOLD_SCHEDULED, confparm_key);
-amglue_add_constant(CNF_TAPERFLUSH, confparm_key);
-amglue_add_constant(CNF_DISPLAYUNIT, confparm_key);
-amglue_add_constant(CNF_KRB5KEYTAB, confparm_key);
-amglue_add_constant(CNF_KRB5PRINCIPAL, confparm_key);
-amglue_add_constant(CNF_LABEL_NEW_TAPES, confparm_key);
-amglue_add_constant(CNF_USETIMESTAMPS, confparm_key);
-amglue_add_constant(CNF_REP_TRIES, confparm_key);
-amglue_add_constant(CNF_CONNECT_TRIES, confparm_key);
-amglue_add_constant(CNF_REQ_TRIES, confparm_key);
-amglue_add_constant(CNF_DEBUG_AMANDAD, confparm_key);
-amglue_add_constant(CNF_DEBUG_AMIDXTAPED, confparm_key);
-amglue_add_constant(CNF_DEBUG_AMINDEXD, confparm_key);
-amglue_add_constant(CNF_DEBUG_AMRECOVER, confparm_key);
-amglue_add_constant(CNF_DEBUG_AUTH, confparm_key);
-amglue_add_constant(CNF_DEBUG_EVENT, confparm_key);
-amglue_add_constant(CNF_DEBUG_HOLDING, confparm_key);
-amglue_add_constant(CNF_DEBUG_PROTOCOL, confparm_key);
-amglue_add_constant(CNF_DEBUG_PLANNER, confparm_key);
-amglue_add_constant(CNF_DEBUG_DRIVER, confparm_key);
-amglue_add_constant(CNF_DEBUG_DUMPER, confparm_key);
-amglue_add_constant(CNF_DEBUG_CHUNKER, confparm_key);
-amglue_add_constant(CNF_DEBUG_TAPER, confparm_key);
-amglue_add_constant(CNF_DEBUG_SELFCHECK, confparm_key);
-amglue_add_constant(CNF_DEBUG_SENDSIZE, confparm_key);
-amglue_add_constant(CNF_DEBUG_SENDBACKUP, confparm_key);
-amglue_add_constant(CNF_RESERVED_UDP_PORT, confparm_key);
-amglue_add_constant(CNF_RESERVED_TCP_PORT, confparm_key);
-amglue_add_constant(CNF_UNRESERVED_TCP_PORT, confparm_key);
+amglue_add_constants(FOR_ALL_CONFPARM_KEY, confparm_key);
 amglue_copy_to_tag(confparm_key, getconf);
+constant_pod(Global Parameters, FOR_ALL_CONFPARM_KEY)
+
+#define FOR_ALL_TAPETYPE_KEY(APPLY)\
+APPLY(TAPETYPE_COMMENT)\
+APPLY(TAPETYPE_LBL_TEMPL)\
+APPLY(TAPETYPE_BLOCKSIZE)\
+APPLY(TAPETYPE_READBLOCKSIZE)\
+APPLY(TAPETYPE_LENGTH)\
+APPLY(TAPETYPE_FILEMARK)\
+APPLY(TAPETYPE_SPEED)\
+APPLY(TAPETYPE_PART_SIZE)\
+APPLY(TAPETYPE_PART_CACHE_TYPE)\
+APPLY(TAPETYPE_PART_CACHE_DIR)\
+APPLY(TAPETYPE_PART_CACHE_MAX_SIZE)
 
 amglue_add_enum_tag_fns(tapetype_key);
-amglue_add_constant(TAPETYPE_COMMENT, tapetype_key);
-amglue_add_constant(TAPETYPE_LBL_TEMPL, tapetype_key);
-amglue_add_constant(TAPETYPE_BLOCKSIZE, tapetype_key);
-amglue_add_constant(TAPETYPE_READBLOCKSIZE, tapetype_key);
-amglue_add_constant(TAPETYPE_LENGTH, tapetype_key);
-amglue_add_constant(TAPETYPE_FILEMARK, tapetype_key);
-amglue_add_constant(TAPETYPE_SPEED, tapetype_key);
-amglue_add_constant(TAPETYPE_FILE_PAD, tapetype_key);
+amglue_add_constants(FOR_ALL_TAPETYPE_KEY, tapetype_key);
 amglue_copy_to_tag(tapetype_key, getconf);
+constant_pod(Tapetype Parameters, FOR_ALL_TAPETYPE_KEY)
+
+#define FOR_ALL_DUMPTYPE_KEY(APPLY)\
+APPLY(DUMPTYPE_COMMENT)\
+APPLY(DUMPTYPE_PROGRAM)\
+APPLY(DUMPTYPE_SRVCOMPPROG)\
+APPLY(DUMPTYPE_CLNTCOMPPROG)\
+APPLY(DUMPTYPE_SRV_ENCRYPT)\
+APPLY(DUMPTYPE_CLNT_ENCRYPT)\
+APPLY(DUMPTYPE_AMANDAD_PATH)\
+APPLY(DUMPTYPE_CLIENT_USERNAME)\
+APPLY(DUMPTYPE_CLIENT_PORT)\
+APPLY(DUMPTYPE_SSH_KEYS)\
+APPLY(DUMPTYPE_AUTH)\
+APPLY(DUMPTYPE_EXCLUDE)\
+APPLY(DUMPTYPE_INCLUDE)\
+APPLY(DUMPTYPE_PRIORITY)\
+APPLY(DUMPTYPE_DUMPCYCLE)\
+APPLY(DUMPTYPE_MAXDUMPS)\
+APPLY(DUMPTYPE_MAXPROMOTEDAY)\
+APPLY(DUMPTYPE_BUMPPERCENT)\
+APPLY(DUMPTYPE_BUMPSIZE)\
+APPLY(DUMPTYPE_BUMPDAYS)\
+APPLY(DUMPTYPE_BUMPMULT)\
+APPLY(DUMPTYPE_STARTTIME)\
+APPLY(DUMPTYPE_STRATEGY)\
+APPLY(DUMPTYPE_ESTIMATELIST)\
+APPLY(DUMPTYPE_COMPRESS)\
+APPLY(DUMPTYPE_ENCRYPT)\
+APPLY(DUMPTYPE_SRV_DECRYPT_OPT)\
+APPLY(DUMPTYPE_CLNT_DECRYPT_OPT)\
+APPLY(DUMPTYPE_COMPRATE)\
+APPLY(DUMPTYPE_TAPE_SPLITSIZE)\
+APPLY(DUMPTYPE_FALLBACK_SPLITSIZE)\
+APPLY(DUMPTYPE_SPLIT_DISKBUFFER)\
+APPLY(DUMPTYPE_RECORD)\
+APPLY(DUMPTYPE_SKIP_INCR)\
+APPLY(DUMPTYPE_SKIP_FULL)\
+APPLY(DUMPTYPE_HOLDINGDISK)\
+APPLY(DUMPTYPE_KENCRYPT)\
+APPLY(DUMPTYPE_IGNORE)\
+APPLY(DUMPTYPE_INDEX)\
+APPLY(DUMPTYPE_APPLICATION)\
+APPLY(DUMPTYPE_SCRIPTLIST)\
+APPLY(DUMPTYPE_PROPERTY)\
+APPLY(DUMPTYPE_DATA_PATH)\
+APPLY(DUMPTYPE_ALLOW_SPLIT)\
+APPLY(DUMPTYPE_RECOVERY_LIMIT) \
+APPLY(DUMPTYPE_DUMP_LIMIT)
 
 amglue_add_enum_tag_fns(dumptype_key);
-amglue_add_constant(DUMPTYPE_COMMENT, dumptype_key);
-amglue_add_constant(DUMPTYPE_PROGRAM, dumptype_key);
-amglue_add_constant(DUMPTYPE_SRVCOMPPROG, dumptype_key);
-amglue_add_constant(DUMPTYPE_CLNTCOMPPROG, dumptype_key);
-amglue_add_constant(DUMPTYPE_SRV_ENCRYPT, dumptype_key);
-amglue_add_constant(DUMPTYPE_CLNT_ENCRYPT, dumptype_key);
-amglue_add_constant(DUMPTYPE_AMANDAD_PATH, dumptype_key);
-amglue_add_constant(DUMPTYPE_CLIENT_USERNAME, dumptype_key);
-amglue_add_constant(DUMPTYPE_SSH_KEYS, dumptype_key);
-amglue_add_constant(DUMPTYPE_SECURITY_DRIVER, dumptype_key);
-amglue_add_constant(DUMPTYPE_EXCLUDE, dumptype_key);
-amglue_add_constant(DUMPTYPE_INCLUDE, dumptype_key);
-amglue_add_constant(DUMPTYPE_PRIORITY, dumptype_key);
-amglue_add_constant(DUMPTYPE_DUMPCYCLE, dumptype_key);
-amglue_add_constant(DUMPTYPE_MAXDUMPS, dumptype_key);
-amglue_add_constant(DUMPTYPE_MAXPROMOTEDAY, dumptype_key);
-amglue_add_constant(DUMPTYPE_BUMPPERCENT, dumptype_key);
-amglue_add_constant(DUMPTYPE_BUMPSIZE, dumptype_key);
-amglue_add_constant(DUMPTYPE_BUMPDAYS, dumptype_key);
-amglue_add_constant(DUMPTYPE_BUMPMULT, dumptype_key);
-amglue_add_constant(DUMPTYPE_STARTTIME, dumptype_key);
-amglue_add_constant(DUMPTYPE_STRATEGY, dumptype_key);
-amglue_add_constant(DUMPTYPE_ESTIMATE, dumptype_key);
-amglue_add_constant(DUMPTYPE_COMPRESS, dumptype_key);
-amglue_add_constant(DUMPTYPE_ENCRYPT, dumptype_key);
-amglue_add_constant(DUMPTYPE_SRV_DECRYPT_OPT, dumptype_key);
-amglue_add_constant(DUMPTYPE_CLNT_DECRYPT_OPT, dumptype_key);
-amglue_add_constant(DUMPTYPE_COMPRATE, dumptype_key);
-amglue_add_constant(DUMPTYPE_TAPE_SPLITSIZE, dumptype_key);
-amglue_add_constant(DUMPTYPE_FALLBACK_SPLITSIZE, dumptype_key);
-amglue_add_constant(DUMPTYPE_SPLIT_DISKBUFFER, dumptype_key);
-amglue_add_constant(DUMPTYPE_RECORD, dumptype_key);
-amglue_add_constant(DUMPTYPE_SKIP_INCR, dumptype_key);
-amglue_add_constant(DUMPTYPE_SKIP_FULL, dumptype_key);
-amglue_add_constant(DUMPTYPE_HOLDINGDISK, dumptype_key);
-amglue_add_constant(DUMPTYPE_KENCRYPT, dumptype_key);
-amglue_add_constant(DUMPTYPE_IGNORE, dumptype_key);
-amglue_add_constant(DUMPTYPE_INDEX, dumptype_key);
+amglue_add_constants(FOR_ALL_DUMPTYPE_KEY, dumptype_key);
 amglue_copy_to_tag(dumptype_key, getconf);
+constant_pod(Dumptype Parameters, FOR_ALL_DUMPTYPE_KEY)
+
+#define FOR_ALL_INTERFACE_KEY(APPLY)\
+APPLY(INTER_COMMENT)\
+APPLY(INTER_MAXUSAGE)
 
 amglue_add_enum_tag_fns(interface_key);
-amglue_add_constant(INTER_COMMENT, interface_key);
-amglue_add_constant(INTER_MAXUSAGE, interface_key);
+amglue_add_constants(FOR_ALL_INTERFACE_KEY, interface_key);
 amglue_copy_to_tag(interface_key, getconf);
+constant_pod(Dumptype Parameters, FOR_ALL_INTERFACE_KEY)
+
+#define FOR_ALL_HOLDINGDISK_KEY(APPLY)\
+APPLY(HOLDING_COMMENT)\
+APPLY(HOLDING_DISKDIR)\
+APPLY(HOLDING_DISKSIZE)\
+APPLY(HOLDING_CHUNKSIZE)
 
 amglue_add_enum_tag_fns(holdingdisk_key);
-amglue_add_constant(HOLDING_COMMENT, holdingdisk_key);
-amglue_add_constant(HOLDING_DISKDIR, holdingdisk_key);
-amglue_add_constant(HOLDING_DISKSIZE, holdingdisk_key);
-amglue_add_constant(HOLDING_CHUNKSIZE, holdingdisk_key);
+amglue_add_constants(FOR_ALL_HOLDINGDISK_KEY, holdingdisk_key);
 amglue_copy_to_tag(holdingdisk_key, getconf);
+constant_pod(Holdingdisk Parameters, FOR_ALL_HOLDINGDISK_KEY)
+
+#define FOR_ALL_APPLICATION_KEY(APPLY)\
+APPLY(APPLICATION_COMMENT)\
+APPLY(APPLICATION_PLUGIN)\
+APPLY(APPLICATION_PROPERTY) \
+APPLY(APPLICATION_CLIENT_NAME)
+
+amglue_add_enum_tag_fns(application_key);
+amglue_add_constants(FOR_ALL_APPLICATION_KEY, application_key);
+amglue_copy_to_tag(application_key, getconf);
+constant_pod(Application Parameters, FOR_ALL_APPLICATION_KEY)
+
+#define FOR_ALL_PP_SCRIPT_KEY(APPLY)\
+APPLY(PP_SCRIPT_COMMENT)\
+APPLY(PP_SCRIPT_PLUGIN)\
+APPLY(PP_SCRIPT_PROPERTY)\
+APPLY(PP_SCRIPT_EXECUTE_ON)\
+APPLY(PP_SCRIPT_EXECUTE_WHERE)\
+APPLY(PP_SCRIPT_ORDER)\
+APPLY(PP_SCRIPT_SINGLE_EXECUTION)\
+APPLY(PP_SCRIPT_CLIENT_NAME)
+
+amglue_add_enum_tag_fns(pp_script_key);
+amglue_add_constants(FOR_ALL_PP_SCRIPT_KEY, pp_script_key);
+amglue_copy_to_tag(pp_script_key, getconf);
+constant_pod(Pre/Post-Script Parameters, FOR_ALL_PP_SCRIPT_KEY)
+
+#define FOR_ALL_DEVICE_CONFIG_KEY(APPLY)\
+APPLY(DEVICE_CONFIG_COMMENT)\
+APPLY(DEVICE_CONFIG_TAPEDEV)\
+APPLY(DEVICE_CONFIG_DEVICE_PROPERTY)
+
+amglue_add_enum_tag_fns(device_config_key);
+amglue_add_constants(FOR_ALL_DEVICE_CONFIG_KEY, device_config_key);
+amglue_copy_to_tag(device_config_key, getconf);
+constant_pod(Pre/Post-Script Parameters, FOR_ALL_DEVICE_CONFIG_KEY)
+
+#define FOR_ALL_CHANGER_CONFIG_KEY(APPLY)\
+APPLY(CHANGER_CONFIG_COMMENT)\
+APPLY(CHANGER_CONFIG_TAPEDEV)\
+APPLY(CHANGER_CONFIG_TPCHANGER)\
+APPLY(CHANGER_CONFIG_CHANGERDEV)\
+APPLY(CHANGER_CONFIG_CHANGERFILE)\
+APPLY(CHANGER_CONFIG_PROPERTY)\
+APPLY(CHANGER_CONFIG_DEVICE_PROPERTY)
+
+amglue_add_enum_tag_fns(changer_config_key);
+amglue_add_constants(FOR_ALL_CHANGER_CONFIG_KEY, changer_config_key);
+amglue_copy_to_tag(changer_config_key, getconf);
+constant_pod(Pre/Post-Script Parameters, FOR_ALL_CHANGER_CONFIG_KEY)
+
+#define FOR_ALL_INTERACTIVITY_KEY(APPLY)\
+APPLY(INTERACTIVITY_COMMENT)\
+APPLY(INTERACTIVITY_PLUGIN)\
+APPLY(INTERACTIVITY_PROPERTY)
+
+amglue_add_enum_tag_fns(interactivity_key);
+amglue_add_constants(FOR_ALL_INTERACTIVITY_KEY, interactivity_key);
+amglue_copy_to_tag(interactivity_key, getconf);
+constant_pod(Interactivity Parameters, FOR_ALL_INTERACTIVITY_KEY)
+
+#define FOR_ALL_TAPERSCAN_KEY(APPLY)\
+APPLY(TAPERSCAN_COMMENT)\
+APPLY(TAPERSCAN_PLUGIN)\
+APPLY(TAPERSCAN_PROPERTY)
+
+amglue_add_enum_tag_fns(taperscan_key);
+amglue_add_constants(FOR_ALL_TAPERSCAN_KEY, taperscan_key);
+amglue_copy_to_tag(taperscan_key, getconf);
+constant_pod(Taperscan Parameters, FOR_ALL_TAPERSCAN_KEY)
 
 /*
  * Various enumerated conftypes
@@ -431,6 +356,13 @@ amglue_add_constant(ES_SERVER, estimate_t);
 amglue_add_constant(ES_CALCSIZE, estimate_t);
 amglue_copy_to_tag(estimate_t, getconf);
 
+amglue_add_enum_tag_fns(autolabel_enum_t);
+amglue_add_constant(AL_OTHER_CONFIG, autolabel_enum_t);
+amglue_add_constant(AL_NON_AMANDA, autolabel_enum_t);
+amglue_add_constant(AL_VOLUME_ERROR, autolabel_enum_t);
+amglue_add_constant(AL_EMPTY, autolabel_enum_t);
+amglue_copy_to_tag(autolabel_enum_t, getconf);
+
 amglue_add_enum_tag_fns(taperalgo_t);
 amglue_add_constant(ALGO_FIRST, taperalgo_t);
 amglue_add_constant(ALGO_FIRSTFIT, taperalgo_t);
@@ -440,143 +372,282 @@ amglue_add_constant(ALGO_SMALLEST, taperalgo_t);
 amglue_add_constant(ALGO_LAST, taperalgo_t);
 amglue_copy_to_tag(taperalgo_t, getconf);
 
+amglue_add_enum_tag_fns(execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_AMCHECK, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_DLE_AMCHECK, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_HOST_AMCHECK, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_AMCHECK, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_DLE_AMCHECK, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_HOST_AMCHECK, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_ESTIMATE, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_DLE_ESTIMATE, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_HOST_ESTIMATE, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_ESTIMATE, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_DLE_ESTIMATE, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_HOST_ESTIMATE, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_BACKUP, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_DLE_BACKUP, execute_on_t);
+amglue_add_constant(EXECUTE_ON_PRE_HOST_BACKUP, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_BACKUP, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_DLE_BACKUP, execute_on_t);
+amglue_add_constant(EXECUTE_ON_POST_HOST_BACKUP, execute_on_t);
+amglue_copy_to_tag(execute_on_t, getconf);
+
+amglue_add_enum_tag_fns(send_amreport_on_t);
+amglue_add_constant(SEND_AMREPORT_ALL, send_amreport_on_t);
+amglue_add_constant(SEND_AMREPORT_STRANGE, send_amreport_on_t);
+amglue_add_constant(SEND_AMREPORT_ERROR, send_amreport_on_t);
+amglue_add_constant(SEND_AMREPORT_NEVER, send_amreport_on_t);
+amglue_copy_to_tag(send_amreport_on_t, getconf);
+
+amglue_add_enum_tag_fns(data_path_t);
+amglue_add_constant(DATA_PATH_AMANDA, data_path_t);
+amglue_add_constant(DATA_PATH_DIRECTTCP, data_path_t);
+amglue_copy_to_tag(data_path_t, getconf);
+
+amglue_add_enum_tag_fns(part_cache_type_t);
+amglue_add_constant(PART_CACHE_TYPE_NONE, part_cache_type_t);
+amglue_add_constant(PART_CACHE_TYPE_DISK, part_cache_type_t);
+amglue_add_constant(PART_CACHE_TYPE_MEMORY, part_cache_type_t);
+amglue_copy_to_tag(part_cache_type_t, getconf);
+
 /*
  * val_t typemaps
  */
 
-/* Typemap to convert a val_t, the union in which config values are
- * stored, to a Perl value of the appropriate type.  This converts:
- *  - CONFTYPE_SIZE, CONFTYPE_INT, CONFTYPE_AM64,
+/* Typemap to convert a val_t to an SV, using a static function since it's huge.  This converts:
+ *  - CONFTYPE_SIZE, CONFTYPE_INT, CONFTYPE_INT64, CONFTYPE_NO_YES_ALL,
  *    CONFTYPE_BOOLEAN -> IV
  *  - CONFTYPE_REAL -> NV
  *  - CONFTYPE_STR, CONFTYPE_IDENT -> PV
+ *  - CONFTYPE_APPLICATION -> PV
  *  - CONFTYPE_TIME -> IV (epoch timestamp)
- *  - CONFTYPE_COMPRESS, CONFTYPE_ENCRYPT, CONFTYPE_ESTIMATE, CONFTYPE_STRATEGY,
- *    CONFTYPE_TAPERALGO, CONFTYPE_PRIORITY, CONFTYPE_HOLDING -> IV (enums)
+ *  - CONFTYPE_COMPRESS, CONFTYPE_ENCRYPT, CONFTYPE_ESTIMATELIST, CONFTYPE_STRATEGY,
+ *    CONFTYPE_TAPERALGO, CONFTYPE_PRIORITY, CONFTYPE_HOLDING, CONFTYPE_EXECUTE_ON,
+ *    CONFTYPE_EXECUTE_WHERE, CONFTYPE_SEND_AMREPORT_ON,
+ *    CONFTYPE_DATA_PATH, CONFTYPE_PART_CACHE_TYPE -> IV (enums)
  *  - CONFTYPE_RATE -> list of two NVs
  *  - CONFTYPE_INTRANGE -> list of two IVs
- *  - CONFTYPE_EXINCLUDE -> hashref with keys 'list' (listref), 'file' (listref), 
+ *  - CONFTYPE_EXINCLUDE -> hashref with keys 'list' (listref), 'file' (listref),
  *    and 'optional' (int)
- *  - CONFTYPE_PROPLIST -> hashref
+ *  - CONFTYPE_PROPLIST -> hashref of hashref with keys 'append' (IV), 'priority' (IV),
+ *                                                     'values' (listref)
+ *  - CONFTYPE_HOST_LIMIT -> listref of match expressions;
+ *           "SAMEHOST-SAMEHOST-SAMEHOST" in list is taken to mean 'same-host'
+ *           "SERVER-SERVER-SERVER" in list is taken to mean 'server'
  */
-%typemap (out) val_t * {
-    switch ($1->type) {
-       case CONFTYPE_RATE: {
-           $result= sv_newmortal();
-           sv_setnv($result, val_t__rate($1)[0]);
-           argvi++;
-
-           $result= sv_newmortal();
-           sv_setnv($result, val_t__rate($1)[1]);
-           argvi++;
-           break;
-       }
 
-       case CONFTYPE_INTRANGE: {
-           $result= sv_newmortal();
-           sv_setiv($result, val_t__intrange($1)[0]);
-           argvi++;
+%perlcode %{
+$LIMIT_SAMEHOST="SAMEHOST-SAMEHOST-SAMEHOST";
+$LIMIT_SERVER="SERVER-SERVER-SERVER";
+%}
 
-           $result= sv_newmortal();
-           sv_setiv($result, val_t__intrange($1)[1]);
-           argvi++;
-           break;
-           break;
-       }
+%{
+static int
+val_t_to_sv(val_t *val, SV **results) {
+    if (!val) {
+       results[0] = &PL_sv_undef;
+       return 1;
+    } else {
+       switch (val->type) {
+           case CONFTYPE_RATE: {
+               results[0] = sv_newmortal();
+               sv_setnv(results[0], val_t__rate(val)[0]);
+
+               results[1] = sv_newmortal();
+               sv_setnv(results[1], val_t__rate(val)[1]);
+               return 2;
+           }
+
+           case CONFTYPE_INTRANGE: {
+               results[0] = sv_newmortal();
+               sv_setiv(results[0], val_t__intrange(val)[0]);
+
+               results[1] = sv_newmortal();
+               sv_setiv(results[1], val_t__intrange(val)[1]);
+               return 2;
+           }
+
+           case CONFTYPE_EXINCLUDE: {
+               /* exincludes are represented in perl as {
+                *      'list' : [ 'list1', 'list2', ..],
+                *      'file' : [ 'file1', 'file2', ..],
+                *      'optional' : 1,
+                * }
+                */
+               exinclude_t *ei = &val_t__exinclude(val);
+               AV *list_entries = (AV *)sv_2mortal((SV *)newAV());
+               AV *file_entries = (AV *)sv_2mortal((SV *)newAV());
+               SV *optional = sv_newmortal();
+               HV *hv;
+               sle_t *iter;
+
+               /* first set up each of the hash values */
+
+               if (ei->sl_list) {
+                   for (iter = ei->sl_list->first; iter != NULL; iter = iter->next) {
+                       av_push(list_entries, newSVpv(iter->name, 0));
+                   }
+               }
+
+               if(ei->sl_file) {
+                   for (iter = ei->sl_file->first; iter != NULL; iter = iter->next) {
+                       av_push(file_entries, newSVpv(iter->name, 0));
+                   }
+               }
+
+               sv_setiv(optional, ei->optional);
+
+               /* now build the hash */
+               hv = (HV *)sv_2mortal((SV *)newHV());
+               
+               hv_store(hv, "file", 4, newRV((SV *)file_entries), 0);
+               hv_store(hv, "list", 4, newRV((SV *)list_entries), 0);
+               hv_store(hv, "optional", 8, optional, 0);
+               SvREFCNT_inc(optional);
 
-       case CONFTYPE_EXINCLUDE: {
-           /* exincludes are represented in perl as {
-            *  'list' : [ 'list1', 'list2', ..],
-            *  'file' : [ 'file1', 'file2', ..],
-            *  'optional' : 1,
-            * }
-            */
-           exinclude_t *ei = &val_t__exinclude($1);
-           AV *list_entries = (AV *)sv_2mortal((SV *)newAV());
-           AV *file_entries = (AV *)sv_2mortal((SV *)newAV());
-           SV *optional = sv_newmortal();
-           HV *hv;
-           sle_t *iter;
-
-           /* first set up each of the hash values */
-
-           if (ei->sl_list) {
-               for (iter = ei->sl_list->first; iter != NULL; iter = iter->next) {
-                   av_push(list_entries, newSVpv(iter->name, 0));
+               results[0] = sv_2mortal(newRV((SV *)hv));
+               return 1;
+           }
+
+           case CONFTYPE_PROPLIST:
+               results[0] = sv_2mortal(g_hash_table_to_hashref_property(val_t__proplist(val)));
+               return 1;
+
+           case CONFTYPE_SIZE:
+               results[0] = sv_2mortal(amglue_newSVi64(val_t__size(val)));
+               return 1;
+
+           case CONFTYPE_INT64:
+               results[0] = sv_2mortal(amglue_newSVi64(val_t__int64(val)));
+               return 1;
+
+           case CONFTYPE_BOOLEAN:          /* all same as INT.. */
+           case CONFTYPE_NO_YES_ALL:
+           case CONFTYPE_COMPRESS:
+           case CONFTYPE_ENCRYPT:
+           case CONFTYPE_STRATEGY:
+           case CONFTYPE_TAPERALGO:
+           case CONFTYPE_PRIORITY:
+           case CONFTYPE_HOLDING:
+           case CONFTYPE_EXECUTE_ON:
+           case CONFTYPE_EXECUTE_WHERE:
+           case CONFTYPE_SEND_AMREPORT_ON:
+           case CONFTYPE_DATA_PATH:
+           case CONFTYPE_PART_CACHE_TYPE:
+           case CONFTYPE_INT:
+               results[0] = sv_2mortal(amglue_newSVi64(val_t__int(val)));
+               return 1;
+
+           case CONFTYPE_ESTIMATELIST: {
+               AV *elist = newAV();
+               estimatelist_t el;
+               for (el=val_t__estimatelist(val); el != NULL; el = el->next) {
+                   av_push(elist, newSVuv(GPOINTER_TO_INT(el->data)));
                }
+               results[0] = sv_2mortal(newRV_noinc((SV *)elist));
+               return 1;
            }
 
-           if(ei->sl_file) {
-               for (iter = ei->sl_file->first; iter != NULL; iter = iter->next) {
-                   av_push(file_entries, newSVpv(iter->name, 0));
+           case CONFTYPE_TIME:
+               results[0] = sv_2mortal(amglue_newSVi64(val_t__time(val)));
+               return 1;
+
+           case CONFTYPE_REAL:
+               results[0] = sv_newmortal();
+               sv_setnv(results[0], val_t__real(val));
+               return 1;
+
+           case CONFTYPE_IDENT:            /* same as STRING */
+           case CONFTYPE_STR:
+           case CONFTYPE_APPLICATION:
+               results[0] = sv_newmortal();
+               sv_setpv(results[0], val_t__str(val));
+               return 1;
+
+           case CONFTYPE_IDENTLIST: {
+               AV *ilist = newAV();
+
+               identlist_t il;
+               for (il=val_t__identlist(val); il != NULL; il = il->next) {
+                   av_push(ilist, newSVpv((char *)il->data, 0));
                }
+
+               results[0] = sv_2mortal(newRV_noinc((SV *)ilist));
+               return 1;
            }
 
-           sv_setiv(optional, ei->optional);
+           case CONFTYPE_HOST_LIMIT: {
+               AV *av;
+               GSList *iter;
+               host_limit_t *rl = &val_t__host_limit(val);
+
+               av = newAV();
+               if (rl->same_host)
+                   av_push(av, newSVpv("SAMEHOST-SAMEHOST-SAMEHOST", 0));
+               if (rl->server)
+                   av_push(av, newSVpv("SERVER-SERVER-SERVER", 0));
+               for (iter=rl->match_pats; iter != NULL; iter = iter->next) {
+                   av_push(av, newSVpv((char *)iter->data, 0));
+               }
+
+               results[0] = sv_2mortal(newRV_noinc((SV *)av));
+               return 1;
+           }
 
-           /* now build the hash */
-           hv = (HV *)sv_2mortal((SV *)newHV());
-           
-           hv_store(hv, "file", 4, newRV((SV *)file_entries), 0);
-           hv_store(hv, "list", 4, newRV((SV *)list_entries), 0);
-           hv_store(hv, "optional", 8, optional, 0);
-           SvREFCNT_inc(optional);
+           case CONFTYPE_AUTOLABEL: {
+               autolabel_t *autolabel = &val_t__autolabel(val);
+               HV *hv;
+
+               /* now build the hash */
+               hv = (HV *)sv_2mortal((SV *)newHV());
+               hv_store(hv, "template", 8,
+                       (autolabel->template)? newSVpv(autolabel->template, 0) : newSV(0),
+                       0);
+               hv_store(hv, "other_config", 12,
+                       (autolabel->autolabel & AL_OTHER_CONFIG)? &PL_sv_yes : &PL_sv_no,
+                       0);
+               hv_store(hv, "non_amanda", 10,
+                       (autolabel->autolabel & AL_NON_AMANDA)? &PL_sv_yes : &PL_sv_no,
+                       0);
+               hv_store(hv, "volume_error", 12,
+                       (autolabel->autolabel & AL_VOLUME_ERROR)? &PL_sv_yes : &PL_sv_no,
+                       0);
+               hv_store(hv, "empty", 5,
+                       (autolabel->autolabel & AL_EMPTY)? &PL_sv_yes : &PL_sv_no,
+                       0);
+
+               results[0] = sv_2mortal(newRV((SV *)hv));
+               return 1;
+           }
 
-           $result = sv_2mortal(newRV((SV *)hv));
-           argvi++;
-           break;
+           /* No match yet -> not one of the "complex" types */
+           default:
+               SWIG_exception(SWIG_TypeError, "Unknown val_t conftype");
+               break;
        }
+    }
 
-       case CONFTYPE_PROPLIST:
-           $result = sv_2mortal(g_hash_table_to_hashref(val_t__proplist($1)));
-           argvi++;
-           break;
-
-       case CONFTYPE_SIZE:
-           $result = sv_2mortal(amglue_newSVi64(val_t__size($1)));
-           argvi++;
-           break;
-
-       case CONFTYPE_AM64:
-           $result = sv_2mortal(amglue_newSVi64(val_t__am64($1)));
-           argvi++;
-           break;
-
-       case CONFTYPE_BOOLEAN:      /* all same as INT.. */
-       case CONFTYPE_COMPRESS:
-       case CONFTYPE_ENCRYPT:
-       case CONFTYPE_ESTIMATE:
-       case CONFTYPE_STRATEGY:
-       case CONFTYPE_TAPERALGO:
-       case CONFTYPE_PRIORITY:
-       case CONFTYPE_HOLDING:
-       case CONFTYPE_INT:
-           $result = sv_2mortal(amglue_newSVi64(val_t__int($1)));
-           argvi++;
-           break;
-
-       case CONFTYPE_TIME:
-           $result = sv_2mortal(amglue_newSVi64(val_t__time($1)));
-           argvi++;
-           break;
-
-       case CONFTYPE_REAL:
-           $result = sv_newmortal();
-           sv_setnv($result, val_t__real($1));
-           argvi++;
-           break;
-
-       case CONFTYPE_IDENT:        /* same as STRING */
-       case CONFTYPE_STR:
-           $result = sv_newmortal();
-           sv_setpv($result, val_t__str($1));
-           argvi++;
-           break;
-
-       /* No match yet -> not one of the "complex" types */
-       default:
-           SWIG_exception(SWIG_TypeError, "Unknown val_t conftype");
-           break;
+    return 0;
+
+fail:
+    SWIG_croak_null();
+}
+%}
+
+%typemap (out) val_t * {
+    SV *results[3], **iter;
+    int nresults;
+
+    /* save the stack, since val_t_to_sv may invoke arbitrary Perl code */
+    SP += argvi; PUTBACK;
+    nresults = val_t_to_sv($1, results);
+    SPAGAIN; SP -= argvi;
+
+    /* add val_t_to_sv's results to the stack */
+    for (iter = results; nresults; iter++, nresults--) {
+       $result = *iter;
+       argvi++;
     }
 }
 
@@ -596,13 +667,40 @@ amglue_copy_to_tag(taperalgo_t, getconf);
     g_slist_free($1);
 }
 
+/* typedef and typemap for getconf_byname_strs, which is like getconf_byname, 
+ * but converts the result with val_t_dispaly_strs
+ */
+%typemap (out) val_t_strs {
+    char **it = $1;
+
+    while (it && *it) {
+       $result = sv_2mortal(newSVpv(*it, 0));
+       argvi++;
+       it++;
+    }
+    g_strfreev($1);
+}
+
+data_path_t data_path_from_string(char *data);
+
 val_t *getconf(confparm_key key);
 gboolean getconf_seen(confparm_key key);
+int getconf_linenum(confparm_key key);
 val_t *getconf_byname(char *key);
 GSList *getconf_list(char *listname);
+%inline %{
+typedef char **val_t_strs;
+val_t_strs getconf_byname_strs(char *key, int str_needs_quotes) {
+    val_t *val = getconf_byname(key);
+    if (!val) return NULL;
+    return val_t_display_strs(val, str_needs_quotes);
+}
+%}
+
 amglue_export_tag(getconf,
-    getconf getconf_seen 
-    getconf_byname getconf_list
+    getconf getconf_seen getconf_linenum
+    getconf_byname getconf_byname_strs
+    getconf_list
 );
 
 tapetype_t *lookup_tapetype(char *identifier);
@@ -633,20 +731,92 @@ amglue_export_tag(getconf,
 );
 
 holdingdisk_t *lookup_holdingdisk(char *identifier);
-holdingdisk_t *getconf_holdingdisks(void);
-holdingdisk_t *holdingdisk_next(holdingdisk_t *hdisk);
+GSList *getconf_holdingdisks(void);
 val_t *holdingdisk_getconf(holdingdisk_t *hdisk, holdingdisk_key key);
 char *holdingdisk_name(holdingdisk_t *hdisk);
 gboolean holdingdisk_seen(holdingdisk_t *hdisk, holdingdisk_key key);
 amglue_export_tag(getconf,
     lookup_holdingdisk holdingdisk_getconf holdingdisk_name
-    getconf_holdingdisks holdingdisk_next
+    getconf_holdingdisks
     holdingdisk_seen holdingdisk_seen
 );
 
+application_t *lookup_application(char *identifier);
+val_t *application_getconf(application_t *app, application_key key);
+char *application_name(application_t *app);
+gboolean application_seen(application_t *app, application_key key);
+amglue_export_tag(getconf,
+    lookup_application application_getconf application_name
+    application_seen application_seen
+);
+
+pp_script_t *lookup_pp_script(char *identifier);
+val_t *pp_script_getconf(pp_script_t *pps, pp_script_key key);
+char *pp_script_name(pp_script_t *pps);
+gboolean pp_script_seen(pp_script_t *app, pp_script_key key);
+amglue_export_tag(getconf,
+    lookup_pp_script pp_script_getconf pp_script_name
+    pp_script_seen pp_script_seen
+);
+
+device_config_t *lookup_device_config(char *identifier);
+val_t *device_config_getconf(device_config_t *pps, device_config_key key);
+char *device_config_name(device_config_t *pps);
+gboolean device_config_seen(device_config_t *app, device_config_key key);
+amglue_export_tag(getconf,
+    lookup_device_config device_config_getconf device_config_name
+    device_config_seen device_config_seen
+);
+
+changer_config_t *lookup_changer_config(char *identifier);
+val_t *changer_config_getconf(changer_config_t *pps, changer_config_key key);
+char *changer_config_name(changer_config_t *pps);
+gboolean changer_config_seen(changer_config_t *app, changer_config_key key);
+amglue_export_tag(getconf,
+    lookup_changer_config changer_config_getconf changer_config_name
+    changer_config_seen changer_config_seen
+);
+
+interactivity_t *lookup_interactivity(char *identifier);
+val_t *interactivity_getconf(interactivity_t *app, interactivity_key key);
+char *interactivity_name(interactivity_t *app);
+gboolean interactivity_seen(interactivity_t *app, interactivity_key key);
+amglue_export_tag(getconf,
+    lookup_interactivity interactivity_getconf interactivity_name
+    interactivity_seen interactivity_seen
+);
+
+taperscan_t *lookup_taperscan(char *identifier);
+val_t *taperscan_getconf(taperscan_t *app, taperscan_key key);
+char *taperscan_name(taperscan_t *app);
+gboolean taperscan_seen(taperscan_t *app, taperscan_key key);
+amglue_export_tag(getconf,
+    lookup_taperscan taperscan_getconf taperscan_name
+    taperscan_seen taperscan_seen
+);
+
+%perlcode %{
+# only those keys with a value of '1' should be shown; the
+# others are deprecated
+our %subsection_names = (
+    "tapetype" => 1,
+    "dumptype" => 1,
+    "interface" => 1,
+    "holdingdisk" => 1,
+    "application" => 1,
+    "script" => 1,
+    "application-tool" => 0,
+    "script-tool" => 0,
+    "device" => 1,
+    "changer" => 1,
+);
+%}
+amglue_export_tag(getconf, %subsection_names);
+
 long int getconf_unit_divisor(void);
 
 extern int debug_amandad;
+extern int debug_recovery;
 extern int debug_amidxtaped;
 extern int debug_amindexd;
 extern int debug_amrecover;
@@ -665,7 +835,7 @@ extern int debug_sendbackup;
 amglue_export_tag(getconf,
     getconf_unit_divisor
 
-    $debug_amandad $debug_amidxtaped $debug_amindexd $debug_amrecover
+    $debug_amandad $debug_recovery $debug_amidxtaped $debug_amindexd $debug_amrecover
     $debug_auth $debug_event $debug_holding $debug_protocol
     $debug_planner $debug_driver $debug_dumper $debug_chunker
     $debug_taper $debug_selfcheck $debug_sendsize $debug_sendbackup
@@ -675,50 +845,64 @@ amglue_export_tag(getconf,
  * Initialization
  */
 
-config_overwrites_t *new_config_overwrites(int size_estimate);
-void free_config_overwrites(config_overwrites_t *co);
-void add_config_overwrite(config_overwrites_t *co,
-                        char *key,
-                        char *value);
-void add_config_overwrite_opt(config_overwrites_t *co,
-                             char *optarg);
-void apply_config_overwrites(config_overwrites_t *co);
-amglue_export_tag(init,
-    new_config_overwrites free_config_overwrites add_config_overwrite
-    add_config_overwrite_opt apply_config_overwrites
-);
-
-
-
+amglue_add_enum_tag_fns(cfgerr_level_t);
+amglue_add_constant(CFGERR_OK, cfgerr_level_t);
+amglue_add_constant(CFGERR_WARNINGS, cfgerr_level_t);
+amglue_add_constant(CFGERR_ERRORS, cfgerr_level_t);
+amglue_copy_to_tag(cfgerr_level_t, init);
 
 amglue_add_flag_tag_fns(config_init_flags);
 amglue_add_constant(CONFIG_INIT_EXPLICIT_NAME, config_init_flags);
 amglue_add_constant(CONFIG_INIT_USE_CWD, config_init_flags);
 amglue_add_constant(CONFIG_INIT_CLIENT, config_init_flags);
 amglue_add_constant(CONFIG_INIT_OVERLAY, config_init_flags);
-amglue_add_constant(CONFIG_INIT_FATAL, config_init_flags);
 amglue_copy_to_tag(config_init_flags, init);
 
-gboolean config_init(config_init_flags flags,
+cfgerr_level_t config_init(config_init_flags flags,
                     char *arg_config_name);
 void config_uninit(void);
 char **get_config_options(int first);
-amglue_export_tag(init,
-    config_init config_uninit get_config_options
-);
+char *get_config_name(void);
+char *get_config_dir(void);
+char *get_config_filename(void);
+
+void config_print_errors(void);
+void config_clear_errors(void);
+
+/* Typemap for config_errors' result parameter; this is a GSList of strings
+ * which should *not* be freed. */
+%typemap(in, numinputs=0) GSList **ERRLIST (GSList *templist) {
+   templist = NULL;
+   $1 = &templist;
+}
+
+%typemap (argout) GSList **ERRLIST {
+    GSList *it = *$1;
+
+    while (it) {
+       $result = sv_2mortal(newSVpv(it->data, 0));
+       argvi++;
+       it = it->next;
+    }
+}
+cfgerr_level_t config_errors(GSList **ERRLIST);
+
+
+config_overrides_t *new_config_overrides(int size_estimate);
+void free_config_overrides(config_overrides_t *co);
+void add_config_override(config_overrides_t *co,
+                        char *key,
+                        char *value);
+void add_config_override_opt(config_overrides_t *co,
+                             char *optarg);
+void set_config_overrides(config_overrides_t *co);
 
-/* These are accessor functions, because SWIG's wrapping of global string
- * variables is no so good -- the resulting strings can't be passed to other
- * functions expecting char * arguments.  */
-%inline %{
-    char *get_config_name(void) { return config_name; }
-    char *get_config_dir(void) { return config_dir; }
-    char *get_config_filename(void) { return config_filename; }
-%}
 amglue_export_tag(init,
-    get_config_name 
-    get_config_dir 
-    get_config_filename
+    config_init config_uninit get_config_options
+    get_config_name get_config_dir get_config_filename
+    config_print_errors config_clear_errors config_errors
+    new_config_overrides free_config_overrides add_config_override
+    add_config_override_opt set_config_overrides
 );
 
 /*
@@ -726,10 +910,29 @@ amglue_export_tag(init,
  */
 
 void dump_configuration(void);
+%newobject config_dir_relative;
 char *config_dir_relative(char *filename);
 char *taperalgo2str(taperalgo_t taperalgo);
 gint64 find_multiplier(char * casestr);
+
 amglue_export_ok(
     dump_configuration config_dir_relative taperalgo2str find_multiplier
 );
 
+%rename(C_string_to_boolean) string_to_boolean;
+int string_to_boolean(const char *str);
+%perlcode %{
+
+sub string_to_boolean {
+    my ($str) = @_;
+    my $ret = C_string_to_boolean($str);
+    return undef unless $ret >= 0;
+    return $ret;
+}
+
+%}
+
+amglue_export_ok(string_to_boolean);
+
+gchar * amandaify_property_name(const gchar *name);
+amglue_export_ok(amandaify_property_name);