2 # Copyright (c) 2008-2012 Zmanda, Inc. All Rights Reserved.
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 # You should have received a copy of the GNU General Public License along
15 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
19 # Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
21 use lib '@amperldir@';
24 use Amanda::Config qw( :getconf :init );
25 use Amanda::Debug qw( :logging );
26 use Amanda::Util qw( :constants );
28 use Amanda::Constants;
29 eval 'use Amanda::Disklist;'; # can fail if compiled for client only
32 # Implementation note: this application is a bit funny, because it does not
33 # set up Amanda fully until some time into processing. This lets it respond
34 # with build configuration information without a config file, and lets it set
35 # up debugging for the caller.
37 # The most obvious consequence is that, rather than calling die (which interfaces
38 # with Amanda::Debug), this file uses a locally defined 'fail' to print error
43 Usage: amgetconf [--client] [--execute-where client|server] [-l|--list] [-o configoption]* <config> <paramname>
44 (any ordering of options and arguments is acceptable)
46 --client is equivalent to --execute-where client
48 --execute-where tells amgetconf whether to operate on the client or the
49 server; the server is the default.
51 paramname can be one of
52 dbopen.APPNAME -- open a debug file
53 dbclose.APPNAME:FILENAME -- close debug file FILENAME
54 build.PARAM -- get a build parameter
55 PARAM -- get an Amanda configuration parameter
57 For all but Amanda configuration parameters, the <config> option is
58 ignored, but must be present. For Amanda configuration parameters,
59 values in subsections are specified in the form TYPE:NAME:PARAMETER.
61 With --list, PARAM can be one of
63 for my $name (keys %Amanda::Config::subsection_names) {
65 if $Amanda::Config::subsection_names{$name};
71 print STDERR @_, "\n";
77 fail("amgetconf: no such parameter \"$parameter\"");
83 # NOTE TO MAINTAINERS:
84 # If you add to this list, be sure to also add the new parameter
85 # amgetconf(8) manual page. Note that all keys are lower-case.
87 ## directories from Amanda::Paths
90 'sbindir' => $sbindir,
91 'libexecdir' => $libexecdir,
92 'amlibexecdir' => $amlibexecdir,
94 'amanda_tmpdir' => $AMANDA_TMPDIR,
95 'config_dir' => $CONFIG_DIR,
96 'amanda_dbgdir' => $AMANDA_DBGDIR,
97 'application_dir' => $APPLICATION_DIR,
98 'gnutar_listed_incremental_dir' => $GNUTAR_LISTED_INCREMENTAL_DIR,
99 'listed_inc_dir' => $GNUTAR_LISTED_INCREMENTAL_DIR, # (historical alias)
101 ## constants from Amanda::Constants
103 # build environment info
105 'cc' => $Amanda::Constants::CC,
106 'version' => $Amanda::Constants::VERSION,
107 'assertions' => $Amanda::Constants::ASSERTIONS,
108 'use_version_suffixes' => 'no', # for backward compatibility
109 'locking' => $Amanda::Constants::LOCKING,
113 'dump' => $Amanda::Constants::DUMP,
114 'restore' => $Amanda::Constants::RESTORE,
115 'vdump' => $Amanda::Constants::VDUMP,
116 'vrestore' => $Amanda::Constants::VRESTORE,
117 'xfsdump' => $Amanda::Constants::XFSDUMP,
118 'xfsrestore' => $Amanda::Constants::XFSRESTORE,
119 'vxdump' => $Amanda::Constants::VXDUMP,
120 'vxrestore' => $Amanda::Constants::VXRESTORE,
121 'samba_client' => $Amanda::Constants::SAMBA_CLIENT,
122 'gnutar' => $Amanda::Constants::GNUTAR,
123 'star' => $Amanda::Constants::STAR,
124 'compress_path' => $Amanda::Constants::COMPRESS_PATH,
125 'uncompress_path' => $Amanda::Constants::UNCOMPRESS_PATH,
126 'aix_backup' => $Amanda::Constants::AIX_BACKUP,
127 'dump_returns_1' => $Amanda::Constants::DUMP_RETURNS_1,
131 'bsd_security' => $Amanda::Constants::BSD_SECURITY,
132 'bsdudp_security' => $Amanda::Constants::BSDUDP_SECURITY,
133 'bsdtcp_security' => $Amanda::Constants::BSDTCP_SECURITY,
134 'krb5_security' => $Amanda::Constants::KRB5_SECURITY,
135 'ssh_security' => $Amanda::Constants::SSH_SECURITY,
136 'rsh_security' => $Amanda::Constants::RSH_SECURITY,
137 'use_amandahosts' => $Amanda::Constants::USE_AMANDAHOSTS,
139 # build-time constants
141 'amanda_debug_days' => $Amanda::Constants::AMANDA_DEBUG_DAYS,
142 'default_server' => $Amanda::Constants::DEFAULT_SERVER,
143 'default_amandates_file' => $Amanda::Constants::DEFAULT_AMANDATES_FILE,
144 'default_config' => $Amanda::Constants::DEFAULT_CONFIG,
145 'default_tape_server' => $Amanda::Constants::DEFAULT_TAPE_SERVER,
146 'default_tape_device' => $Amanda::Constants::DEFAULT_TAPE_DEVICE,
147 'client_login' => $Amanda::Constants::CLIENT_LOGIN,
148 'use_rundump' => $Amanda::Constants::USE_RUNDUMP,
149 'check_userid' => $Amanda::Constants::CHECK_USERID,
151 # compression information
153 'compress_suffix' => $Amanda::Constants::COMPRESS_SUFFIX,
154 'compress_fast_opt' => $Amanda::Constants::COMPRESS_FAST_OPT,
155 'compress_best_opt' => $Amanda::Constants::COMPRESS_BEST_OPT,
156 'uncompress_opt' => $Amanda::Constants::UNCOMPRESS_OPT,
158 # kerberos information
160 'ticket_lifetime' => $Amanda::Constants::TICKET_LIFETIME,
161 'server_host_principal' => $Amanda::Constants::SERVER_HOST_PRINCIPAL,
162 'server_host_instance' => $Amanda::Constants::SERVER_HOST_INSTANCE,
163 'server_host_key_file' => $Amanda::Constants::SERVER_HOST_KEY_FILE,
164 'client_host_principal' => $Amanda::Constants::CLIENT_HOST_PRINCIPAL,
165 'client_host_instance' => $Amanda::Constants::CLIENT_HOST_INSTANCE,
166 'client_host_key_file' => $Amanda::Constants::CLIENT_HOST_KEY_FILE,
167 # (historical typos:)
168 'server_host_principle' => $Amanda::Constants::SERVER_HOST_PRINCIPAL,
169 'client_host_principle' => $Amanda::Constants::CLIENT_HOST_PRINCIPAL,
170 # (for testing purposes)
176 my ($parameter, $opt_list) = @_;
179 usage() unless ($parameter eq "build");
181 for my $pname (sort keys %build_info) {
185 my ($pname) = $parameter =~ /^build\.(.*)/;
187 my $val = $build_info{lc $pname};
188 no_such_param($parameter) unless (defined($val));
197 my ($parameter, $opt_list) = @_;
198 my ($appname, $filename);
200 # copy amgetconf pname and pcontext
201 my $pname = Amanda::Util::get_pname();
202 my $pcontext = Amanda::Util::get_pcontext();
204 if (($appname) = $parameter =~ /^dbopen\.(.*)/) {
205 $appname =~ s/[^[:alnum:]]/_/g;
206 # set pname and pcontext for the application
207 Amanda::Util::set_pname($appname);
208 Amanda::Util::set_pcontext($CONTEXT_CMDLINE);
209 Amanda::Debug::dbopen("server");
210 print Amanda::Debug::dbfn(), "\n";
211 } elsif (($appname, $filename) = $parameter =~ /^dbclose\.([^:]*):(.*)/) {
212 fail("debug file $filename does not exist") unless (-f $filename);
213 # set pname and pcontext for the application
214 Amanda::Util::set_pname($appname);
215 Amanda::Util::set_pcontext($CONTEXT_CMDLINE);
216 Amanda::Debug::dbreopen($filename, '');
217 Amanda::Debug::dbclose();
220 fail("cannot parse $parameter");
222 # reset pname and pcontext for amgetconf
223 Amanda::Util::set_pcontext($pcontext);
224 Amanda::Util::set_pname($pname);
227 ## regular configuration parameters
230 my ($parameter, $opt_list) = @_;
233 # getconf_list will return an empty list for any unrecognized name,
234 # so first check that the user has supplied a real subsection
235 no_such_param($parameter)
236 unless defined($Amanda::Config::subsection_names{$parameter});
237 my @list = getconf_list($parameter);
239 for my $subsec (@list) {
242 } elsif ($parameter =~ /^property:/i) {
243 my %properties = %{ getconf($CNF_PROPERTY)};
244 my $propname = $parameter;
245 $propname =~ s/^property://i;
246 $propname = lc($propname);
247 if (exists $properties{$propname}) {
248 print $properties{$propname}->{'values'}[0], "\n";
250 } elsif ($parameter =~ /^device-property:/i ||
251 $parameter =~ /^device_property:/i) {
252 my %properties = %{ getconf($CNF_DEVICE_PROPERTY) };
253 my $propname = $parameter;
254 $propname =~ s/^device-property://i;
255 $propname =~ s/^device_property://i;
256 $propname = lc($propname);
257 if (exists $properties{$propname}) {
258 print $properties{$propname}->{'values'}[0], "\n";
261 no_such_param($parameter)
262 unless defined(getconf_byname($parameter));
263 my @strs = getconf_byname_strs($parameter, 0);
265 for my $str (@strs) {
271 Amanda::Util::setup_application("amgetconf", "server", $CONTEXT_SCRIPTUTIL);
273 ## Command-line parsing
276 my $config_overrides = new_config_overrides($#ARGV+1);
277 my $execute_where = undef;
279 debug("Arguments: " . join(' ', @ARGV));
280 Getopt::Long::Configure(qw{bundling});
282 'version' => \&Amanda::Util::version_opt,
283 'list|l' => \$opt_list,
284 'o=s' => sub { add_config_override_opt($config_overrides, $_[1]); },
285 'execute-where=s' => sub {
286 my $where = lc($_[1]);
287 fail("Invalid value ($_[1]) for --execute-where. Must be client or server.")
288 unless $where eq 'client' or $where eq 'server';
289 fail("--execute-where=server conflicts with --execute-where=client or --client.")
290 unless !defined($execute_where) || (
291 ($where eq 'client' && $execute_where) ||
292 ($where eq 'server' && !$execute_where));
293 $execute_where = ($where eq 'client')? $CONFIG_INIT_CLIENT : 0;
296 fail("--execute-where=server conflicts with --execute-where=client or --client.")
297 unless !defined($execute_where) || $execute_where;
298 $execute_where = $CONFIG_INIT_CLIENT;
306 $parameter = $ARGV[0];
307 } elsif (@ARGV >= 2) {
308 # note that we ignore any arguments past these two. Amdump lazily passes
309 # such arguments on to us, so we have no choice.
310 $config_name = $ARGV[0];
311 $parameter = $ARGV[1];
316 ## Now start looking at the parameter.
318 if ($parameter =~ /^build(?:\..*)?/) {
319 config_init(0|$execute_where, undef);
320 build_param($parameter, $opt_list);
321 Amanda::Util::finish_application();
325 if ($parameter =~ /^db(open|close)\./) {
326 config_init(0|$execute_where, undef);
327 db_param($parameter, $opt_list);
328 Amanda::Util::finish_application();
332 # finally, finish up the application startup procedure
333 set_config_overrides($config_overrides);
334 if ($execute_where == $CONFIG_INIT_CLIENT &&
335 defined($config_name) && $config_name eq '.') {
336 config_init($CONFIG_INIT_USE_CWD | $execute_where, undef);
337 } elsif ($execute_where == $CONFIG_INIT_CLIENT &&
338 defined($config_name) && $config_name ne '.') {
339 config_init($CONFIG_INIT_EXPLICIT_NAME | $execute_where, $config_name);
340 } elsif ($execute_where == $CONFIG_INIT_CLIENT) {
341 config_init($execute_where, undef);
343 config_init($CONFIG_INIT_EXPLICIT_NAME | $CONFIG_INIT_USE_CWD | $execute_where, $config_name);
345 my ($cfgerr_level, @cfgerr_errors) = config_errors();
346 if ($cfgerr_level >= $CFGERR_WARNINGS) {
347 config_print_errors();
348 if ($cfgerr_level >= $CFGERR_ERRORS) {
349 die("errors processing config file");
353 Amanda::Util::finish_setup($RUNNING_AS_ANY);
355 if ($execute_where != $CONFIG_INIT_CLIENT) {
356 my $diskfile = Amanda::Config::config_dir_relative(getconf($CNF_DISKFILE));
357 $cfgerr_level = Amanda::Disklist::read_disklist('filename' => $diskfile);
358 # if ($cfgerr_level >= $CFGERR_ERRORS) {
359 # die "Errors processing disklist";
363 conf_param($parameter, $opt_list);
365 Amanda::Util::finish_application();