File Coverage

blib/lib/Advanced/Config.pm
Criterion Covered Total %
statement 923 1125 82.0
branch 302 464 65.0
condition 116 255 45.4
subroutine 75 79 94.9
pod 50 51 98.0
total 1466 1974 74.2


line stmt bran cond sub pod time code
1             ###
2             ### Copyright (c) 2007 - 2026 Curtis Leach. All rights reserved.
3             ###
4             ### Module: Advanced::Config
5              
6             =head1 NAME
7              
8             Advanced::Config - Perl module reads configuration files from various sources.
9              
10             =head1 SYNOPSIS
11              
12             use Advanced::Config;
13             or
14             require Advanced::Config;
15              
16             =head1 DESCRIPTION
17              
18             F is an enhanced implementation of a config file manager
19             that allows you to manage almost any config file as a true object with a common
20             interface. It allows you to configure for almost any look and feel inside your
21             config files.
22              
23             You will need to create one object per configuration file that you wish to
24             manipulate. And any updates you make to the object in memory will not make it
25             back into the config file itself.
26              
27             It also has options for detecting if the data in the config file has been
28             updated since you loaded it into memory and allows you to refresh the
29             configuration object. So that your long running programs never have to execute
30             against stale configuration data.
31              
32             This module supports config file features such as variable substitution,
33             sourcing in other config files, comments, breaking your configuration data
34             up into sections, encrypting/decrypting individual tag values, and even more ...
35              
36             So feel free to experiment with this module on the best way to access your
37             data in your config files. And never have to worry about having multiple
38             versions of your config files again for Production vs Development vs QA vs
39             different OS, etc.
40              
41             =head1 NOTES ON FUNCTIONS WITH MULTIPLE RETURN VALUES
42              
43             Whenever a function in this module or one if it's helper modules says it can
44             have multiple return values and you ask for them in scalar mode, it only returns
45             the first return value. The other return values are tossed. Not the count of
46             return values as some might expect.
47              
48             This is because in most cases these secondary return values only have meaning
49             in special cases. So usually there's no need to grab them unless you plan on
50             using them.
51              
52             For a list of the related helper modules see the B section at the
53             end of this POD. These helper modules are not intended for general use.
54              
55             =cut
56              
57             # ---------------------------------------------------------------
58              
59             package Advanced::Config;
60              
61 26     26   3849183 use strict;
  26         70  
  26         1089  
62 26     26   140 use warnings;
  26         198  
  26         1930  
63              
64             # The version of this module!
65             our $VERSION = "1.14";
66              
67 26     26   155 use File::Basename;
  26         49  
  26         1948  
68 26     26   13591 use File::Copy;
  26         157383  
  26         1811  
69 26     26   4659 use Sys::Hostname;
  26         12177  
  26         1474  
70 26     26   145 use File::Spec;
  26         45  
  26         645  
71 26     26   113 use Perl::OSType ':all';
  26         36  
  26         3412  
72 26     26   175 use Cwd 'abs_path';
  26         70  
  26         1342  
73              
74 26     26   19304 use Advanced::Config::Date;
  26         103  
  26         3714  
75 26     26   19796 use Advanced::Config::Options;
  26         113  
  26         2900  
76 26     26   17630 use Advanced::Config::Reader;
  26         125  
  26         3048  
77 26     26   245 use Fred::Fish::DBUG 2.09 qw / on_if_set ADVANCED_CONFIG_FISH /;
  26         698  
  26         234  
78              
79             # The name of the default section ... (even if no sections are defined!)
80 26     26   11556 use constant DEFAULT_SECTION => Advanced::Config::Options::DEFAULT_SECTION_NAME;
  26         74  
  26         13131  
81              
82             # Should only be modifiable via BEGIN ...
83             my %begin_special_vars;
84             my $secret_tag;
85             my $fish_tag;
86              
87              
88             # This begin block initializes the special variables used
89             # for "rule 5" & "rule 6" in lookup_one_variable()
90             # and _find_variables()!
91             BEGIN
92             {
93 26     26   216 DBUG_ENTER_FUNC ();
94              
95             # -----------------------------------------------
96             # These are the "Rule 5" special perl varibles.
97             # Done this way to avoid having to support
98             # indirect "eval" logic.
99             # -----------------------------------------------
100 26 50       7239 $begin_special_vars{'0'} = ($0 eq "-e") ? "perl" : $0;
101 26         195 $begin_special_vars{'$'} = $$;
102 26         140 $begin_special_vars{'^O'} = $^O; # MSWin32, aix, etc ...
103              
104             # ---------------------------------------------
105             # Start of the "rule 6" initialization ...
106             # ---------------------------------------------
107 26         119 $begin_special_vars{PID} = $$;
108 26         119 $begin_special_vars{user} = Advanced::Config::Options::_get_user_id ();
109 26         4936 $begin_special_vars{hostname} = hostname ();
110 26         1172 $begin_special_vars{flavor} = os_type (); # Windows, Unix, etc...
111              
112             # ---------------------------------------------
113             # Get the Parent PID if available ... (PPID)
114             # ---------------------------------------------
115 26         291 eval {
116 26         155 $begin_special_vars{PPID} = getppid ();
117             };
118 26 50       106 if ( $@ ) {
119 0         0 DBUG_PRINT ("INFO", "Cheating to get the PPID. It may be wrong!");
120             # We can't easily get the parent process id for Windows.
121             # So we're going to cheat a bit. We'll ask if any parent
122             # or grandparent process used this module before and call it
123             # the parent process!
124 0         0 $secret_tag = "_ADVANCED_CONFIG_PPID_";
125              
126 0 0       0 if ( $ENV{$secret_tag} ) {
127 0         0 $begin_special_vars{PPID} = $ENV{$secret_tag};
128             } else {
129 0         0 $begin_special_vars{PPID} = -1; # Can't figure out the PPID.
130             }
131 0         0 $ENV{$secret_tag} = $$;
132             }
133              
134             # -----------------------------------------------------
135             # Calculate the separator used by the current OS
136             # when constructing a directory tree. (sep)
137             # -----------------------------------------------------
138 26         66 my ($a, $b) = ("one", "two");
139 26         461 my $p = File::Spec->catfile ($a, $b);
140 26 50       977 if ( $p =~ m/^${a}(.+)${b}$/ ) {
141 26         123 $begin_special_vars{sep} = $1; # We have it!
142             } else {
143 0         0 warn "Unknown separator for current OS!\n";
144 0         0 $begin_special_vars{sep} = ""; # Unknown value!
145             }
146              
147             # -----------------------------------------------------
148             # Calculate the program name minus any path info or
149             # certain file extensions.
150             # -----------------------------------------------------
151 26 50       93 if ( $0 eq "-e" ) {
152 0         0 $begin_special_vars{program} = "perl"; # Perl add hock script!
153             } else {
154 26         1420 $begin_special_vars{program} = basename ($0);
155              
156             # Remove only certain file extensions from the program's name!
157 26 50       195 if ( $begin_special_vars{program} =~ m/^(.+)[.]([^.]*)$/ ) {
158 26         160 my ($f, $ext) = ($1, lc ($2));
159 26 50 33     327 if ( $ext eq "" || $ext eq "pl" || $ext eq "t" ) {
      33        
160 26         71 $begin_special_vars{program} = $f;
161             }
162             }
163             }
164              
165 26         200 DBUG_VOID_RETURN ();
166             }
167              
168             # Called automatically when this module goes out of scope ...
169             # At times this might be called before DESTROY ...
170             END
171             {
172 26     26   904106 DBUG_ENTER_FUNC ();
173 26         5913 DBUG_VOID_RETURN ();
174             }
175              
176             # Called automatically when the current instance of module goes out of scope.
177             # Only called if new() was successfull!
178             # At times this might be called after END ...
179             DESTROY
180             {
181 54     54   7585 DBUG_ENTER_FUNC ();
182 54         10460 DBUG_VOID_RETURN ();
183             }
184              
185              
186             # ----------------------------------------------------------------------------
187             # Helper functions that won't appear in the POD.
188             # They will all start with "_" in their name.
189             # But they are still considered members of the object.
190             # These functions can appear throughout this file.
191             # ----------------------------------------------------------------------------
192              
193             # Using Cwd's abs_path() bombs on Windows if the file doesn't exist!
194             # So I'm doing this conversion myself.
195             # This function doesn't care if the file actually exists or not!
196             # It just converts a relative path into an absolute path!
197             sub _fix_path
198             {
199 257     257   1117 DBUG_ENTER_FUNC ( @_ );
200 257         151618 my $self = shift;
201 257   100     1411 my $file = shift || "";
202 257         663 my $dir = shift; # If not provided uses current directory!
203              
204 257 100       853 if ( $file ) {
205             # Convert relative paths to absolute path names.
206             # Removes internal ".", but not ".." in the path info ...
207             # It also doesn't resolve symbolic links.
208 231 100       4132 unless ( File::Spec->file_name_is_absolute ( $file ) ) {
209 147 100       511 if ( $dir ) {
210 46         1261 $file = File::Spec->rel2abs ( File::Spec->catfile ( $dir, $file ) );
211             } else {
212 101         3576 $file = File::Spec->rel2abs ( $file );
213             }
214             }
215              
216             # Now let's remove any relative path info (..) from the new absolute path.
217             # Still not resolving any symbolic links on purpose!
218             # I don't agree with File::Spec->canonpath()'s reasoning for not doing it
219             # that way. So I need to resolve it myself.
220 231         2524 my @parts = File::Spec->splitdir ( $file );
221 231         1014 foreach ( 1..$#parts ) {
222 1631 100       3684 if ( $parts[$_] eq ".." ) {
223 7         27 $parts[$_] = $parts[$_ - 1] = "";
224             }
225             }
226              
227             # It's smart enough to ignore "" in the array!
228 231         2368 $file = File::Spec->catdir (@parts);
229             }
230              
231 257         1161 DBUG_RETURN ( $file );
232             }
233              
234              
235             # ----------------------------------------------------------------------------
236             # Start of the exposed methods in the module ...
237             # ----------------------------------------------------------------------------
238              
239             =head1 CONSTRUCTORS
240              
241             To use this module, you must call C()> to create the I
242             object you wish to work with. All it does is create an empty object for you to
243             reference and returns the C object created. Once you
244             have this object reference you are good to go! You can either load an existing
245             config file into memory or dynamically build your own virtual config file or
246             even do a mixure of both!
247              
248             =over
249              
250             =item $cfg = Advanced::Config->new( [$filename[, \%read_opts[, \%get_opts[, \%date_var_opts]]]] );
251              
252             It takes four arguments, any of which can be omitted or B during object
253             creation!
254              
255             F<$filename> is the optional name of the config file to read in. It can be a
256             relative path. The absolute path to it will be calculated for you if a relative
257             path was given.
258              
259             F<\%read_opts> is an optional hash reference that controls the default parsing
260             of the config file as it's being read into memory. Feel free to leave as
261             B if you're satisfied with this module's default behavior.
262              
263             F<\%get_opts> is an optional hash reference that defines the default behavior
264             when this module looks something up in the config file. Feel free to leave as
265             B if you're satisfied with this module's default behavior.
266              
267             F<\%date_var_opts> is an optional hash reference that defines the default
268             formatting of the special predefined date variables. Feel free to leave as
269             B if you're satisfied with the default formatting rules.
270              
271             See the POD under L for more details on what options
272             these three hash references support! Look under the S>,
273             S>, and S>
274             sections of the POD.
275              
276             It returns the I object created.
277              
278             Here's a few examples:
279              
280             # Sets up an empty object.
281             $cfg = Advanced::Config->new();
282              
283             # Just specifies the config file to use ...
284             $cfg = Advanced::Config->new("MyFile.cfg");
285              
286             # Overrides some of the default featurs of the module ...
287             $cfg = Advanced::Config->new("MyFile.cfg",
288             { "assign" => ":=", "comment" => ";" },
289             { "required" => 1, "date_language" => "German" },
290             { "month_type" => 2, "month_language" => "German" } );
291              
292             =cut
293              
294             sub new
295             {
296 86     86 1 3449893 DBUG_ENTER_FUNC ( @_ );
297 86         45175 my $prototype = shift;;
298 86         238 my $filename = shift;
299 86         288 my $read_opts = shift; # A hash ref of "read" options ...
300 86         279 my $get_opts = shift; # Another hash ref of "get" options ...
301 86         195 my $date_opts = shift; # Another hash ref of "date" formatting options ...
302              
303 86   33     748 my $class = ref ( $prototype ) || $prototype;
304 86         208 my $self = {};
305              
306             # Create an empty object ...
307 86         266 bless ( $self, $class );
308              
309             # Creating a new object ... (The main section)
310 86         221 my %control;
311              
312             # Initialize what options were selected ...
313 86         509 $control{filename} = $self->_fix_path ($filename);
314 86         22737 $control{read_opts} = get_read_opts ( $read_opts );
315 86         21853 $control{get_opts} = get_get_opts ( $get_opts );
316 86         21678 $control{date_opts} = get_date_opts ( $date_opts );
317              
318 86         21370 my ( %dates, %empty, %mods, %ropts, %rec, @lst );
319              
320             # Special Date Variables ...
321 86         696 set_special_date_vars ($control{date_opts}, \%dates);
322 86         21333 $control{DATES} = \%dates;
323 86         311 $control{DATE_USED} = 0;
324              
325             # Environment variables referenced ...
326 86         305 $control{ENV} = \%empty;
327              
328             # Timestamps & options used for each config file loaded into memory ...
329             # Controls the refesh logic.
330 86         316 $control{REFRESH_MODIFY_TIME} = \%mods;
331 86         261 $control{REFRESH_READ_OPTIONS} = \%ropts;
332              
333             # Used to detect recursion ...
334 86         246 $control{RECURSION} = \%rec;
335              
336             # Used to detect recursion ...
337 86         384 $control{MERGE} = \@lst;
338              
339             # The count for sensitive entries ...
340 86         461 $control{SENSITIVE_CNT} = sensitive_cnt ();
341              
342             # Assume not allowing utf8/Unicode/Wide Char dates ...
343             # Or inside the config file itself.
344 86         20759 $control{ALLOW_UTF8} = 0;
345              
346             # Controls the behavior of this module.
347             # Only exists in the parent object.
348 86         340 $self->{CONTROL} = \%control;
349              
350 86         371 my $key = $self->{SECTION_NAME} = DEFAULT_SECTION;
351              
352 86         162 my %sections;
353 86         258 $sections{$key} = $self;
354 86         226 $self->{SECTIONS} = \%sections;
355              
356             # Holds all the tag data for the main section in the config file.
357 86         158 my %data;
358 86         242 $self->{DATA} = \%data;
359              
360             # Is the data all sensitive?
361 86         227 $self->{SENSITIVE_SECTION} = 0; # No for the default section ...
362              
363 86         358 DBUG_RETURN ( $self );
364             }
365              
366             # Only called by Advanced::Config::Reader::read_config() ...
367             # So not exposed in the POD!
368             # Didn't rely on read option 'use_utf8' since in many cases
369             # the option is misleading or just plain wrong!
370             sub _allow_utf8
371             {
372 3     3   13 DBUG_ENTER_FUNC ( @_ );
373 3         540 my $self = shift;
374              
375             # Tells calls to Advanced::Config::Options::apply_get_rules() that
376             # it's ok to use Wide Char Languages like Greek.
377 3   33     46 my $pcfg = $self->{PARENT} || $self;
378 3         10 $pcfg->{CONTROL}->{ALLOW_UTF8} = 1;
379              
380 3         11 DBUG_VOID_RETURN ();
381             }
382              
383             # This private method preps for a clean refresh of the objects contents.
384             # Kept after the consructor so I can remember to add any new hashes to
385             # the list below.
386             sub _wipe_internal_data
387             {
388 96     96   433 DBUG_ENTER_FUNC ( @_ );
389 96         48386 my $self = shift;
390 96         235 my $file = shift; # The main config file
391              
392             # Wiping the main section automatically wipes everything else ...
393 96   33     645 $self = $self->{PARENT} || $self;
394              
395 96         277 my ( %env, %mods, %rOpts, %rec, @lst, %sect, %data );
396              
397 96         211 my $key = DEFAULT_SECTION;
398 96         417 $sect{$key} = $self;
399              
400 96         350 $self->{CONTROL}->{filename} = $file;
401 96         383 $self->{CONTROL}->{ENV} = \%env;
402 96         320 $self->{CONTROL}->{REFRESH_MODIFY_TIME} = \%mods;
403 96         304 $self->{CONTROL}->{REFRESH_READ_OPTIONS} = \%rOpts;
404 96         305 $self->{CONTROL}->{RECURSION} = \%rec;
405 96         320 $self->{CONTROL}->{MERGE} = \@lst;
406 96         504 $self->{CONTROL}->{SENSITIVE_CNT} = sensitive_cnt ();
407 96         24215 $self->{CONTROL}->{ALLOW_UTF8} = 0;
408              
409 96         451 $self->{SECTIONS} = \%sect;
410 96         5560 $self->{DATA} = \%data;
411              
412 96         265 $self->{SENSITIVE_SECTION} = 0; # Not a sensitive section name!
413              
414 96         401 DBUG_VOID_RETURN ();
415             }
416              
417              
418             #######################################
419              
420             # =item $cfg = Advanced::Config->new_section ( $cfg_obj, $section );
421              
422             # This special case constructor creates a new B object and
423             # relates it to the given I<$cfg_obj> as a new section named I<$section>.
424              
425             # It will call die if I<$cfg_obj> is not a valid B object or
426             # the I<$section> is missing or already in use.
427              
428             # Returns a reference to this new object.
429              
430             # =cut
431              
432             # Stopped exposing to public on 12/30/2019 ... but still used internally.
433             # In most cases 'create_section' should be called instead!
434             sub new_section
435             {
436 333     333 0 1368 DBUG_ENTER_FUNC ( @_ );
437 333         136444 my $prototype = shift;;
438 333         739 my $parent = shift;
439 333         929 my $section = shift;
440              
441 333   33     1525 my $class = ref ( $prototype ) || $prototype;
442 333         790 my $self = {};
443              
444             # Create an empty object ...
445 333         1530 bless ( $self, $class );
446              
447 333 50       1499 if ( ref ( $parent ) ne __PACKAGE__ ) {
448 0         0 die ("You must provide an ", __PACKAGE__, " object as an argument!\n");
449             }
450              
451             # Make sure it's really the parent object ...
452 333   33     1780 $parent = $parent->{PARENT} || $parent;
453              
454             # Trim so we can check if unique ...
455 333 50       1127 if ( $section ) {
456 333         1494 $section =~ s/^\s+//; $section =~ s/\s+$//;
  333         1497  
457 333         1147 $section = lc ($section);
458             }
459              
460 333 50       1040 unless ( $section ) {
461 0         0 die ("You must provide a section name to use this constructor.\n");
462             }
463              
464             # Creating a new section for the parent object ...
465 333 50       1259 if ( exists $parent->{SECTIONS}->{$section} ) {
466 0         0 die ("Section \"${section}\" already exists!\n");
467             }
468              
469             # Links the parent & child objects together ...
470 333         20618 $parent->{SECTIONS}->{$section} = $self;
471 333         1249 $self->{SECTION_NAME} = $section;
472 333         880 $self->{PARENT} = $parent;
473              
474             # Holds all the tag data for this section in the config file.
475 333         612 my %data;
476 333         1037 $self->{DATA} = \%data;
477              
478             # Does this section have a sinsitive name?
479             # If so, all tags in this section are sensitive!
480 333         1621 $self->{SENSITIVE_SECTION} = should_we_hide_sensitive_data ($section, 1);
481              
482 333         1170 DBUG_RETURN ( $self );
483             }
484              
485             #######################################
486              
487             =back
488              
489             =head1 THE METHODS
490              
491             Once you have your B object initialized, you can manipulate
492             your object in many ways. You can access individual components of your config
493             file, modify its contents, refresh its contents and even organize it in
494             different ways.
495              
496             Here are your exposed methods to help with this manipulation.
497              
498             =head2 Loading the Config file into memory.
499              
500             These methods are used to initialize the contents of an B
501             object.
502              
503             =over 4
504              
505             =item $cfg = $cfg->load_config ( [$filename[, %override_read_opts]] );
506              
507             This method reads the current I<$filename> into memory and converts it into an
508             object so that you may reference its contents. The I<$filename> must be defined
509             either here or in the call to B.
510              
511             Each time you call this method, it wipes the contents of the object and starts
512             you from a clean slate again. Making it safe to call multiple times if needed.
513              
514             The I<%override_read_opts> options apply just to the current call to
515             I and will be forgotten afterwards. If you want these options
516             to persist between calls, set the option via the call to B. This
517             argument can be passed either by value or by reference. Either way will work.
518             See L for more details.
519              
520             On success, it returns a reference to itself so that it can be initialized
521             separately or as a single unit.
522              
523             Ex: $cfg = Advanced::Config->new(...)->load_config (...);
524              
525             On failure it returns I or calls B if option I is set!
526              
527             WARNING: If basename(I<$filename>) is a symbolic link and your config file
528             contains encrypted data, please review the encryption options about special
529             considerations.
530              
531             =cut
532              
533             sub load_config
534             {
535 172     172 1 99214 DBUG_ENTER_FUNC ( @_ );
536 172         86828 my $self = shift;
537 172         441 my $filename = shift;
538 172         406 my $read_opts = $_[0]; # Don't pop from the stack yet ...
539              
540 172   33     1192 $self = $self->{PARENT} || $self;
541              
542             # Get the filename to read ...
543 172 100       569 if ( $filename ) {
544 107         621 $filename = $self->_fix_path ($filename);
545             } else {
546 65         204 $filename = $self->{CONTROL}->{filename};
547             }
548              
549             # Get the read options ...
550 172         27217 my $new_opts;
551 172 100       587 if ( ! defined $read_opts ) {
552 91         199 my %none;
553 91         239 $new_opts = \%none;
554             } else {
555 81 50       444 $read_opts = {@_} if ( ref ($read_opts) ne "HASH" );
556 81         223 $new_opts = $read_opts;
557             }
558 172         1058 $read_opts = get_read_opts ( $read_opts, $self->{CONTROL}->{read_opts} );
559              
560 172 100       42402 unless ( $filename ) {
561 5         14 my $msg = "You must provide a file name to load!";
562 5         27 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
563             }
564              
565 167 50       6819 unless ( -f $filename ) {
566 0         0 my $msg = "No such file or it's unreadable! -- $filename";
567 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
568             }
569              
570 167         897 DBUG_PRINT ("READ", "Reading a config file into memory ... %s", $filename);
571              
572 167 50 33     45150 unless ( -f $filename && -r _ ) {
573 0         0 my $msg = "Your config file name doesn't exist or isn't readable.";
574 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
575             }
576              
577             # Behaves diferently based on who calls us ...
578 167   50     1497 my $c = (caller(1))[3] || "";
579 167         518 my $by = __PACKAGE__ . "::merge_config";
580 167         383 my $by2 = __PACKAGE__ . "::_load_config_with_new_date_opts";
581 167 100       710 if ( $c eq $by ) {
    100          
582             # Manually merging in another config file.
583 41         99 push (@{$self->{CONTROL}->{MERGE}}, $filename);
  41         210  
584             } elsif ( $c eq $by2 ) {
585             # Sourcing in a file says to remove these old decryption opts.
586 44 100       225 delete $read_opts->{alias} unless ( $new_opts->{alias} );
587 44 50       165 delete $read_opts->{pass_phrase} unless ( $new_opts->{pass_phrase} );
588 44 50       177 delete $read_opts->{encrypt_by_user} unless ( $new_opts->{encrypt_by_user} );
589             } else {
590             # Loading the original file ...
591 82         465 $self->_wipe_internal_data ( $filename );
592             }
593              
594             # Auto add the alias if it's a symbolic link & there isn't an alias.
595             # Otherwise decryption won't work!
596 167 50 33     16696 if ( -l $filename && ! $read_opts->{alias} ) {
597 0         0 $read_opts->{alias} = abs_path( $filename );
598             }
599              
600             # So refresh logic will work ...
601 167         2676 $self->{CONTROL}->{REFRESH_MODIFY_TIME}->{$filename} = (stat( $filename ))[9];
602 167         827 $self->{CONTROL}->{REFRESH_READ_OPTIONS}->{$filename} = get_read_opts ($read_opts);
603              
604             # So will auto-clear if die is called!
605 167         51063 local $self->{CONTROL}->{RECURSION}->{$filename} = 1;
606              
607             # Temp override of the default read options ...
608 167         657 local $self->{CONTROL}->{read_opts} = $read_opts;
609              
610 167 50       1275 unless ( read_config ( $filename, $self ) ) {
611 0         0 my $msg = "Reading the config file had serious issues!";
612 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
613             }
614              
615 167         45868 DBUG_RETURN ( $self );
616             }
617              
618             #######################################
619              
620             =item $cfg = $cfg->load_string ( $string[, %override_read_opts] );
621              
622             This method takes the passed I<$string> and treats it's value as the contents of
623             a config file. Modifying the I<$string> afterwards will not affect things. You
624             can use this as an alternative to F.
625              
626             Each time you call this method, it wipes the contents of the object and starts
627             you from a clean slate again. Making it safe to call multiple times if needed.
628              
629             The I<%override_read_opts> options apply just to the current call to
630             I and will be forgotten afterwards. If you want these options
631             to persist between calls, set the option via the call to B. This
632             argument can be passed either by value or by reference. Either way will work.
633             See L for more details.
634              
635             If you plan on decrypting any values in the string, you must use the B
636             option in order for them to be successfully decrypted.
637              
638             On success, it returns a reference to itself so that it can be initialized
639             separately or as a single unit.
640              
641             =cut
642              
643             sub load_string
644             {
645 18     18 1 22421 DBUG_ENTER_FUNC ( @_ );
646 18         46651 my $self = shift;
647 18         50 my $string = shift; # The string to treat as a config file's contents.
648 18         42 my $read_opts = $_[0]; # Don't pop from the stack yet ...
649              
650 18   33     142 $self = $self->{PARENT} || $self;
651              
652             # Get the read options ...
653 18 100       88 $read_opts = {@_} if ( ref ($read_opts) ne "HASH" );
654 18         117 $read_opts = get_read_opts ( $read_opts, $self->{CONTROL}->{read_opts} );
655              
656 18 50       5392 unless ( $string ) {
657 0         0 my $msg = "You must provide a string to use this method!";
658 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
659             }
660              
661             # The filename is a reference to the string passed to this method!
662 18         51 my $filename = \$string;
663              
664             # If there's no alias provided, use a default value for it ...
665             # There is no filename to use for decryption purposes without it.
666 18 100       103 $read_opts->{alias} = "STRING" unless ( $read_opts->{alias} );
667              
668             # Dynamically correct based on type of string ...
669 18 50       115 $read_opts->{use_utf8} = ( $string =~ m/[^\x00-\xff]/ ) ? 1 : 0;
670              
671             # Behaves diferently based on who calls us ...
672 18   50     168 my $c = (caller(1))[3] || "";
673 18         64 my $by = __PACKAGE__ . "::merge_string";
674 18 100       66 if ( $c eq $by ) {
675             # Manually merging in another string as a config file.
676 4         8 push (@{$self->{CONTROL}->{MERGE}}, $filename);
  4         17  
677             } else {
678             # Loading the original string ...
679 14         82 $self->_wipe_internal_data ( $filename );
680             }
681              
682             # So refresh logic will work ...
683 18         3402 $self->{CONTROL}->{REFRESH_MODIFY_TIME}->{$filename} = 0; # No timestamp!
684 18         87 $self->{CONTROL}->{REFRESH_READ_OPTIONS}->{$filename} = get_read_opts ($read_opts);
685              
686             # So will auto-clear if die is called!
687 18         5243 local $self->{CONTROL}->{RECURSION}->{$filename} = 1;
688              
689             # Temp override of the default read options ...
690 18         72 local $self->{CONTROL}->{read_opts} = $read_opts;
691              
692 18 50       114 unless ( read_config ( $filename, $self ) ) {
693 0         0 my $msg = "Reading the config file had serious issues!";
694 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
695             }
696              
697 18         5583 DBUG_RETURN ( $self );
698             }
699              
700              
701             #######################################
702             # No POD on purpose ...
703             # For use by Advanced::Config::Reader only.
704             # Purpose is to allow source_file() a way to modify the date options.
705              
706             sub _load_config_with_new_date_opts
707             {
708 44     44   249 DBUG_ENTER_FUNC ( @_ );
709 44         28418 my $self = shift;
710 44         117 my $filename = shift;
711 44         101 my $read_opts = shift;
712 44         85 my $date_opts = shift;
713              
714 44   33     290 $self = $self->{PARENT} || $self;
715              
716 44         107 my $res;
717 44 100       170 if ( $date_opts ) {
718 1         2 my %dates;
719 1         10 $date_opts = get_date_opts ( $date_opts, $self->{CONTROL}->{date_opts} );
720             change_special_date_vars ( $self->{CONTROL}->{DATES}->{timestamp},
721 1         347 $date_opts, \%dates );
722              
723             # Temp override of the default date info ...
724 1         242 local $self->{CONTROL}->{date_opts} = $date_opts;
725 1         5 local $self->{CONTROL}->{DATES} = \%dates;
726              
727 1         7 $res = $self->load_config ( $filename, $read_opts );
728             } else {
729 43         323 $res = $self->load_config ( $filename, $read_opts );
730             }
731              
732 44         12927 DBUG_RETURN ( $res );
733             }
734              
735             #######################################
736              
737             =item $boolean = $cfg->merge_config ( $filename[, %override_read_opts] );
738              
739             Provides a way to merge multiple config files into a single B
740             object. Useful when the main config file can't source in the passed config
741             file due to different I<%read_opts> settings, or when a shared config file
742             can't be modified to source in a sub-config file, or if for some reason you
743             can't use the I Read Option during the initial load.
744              
745             Be aware that any tags in common with what's in this file will override the
746             tag/value pairs from any previous calls to I or I.
747             You may also reference any tags in the previous loads as variables during this
748             load. And if you have sections in common, it will merge each section's
749             tag/value pairs as well.
750              
751             Just be aware that I<%override_read_opts> is overriding the default options set
752             during the call to B, not necessarily the same options being used by
753             I. See L for more details on what
754             options are available.
755              
756             And finally if I<$filename> is a relative path, it's relative to the current
757             directory, not relative to the location of the config file its being merged
758             into.
759              
760             Returns B<1> if the config file was loaded and merged. Else B<0>.
761              
762             =cut
763              
764             sub merge_config
765             {
766 41     41 1 23965 DBUG_ENTER_FUNC ( @_ );
767 41         18713 my $self = shift;
768 41         108 my $file = shift; # Can be a relative path name if called directly ...
769             # my $rOpts = shift; # The read options to use ...
770              
771 41         220 my $res = $self->load_config ( $file, @_ );
772              
773 41 50       9862 DBUG_RETURN ( (defined $res) ? 1 : 0 );
774             }
775              
776              
777             #######################################
778              
779             =item $boolean = $cfg->merge_string ( $string[, %override_read_opts] );
780              
781             Provides a way to merge multiple strings into a single B
782             object. Modifying the I<$string> afterwards will not affect this object.
783              
784             Be aware that any tags in common with what's in this string will override the
785             tag/value pairs from any previous calls to load things into this object.
786              
787             Just be aware that I<%override_read_opts> is overriding the default options set
788             during the call to B, not necessarily the same options being used by
789             I or I. See L for more
790             details on what options are available.
791              
792             Returns B<1> if the string was merged into the object. Else B<0>.
793              
794             =cut
795              
796             sub merge_string
797             {
798 4     4 1 55611 DBUG_ENTER_FUNC ( @_ );
799 4         21909 my $self = shift;
800 4         12 my $string = shift; # The string to treat as a config file's contents.
801             # my $rOpts = shift; # The read options to use ...
802              
803 4         24 my $res = $self->load_string ( $string, @_ );
804              
805 4 50       1120 DBUG_RETURN ( (defined $res) ? 1 : 0 );
806             }
807              
808             #######################################
809              
810             =item $boolean = $cfg->refresh_config ( %refresh_opts );
811              
812             This boolean function detects if your config file or one of it's dependencies
813             has been updated. If your config file sources in other config files, those
814             config files are checked for changes as well.
815              
816             These changes could be to the config file itself or to any referenced variables
817             in your config file whose value has changed.
818              
819             If it detects any updates, then it will reload the config file into memory,
820             tossing any customizations you may have added via calls to B. It
821             will keep the current B options unchanged.
822              
823             =over 4
824              
825             =item Supported Refresh Options Are:
826              
827             "test_only => 1" - It will skip the reloading of the config file even if it
828             detects something changed. And just tell you if it detected any changes.
829              
830             "force => 1" - It will assume you know better and that something was updated.
831             It will almost always return true (B<1>) when used.
832              
833             =back
834              
835             It returns true (B<1>) if any updates were detected or the B option was
836             used. It will return false (B<0>) otherwise.
837              
838             It will also return false (B<0>) if you never called B or
839             B against this configuration object. In which case there is
840             nothing to refresh.
841              
842             =cut
843              
844             sub refresh_config
845             {
846 51     51 1 94943 DBUG_ENTER_FUNC (@_);
847 51         25187 my $self = shift;
848 51 50       375 my %opts = (ref ($_[0]) eq "HASH" ) ? %{$_[0]} : @_;
  0         0  
849              
850 51         135 my $updated = 0; # Assume no updates ...
851 51         126 my $skip = 0;
852              
853             # Do a case insensitive lookup of the options hash ...
854 51         198 foreach my $k ( keys %opts ) {
855 49 100       219 next unless ( $opts{$k} ); # Skip if set to false ...
856              
857 38 100       279 if ( $k =~ m/^force$/i ) {
    50          
858 27         85 $updated = 1; # Force an update ...
859             } elsif ( $k =~ m/^test_only$/i ) {
860 11         30 $skip = 1; # Skip any refresh of the config file ...
861             }
862             }
863              
864 51   33     323 $self = $self->{PARENT} || $self; # Force to the "main" section ...
865              
866 51 100       313 if ( $self->{CONTROL}->{SENSITIVE_CNT} != sensitive_cnt () ) {
867 1         288 $updated = 1;
868             }
869              
870             # If not forcing an update, try to detect any changes to the %ENV hash ...
871 51 100       11875 unless ( $updated ) {
872 23         89 DBUG_PRINT ("INFO", "Checking for changes to %ENV ...");
873 23         4866 foreach my $k ( sort keys %{$self->{CONTROL}->{ENV}} ) {
  23         145  
874 0 0       0 if ( ! defined $ENV{$k} ) {
    0          
875 0         0 $updated = 1; # Env. Var. was removed from the environment.
876             } elsif ( $ENV{$k} ne $self->{CONTROL}->{ENV}->{$k} ) {
877 0         0 $updated = 1; # Env. Var. was modified ...
878             }
879              
880 0 0       0 if ( $updated ) {
881 0         0 DBUG_PRINT ("WARN", "ENV{%s} changed it's value!", $k);
882 0         0 last;
883             }
884             }
885             }
886              
887             # If any of the special date vars were referenced in the config file,
888             # assume the program's been running long enough for one of them to change!
889 51         205 my %dates;
890 51 100       240 if ( $self->{CONTROL}->{DATE_USED} ) {
891 40         149 DBUG_PRINT ("INFO", "Checking the special date variables for changes ...");
892             my $res = set_special_date_vars ($self->{CONTROL}->{date_opts},
893 40         8636 \%dates, $self->{CONTROL}->{DATES});
894 40 50       9249 if ( $res >= $self->{CONTROL}->{DATE_USED} ) {
895 0         0 DBUG_PRINT ("WARN", "A referenced special date variable's value changed!");
896 0         0 $updated = 1;
897             } else {
898 40         147 $dates{timestamp} = $self->{CONTROL}->{DATES}->{timestamp};
899             }
900             }
901              
902             # Try to detect if any config files were modified ...
903 51 100       184 unless ( $updated ) {
904 23         84 DBUG_PRINT ("INFO", "Checking the file timestamps ...");
905 23         4675 foreach my $f ( sort keys %{$self->{CONTROL}->{REFRESH_MODIFY_TIME}} ) {
  23         180  
906             # Can't do ref($f) since key is stored as a string here.
907 35 100       1797 my $modify_time = ( $f =~ m/^SCALAR[(]0x[0-9a-f]+[)]$/ ) ? 0 : (stat( $f ))[9];
908              
909 35 50       212 if ( $modify_time > $self->{CONTROL}->{REFRESH_MODIFY_TIME}->{$f} ) {
910 0         0 DBUG_PRINT ("WARN", "File was modified: %s", $f);
911 0         0 $updated = 1;
912 0         0 last;
913             }
914             }
915             }
916              
917             # Refresh the config file's contents in memory ...
918 51 100 66     303 if ( $updated && $skip == 0 ) {
919 28         118 my $f = $self->{CONTROL}->{filename};
920 28         59 my @mlst = @{$self->{CONTROL}->{MERGE}};
  28         141  
921 28         83 my $opts = $self->{CONTROL}->{REFRESH_READ_OPTIONS};
922              
923             # Update date info gathered earlier only if these vars are used.
924 28 100       103 if ( $self->{CONTROL}->{DATE_USED} ) {
925 22         177 $self->{CONTROL}->{DATES} = \%dates;
926 22         74 $self->{CONTROL}->{DATE_USED} = 0;
927             }
928              
929 28         53 my $reload;
930 28         112 DBUG_PRINT ("LOG", "Calling Load Function ... %s", ref ($f));
931 28 100       6004 if ( ref ( $f ) eq "SCALAR" ) {
932 1         3 $reload = $self->load_string ( ${$f}, $opts->{$f} );
  1         10  
933             } else {
934 27         211 $reload = $self->load_config ( $f, $opts->{$f} );
935             }
936 26 100       6863 return DBUG_RETURN ( 0 ) unless ( defined $reload ); # Load failed ???
937              
938 23         511 foreach my $m (@mlst) {
939 20         3185 DBUG_PRINT ("LOG", "Calling Merge Function ... %s", ref ($m));
940 20 100       3966 if ( ref ( $m ) eq "SCALAR" ) {
941 2         5 $self->merge_string ( ${$m}, $opts->{$m} );
  2         15  
942             } else {
943 18         103 $self->merge_config ( $m, $opts->{$m} );
944             }
945             }
946             }
947              
948 46         1449 DBUG_RETURN ( $updated );
949             }
950              
951             #######################################
952              
953             # Private method ...
954             # Checks for recursion while sourcing in sub-files.
955             # Returns: 1 (yes) or 0 (no)
956              
957             sub _recursion_check
958             {
959 46     46   259 DBUG_ENTER_FUNC (@_);
960 46         27144 my $self = shift;
961 46         134 my $file = shift;
962              
963             # Get the main/parent section to work against!
964 46   66     340 $self = $self->{PARENT} || $self;
965              
966 46 100       307 DBUG_RETURN ( exists $self->{CONTROL}->{RECURSION}->{$file} ? 1 : 0 );
967             }
968              
969             #######################################
970              
971             # Private method ...
972             # Gets the requested tag from the current section.
973             # And then apply the required rules against the returned value.
974             # The {required} option isn't reliable until in this method!
975             # Returns: The tag hash ... (undef if it doesn't exist)
976             sub _base_get
977             {
978 67201     67201   100526 my $self = shift;
979 67201         106733 my $tag = shift;
980 67201         99235 my $opts = shift;
981 67201         103766 my $disable_req = shift;
982              
983             # Get the main/parent section to work against!
984 67201   66     264929 my $pcfg = $self->{PARENT} || $self;
985              
986             # Determine what the "get" options must be ...
987 67201         168160 my $get_opts = $pcfg->{CONTROL}->{get_opts};
988 67201 100       161055 $get_opts = get_get_opts ( $opts, $get_opts ) if ( $opts );
989              
990             # Check if a case insensitive lookup was requested ...
991 67201 100 66     651511 my $t = ( $pcfg->{CONTROL}->{read_opts}->{tag_case} && $tag ) ? lc ($tag) : $tag;
992              
993             # Check if we're overriding the required flag ...
994 67201         152305 my $req = $get_opts->{required};
995 67201 100       230654 local $get_opts->{required} = $disable_req ? 0 : $req;
996              
997             # Returns a hash reference to a local copy of the tag's data ... (or undef)
998             # Handles the inherit option if used.
999             my $data_ref =apply_get_rules ( $tag, $self->{SECTION_NAME},
1000             $self->{DATA}->{$t}, $pcfg->{DATA}->{$t},
1001             $pcfg->{CONTROL}->{ALLOW_UTF8},
1002 67201         479227 $get_opts );
1003              
1004 67201 50       12586990 return ( wantarray ? ($data_ref, $req) : $data_ref );
1005             }
1006              
1007              
1008             # Private method ...
1009             # Gets the requested tag value from the current section.
1010             # Returns: All 5 of the hash members individually ... + required flag setting.
1011             sub _base_get2
1012             {
1013 67145     67145   115205 my $self = shift;
1014 67145         107036 my $tag = shift;
1015 67145         112992 my $opts = shift;
1016              
1017 67145         183133 my ($data, $req) = $self->_base_get ( $tag, $opts, 0 );
1018              
1019 67145 100       177864 if ( defined $data ) {
1020 58088         364677 return ( $data->{VALUE}, $data->{MASK_IN_FISH}, $data->{FILE}, $data->{ENCRYPTED}, $data->{VARIABLE}, $req );
1021             } else {
1022 9057         42657 return ( undef, 0, "", 0, 0, $req ); # No such tag ...
1023             }
1024             }
1025              
1026              
1027             # Private method ...
1028             # Gets the requested tag date value from the current section.
1029             # or treat the tag name as the date if the tag doesn't exist!
1030             # Returns: All 5 of the hash members individually ... + required flag setting.
1031             sub _base_get3_date_str
1032             {
1033 32     32   89 my $self = shift;
1034 32         165 my $tag = shift;
1035 32         86 my $opts = shift;
1036 32         73 my $hyd_flg = shift; # Is it OK to return a HYD as HYD?
1037 32         106 my $cvt_hyd_flg = shift; # Is it OK to convert a HYD into a date str?
1038              
1039 32 50 66     159 if ($hyd_flg && $cvt_hyd_flg) {
1040 0         0 local $opts->{required} = 1;
1041 0         0 croak_helper ($opts, "Programming error! Can't set both hyd flags to true.", undef);
1042             }
1043              
1044 32         74 my ($data, $req);
1045             {
1046 32         66 local $opts->{date_active} = 0;
  32         115  
1047 32         137 ($data, $req) = $self->_base_get ( $tag, $opts, 1 ); # Does tag exist?
1048             }
1049              
1050             # If the tag doesn't exist, use $tag as a date string instead.
1051 32 100       143 unless ( defined $data ) {
1052 8         41 my $yr = _validate_date_str ($tag);
1053 8 100 66     1935 if ( defined $yr ) {
    100 66        
    100          
1054 4         25 return ( $tag, 0, "", 0, 0, $req ); # We have a valid date string!
1055             } elsif ( $hyd_flg && $tag =~ m/^[-]?\d+$/ ) {
1056 1         9 return ( $tag, 0, "", 0, 0, $req ); # We have a valid HYD string!
1057             } elsif ( $cvt_hyd_flg && $tag =~ m/^[-]?\d+$/ ) {
1058 1         4 my $dt = convert_hyd_to_date_str ($tag);
1059 1         176 return ( $dt, 0, "", 0, 0, $req ); # We have a valid date string!
1060             } else {
1061 2         9 local $opts->{required} = $req;
1062 2         12 croak_helper ($opts, "No such tag ($tag), nor is it a date string.", undef);
1063 2         16 return ( undef, 0, "", 0, 0, $req ); # No such tag/date ...
1064             }
1065             }
1066              
1067             # The tag exists, then it must reference a date!
1068 24         81 local $opts->{date_active} = 1;
1069 24         123 ($data, $req) = $self->_base_get ( $tag, $opts, 0 );
1070              
1071 24 100       149 if ( defined $data ) {
1072 12         108 return ( $data->{VALUE}, $data->{MASK_IN_FISH}, $data->{FILE}, $data->{ENCRYPTED}, $data->{VARIABLE}, $req );
1073             } else {
1074 12         82 return ( undef, 0, "", 0, 0, $req ); # Not a date ...
1075             }
1076             }
1077              
1078              
1079             #######################################
1080              
1081             =back
1082              
1083             =head2 Accessing the contents of an Advanced::Config object.
1084              
1085             These methods allow you to access the data loaded into this object.
1086              
1087             They all look in the current section for the B and if the B couldn't
1088             be found in this section and the I option was also set, it will then
1089             look in the parent/main section for the B. But if the I option
1090             wasn't set it wouldn't look there.
1091              
1092             If the requested B couldn't be found, they return B. But if the
1093             I option was used, it may call B instead!
1094              
1095             But normally they just return the requested B's value.
1096              
1097             They all use F<%override_get_opts>, passed by value or by reference, as an
1098             optional argument that overrides the default options provided in the call
1099             to F. The I and I options discussed above are two
1100             such options. In most cases this hash argument isn't needed. So leave it off
1101             if you are happy with the current defaults!
1102              
1103             See the POD under L, I for more
1104             details on what options you may override.
1105              
1106             Only the B> function was truly needed. But the other I
1107             methods were added for a couple of reasons. First to make it clear in your code
1108             what type of value is being returned and provide the ability to do validation of
1109             the B's value without having to validate it yourself! Another benefit was
1110             that it drastically reduced the number of exposed I needed for this
1111             module. Making it easier to use.
1112              
1113             Finally when these extra methods apply their validation, if the B's value
1114             fails the test, it treats it as a I not found> situation as described
1115             above.
1116              
1117             =over
1118              
1119             =item $value = $cfg->get_value ( $tag[, %override_get_opts] );
1120              
1121             This function looks up the requested B's value and returns it.
1122             See common details above.
1123              
1124             =cut
1125              
1126             sub get_value
1127             {
1128 49353     49353 1 25525433 DBUG_ENTER_FUNC ( @_ );
1129 49353         13239009 my $self = shift; # Reference to the current section.
1130 49353         99978 my $tag = shift; # The tag to look up ...
1131 49353         96054 my $opt_ref = $_[0]; # The override options ...
1132              
1133 49353 100       170767 $opt_ref = $self->_get_opt_args ( @_ ) if ( defined $opt_ref );
1134              
1135 49353         179279 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1136 49353 100       171658 DBUG_MASK (0) if ( $sensitive );
1137              
1138 49353         176582 DBUG_RETURN ( $value );
1139             }
1140              
1141             #######################################
1142             # A helper function to handle the various ways to find a hash as an argument!
1143             # Handles all 3 cases.
1144             # undef - No arguments
1145             # hash ref - passed by reference
1146             # something else - passed by value. (array)
1147              
1148             sub _get_opt_args
1149             {
1150 3229     3229   17158 my $self = shift; # Reference to the current section.
1151 3229         8617 my $opt_ref = $_[0]; # May be undef, a hash ref, or start of a hash ...
1152              
1153             # Convert the parameter array into a regular old hash reference ...
1154 3229         6513 my %opts;
1155 3229 100 66     18896 unless ( defined $opt_ref ) {
1156 284         915 $opt_ref = \%opts;
1157             } elsif ( ref ($opt_ref) ne "HASH" ) {
1158             %opts = @_;
1159             $opt_ref = \%opts;
1160             }
1161              
1162 3229         10146 return ( $opt_ref ); # The hash reference to use ...
1163             }
1164              
1165             #######################################
1166             # Another helper function to help with evaluating which value to use ...
1167             # Does a 4 step check.
1168             # 1) Use the $value if provided.
1169             # 2) If the key exists in the hash returned by _get_opt_args(), use it.
1170             # 3) Look it up in the default "Get Options" set via call to new().
1171             # 4) undef if all the above fail.
1172              
1173             sub _evaluate_hash_values
1174             {
1175 520     520   1010 my $self = shift; # References the current section.
1176 520         1115 my $key = shift; # The hash key to look up ...
1177 520         985 my $ghash = shift; # A hash ref returned by _get_opt_args().
1178 520         940 my $value = shift; # Use only if explicitly set ...
1179              
1180 520 100       1565 unless ( defined $value ) {
1181 167 50 33     1363 if ( defined $ghash && exists $ghash->{$key} ) {
1182 0         0 $value = $ghash->{$key}; # Passed via the get options hash ...
1183             } else {
1184             # Use the default from the call to new() ...
1185 167   66     1031 my $pcfg = $self->{PARENT} || $self;
1186 167 50       1179 if ( exists $pcfg->{CONTROL}->{get_opts}->{$key} ) {
1187 167         564 $value = $pcfg->{CONTROL}->{get_opts}->{$key};
1188             }
1189             }
1190             }
1191              
1192 520         1724 return ( $value ); # The value to use ...
1193             }
1194              
1195             #######################################
1196              
1197             =item $value = $cfg->get_integer ( $tag[, $rt_flag[, %override_get_opts]] );
1198              
1199             This function looks up the requested B's value and returns it if its an
1200             integer. If the B's value is a floating point number (ex 3.6), then the
1201             value is either truncated or rounded up based on the setting of the I.
1202              
1203             If I is set, it will perform truncation, so 3.6 becomes B<3>. If the
1204             flag is B or zero, it does rounding, so 3.6 becomes B<4>. Meaning the
1205             default is rounding.
1206              
1207             Otherwise if the B doesn't exist or its value is not numeric it will
1208             return B unless it's been marked as I. In that case B
1209             may be called instead.
1210              
1211             =cut
1212              
1213             sub get_integer
1214             {
1215 74     74 1 4616 DBUG_ENTER_FUNC ( @_ );
1216 74         45933 my $self = shift; # Reference to the current section.
1217 74         203 my $tag = shift; # The tag to look up ...
1218 74         132 my $rt_flag = shift; # 1 - truncate, 0 - rounding.
1219 74         312 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1220              
1221             # Flag if we should use truncation (2) or rounding (1) if needed ...
1222 74 100       359 local $opt_ref->{numeric} = $rt_flag ? 2 : 1;
1223              
1224 74         518 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1225 74 50       371 DBUG_MASK (0) if ( $sensitive );
1226              
1227 74         288 DBUG_RETURN ( $value );
1228             }
1229              
1230              
1231             #######################################
1232              
1233             =item $value = $cfg->get_numeric ( $tag[, %override_get_opts] );
1234              
1235             This function looks up the requested B's value and returns it if its
1236             value is numeric. Which means any valid integer or floating point number!
1237              
1238             If the B doesn't exist or its value is not numeric it will return B
1239             unless it's been marked as I. In that case B may be called
1240             instead.
1241              
1242             =cut
1243              
1244             sub get_numeric
1245             {
1246 37     37 1 2264 DBUG_ENTER_FUNC ( @_ );
1247 37         21977 my $self = shift; # Reference to the current section.
1248 37         117 my $tag = shift; # The tag to look up ...
1249 37         186 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1250              
1251             # Asking for a floating point number ...
1252 37         141 local $opt_ref->{numeric} = 3;
1253              
1254 37         167 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1255 37 50       176 DBUG_MASK (0) if ( $sensitive );
1256              
1257 37         149 DBUG_RETURN ( $value );
1258             }
1259              
1260              
1261             #######################################
1262              
1263             =item $value = $cfg->get_boolean ( $tag[, %override_get_opts] );
1264              
1265             Treats the B's value as a boolean value and returns I,
1266             B<0> or B<1>.
1267              
1268             Sometimes you just want to allow for basically a true/false answer
1269             without having to force a particular usage in the config file.
1270             This function converts the B's value accordingly.
1271              
1272             So it handles pairs like: Yes/No, True/False, Good/Bad, Y/N, T/F, G/B, 1/0,
1273             On/Off, etc. and converts them into a boolean value. This test is case
1274             insensitive. It never returns what's actually in the config file.
1275              
1276             If it doesn't recognize something it always returns B<0>.
1277              
1278             =cut
1279              
1280             sub get_boolean
1281             {
1282 32     32 1 7706 DBUG_ENTER_FUNC ( @_ );
1283 32         18260 my $self = shift; # Reference to the current section.
1284 32         101 my $tag = shift; # The tag to look up ...
1285 32         160 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1286              
1287             # Turns on the treat as a boolean option ...
1288 32         132 local $opt_ref->{auto_true} = 1;
1289              
1290 32         142 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1291 32 50       161 DBUG_MASK (0) if ( $sensitive );
1292              
1293 32         131 DBUG_RETURN ( $value );
1294             }
1295              
1296              
1297             #######################################
1298              
1299             =item $date = $cfg->get_date ( $tag[, $language[, %override_get_opts]] );
1300              
1301             This function looks up the requested B's value and returns it if its
1302             value contains a valid date. The returned value will always be in I
1303             format no matter what format or language was actually used in the config file
1304             for the date.
1305              
1306             If the B doesn't exist or its value is not a date it will return B
1307             unless it's been marked as I. In that case B may be called
1308             instead.
1309              
1310             If I<$language> is undefined, it will use the default language defined in the
1311             call to I for parsing the date. (B if not overridden.) Otherwise
1312             it must be a valid language defined by B. If it's a wrong or
1313             bad language, your date might not be recognized as valid.
1314              
1315             Unlike most other B options, when parsing the B's value, it's not
1316             looking to match the entire string. It's looking for a date portion inside the
1317             value and ignores any miscellaneous information. There was just too many
1318             semi-valid potential surrounding data to worry about parsing that info as well.
1319              
1320             So B returns "2017-01-03".
1321              
1322             There are also a few date related options for I<%override_get_opts> to use that
1323             you may find useful.
1324              
1325             See L for more details.
1326              
1327             =cut
1328              
1329             sub get_date
1330             {
1331 2568     2568 1 379098 DBUG_ENTER_FUNC ( @_ );
1332 2568         350610 my $self = shift; # Reference to the current section.
1333 2568         5775 my $tag = shift; # The tag to look up ...
1334 2568         4837 my $language = shift; # The language the date appears in ...
1335 2568         11136 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1336              
1337 2568         9419 local $opt_ref->{date_active} = 1;
1338 2568 100       10003 local $opt_ref->{date_language} = $language if ( defined $language );
1339              
1340 2568         7893 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1341 2568 50       10156 DBUG_MASK (0) if ( $sensitive );
1342              
1343 2568         10298 DBUG_RETURN ( $value );
1344             }
1345              
1346              
1347             #######################################
1348              
1349             =item $hyd = $cfg->get_hyd_date ( $tag[, $language[, %override_get_opts]] );
1350              
1351             Behaves the same as B except that it returns the date in the Hundred
1352             Year Date (I) format. Which is defined as the number of days since
1353             B. Which has the I<$hyd> of B<1>.
1354              
1355             But if the tag B<$tag> doesn't exist in the config file, and it's name is in the
1356             format of I, it will return the I for that date instead.
1357              
1358             This date format makes it very easy to do math against dates,
1359              
1360             See L for more details.
1361              
1362             =cut
1363              
1364             sub get_hyd_date
1365             {
1366 8     8 1 14376 DBUG_ENTER_FUNC ( @_ );
1367 8         4385 my $self = shift; # Reference to the current section.
1368 8         23 my $tag = shift; # The tag to look up ...
1369 8         24 my $language = shift; # The language the date appears in ...
1370 8         66 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1371              
1372 8         34 local $opt_ref->{date_active} = 1;
1373 8 50       39 local $opt_ref->{date_language} = $language if ( defined $language );
1374              
1375 8         43 my ( $value, $sensitive, $required ) = ($self->_base_get3_date_str ( $tag, $opt_ref, 0, 0 ))[0,1,5];
1376 8 50       37 if ( $sensitive ) {
1377 0         0 DBUG_MASK (0);
1378 0         0 DBUG_MASK_NEXT_FUNC_CALL (-1);
1379             }
1380 8 100       57 return DBUG_RETURN (undef) unless (defined $value);
1381              
1382 4         25 $value = calc_hundred_year_date ( $value );
1383              
1384 4         914 DBUG_RETURN ( $value );
1385             }
1386              
1387              
1388             #######################################
1389              
1390             =item $dow = $cfg->get_dow_date ( $tag[, $language[, %override_get_opts]] );
1391              
1392             Behaves the same as B except that it returns the Day of Week (I)
1393             that the date falls on. It returns the I as a number between B<0> and
1394             B<6>. For Sunday to Saturday.
1395              
1396             But if the tag B<$tag> doesn't exist in the config file, and it's name is in the
1397             format of I, it will return the I for that date instead.
1398              
1399             Finally if B<$tag> still didn't match it checks if it's an integer and it
1400             assumes you want the I for a I date.
1401              
1402             See L for more details.
1403              
1404             =cut
1405              
1406             sub get_dow_date
1407             {
1408 8     8 1 13448 DBUG_ENTER_FUNC ( @_ );
1409 8         4472 my $self = shift; # Reference to the current section.
1410 8         20 my $tag = shift; # The tag to look up ...
1411 8         19 my $language = shift; # The language the date appears in ...
1412 8         80 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1413              
1414 8         35 local $opt_ref->{date_active} = 1;
1415 8 50       31 local $opt_ref->{date_language} = $language if ( defined $language );
1416              
1417 8         42 my ( $value, $sensitive, $required ) = ($self->_base_get3_date_str ( $tag, $opt_ref, 1, 0 ))[0,1,5];
1418 8 50       35 if ( $sensitive ) {
1419 0         0 DBUG_MASK (0);
1420 0         0 DBUG_MASK_NEXT_FUNC_CALL (-1);
1421             }
1422 8 100       33 return DBUG_RETURN (undef) unless (defined $value);
1423              
1424 5         25 $value = calc_day_of_week ( $value );
1425              
1426 5         1235 DBUG_RETURN ( $value );
1427             }
1428              
1429             #######################################
1430              
1431             =item $doy = $cfg->get_doy_date ( $tag[, $language[, %override_get_opts]] );
1432              
1433             Behaves the same as B except that it returns the Day of Year (I)
1434             that the date falls on. It returns the I as a number between B<1> and
1435             B<366>. With Jan 1st being B<1> and Dec 31st being B<365> or B<366>.
1436              
1437             But if the tag B<$tag> doesn't exist in the config file, and it's name is in the
1438             format of I, it will return the I for that date instead.
1439              
1440             See L for more details.
1441              
1442             =cut
1443              
1444             sub get_doy_date
1445             {
1446 8     8 1 15176 DBUG_ENTER_FUNC ( @_ );
1447 8         4388 my $self = shift; # Reference to the current section.
1448 8         20 my $tag = shift; # The tag to look up ...
1449 8         18 my $language = shift; # The language the date appears in ...
1450 8         43 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1451              
1452 8         54 local $opt_ref->{date_active} = 1;
1453 8 50       34 local $opt_ref->{date_language} = $language if ( defined $language );
1454              
1455 8         43 my ( $value, $sensitive, $required ) = ($self->_base_get3_date_str ( $tag, $opt_ref, 0, 0 ))[0,1,5];
1456 8 50       36 if ( $sensitive ) {
1457 0         0 DBUG_MASK (0);
1458 0         0 DBUG_MASK_NEXT_FUNC_CALL (-1);
1459             }
1460 8 100       37 return DBUG_RETURN (undef) unless (defined $value);
1461              
1462 4         22 $value = calc_day_of_year ( $value );
1463              
1464 4         967 DBUG_RETURN ( $value );
1465             }
1466              
1467              
1468             #######################################
1469              
1470             =item $newDate = $cfg->get_adjusted_date ( $tag, $adjYr, $adjMon[, $language[, %override_get_opts]] );
1471              
1472             Behaves the same as B except that it returns an offsetted date.
1473             Where both I<$adjYr> & I<$adjMon> are integers.
1474             It correctly handles leap years and the proper number of days per month.
1475              
1476             But if the tag B<$tag> doesn't exist in the config file, and it's name is in the
1477             format of I, it will return the offset to that date instead.
1478              
1479             Example:
1480              
1481             B<2020-02-15> = get_adjusted_date ("2024-01-15", -4, 1);
1482              
1483             Finally if B<$tag> still didn't match it checks if it's an integer and it
1484             assumes you want the offset to be against the I instead. You can use this
1485             option to convert a I into a I as follows:
1486              
1487             B<$date_str> = get_adjusted_date (I<$hyd>, 0, 0);
1488              
1489             See L for more details.
1490              
1491             =cut
1492              
1493             sub get_adjusted_date
1494             {
1495 8     8 1 15004 DBUG_ENTER_FUNC ( @_ );
1496 8         10995 my $self = shift; # Reference to the current section.
1497 8         69 my $tag = shift; # The tag to look up ...
1498 8         19 my $adjYrs = shift; # Number of years to adjust.
1499 8         21 my $adjMons = shift; # Number of months to adjust.
1500 8         15 my $language = shift; # The language the date appears in ...
1501 8         46 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1502              
1503 8         38 local $opt_ref->{date_active} = 1;
1504 8 50       34 local $opt_ref->{date_language} = $language if ( defined $language );
1505              
1506 8         41 my ( $value, $sensitive, $required ) = ($self->_base_get3_date_str ( $tag, $opt_ref, 0, 1 ))[0,1,5];
1507 8 50       39 if ( $sensitive ) {
1508 0         0 DBUG_MASK (0);
1509 0         0 DBUG_MASK_NEXT_FUNC_CALL (-1);
1510             }
1511 8 100       46 return DBUG_RETURN (undef) unless (defined $value);
1512              
1513 5         26 $value = adjust_date_str ( $value, $adjYrs, $adjMons );
1514 5 50       1233 unless (defined $value) {
1515 0         0 local $opt_ref->{required} = $required;
1516 0         0 croak_helper ($opt_ref, "usage errror", undef);
1517             }
1518              
1519 5         19 DBUG_RETURN ( $value );
1520             }
1521              
1522              
1523             #######################################
1524              
1525             =item $value = $cfg->get_filename ( $tag[, $access[, %override_get_opts]] );
1526              
1527             Treats the B's value as a filename. If the referenced file doesn't exist
1528             it returns I instead, as if the B didn't exist.
1529              
1530             B defines the minimum access required. If that minimum access isn't
1531             met it returns I instead, as if the B didn't exist. B
1532             may be I to just check for existence.
1533              
1534             The B levels are B for read, B for write and B for execute.
1535             You may also combine them if you wish in any order.
1536             Ex: B, B, B ...
1537              
1538             =cut
1539              
1540             sub get_filename
1541             {
1542 15     15 1 11166 DBUG_ENTER_FUNC ( @_ );
1543 15         7937 my $self = shift; # Reference to the current section.
1544 15         39 my $tag = shift; # The tag to look up ...
1545 15         27 my $access = shift; # undef or contains "r", "w" and/or "x" ...
1546 15         66 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1547              
1548             # Verify that the tag's value points to an existing filename ...
1549 15         53 local $opt_ref->{filename} = 1; # Existance ...
1550 15 50       52 if ( defined $access ) {
1551 0 0       0 $opt_ref->{filename} |= 2 if ( $access =~ m/[rR]/ ); # -r--
1552 0 0       0 $opt_ref->{filename} |= 4 if ( $access =~ m/[wW]/ ); # --w-
1553 0 0       0 $opt_ref->{filename} |= 2 | 8 if ( $access =~ m/[xX]/ ); # -r-x
1554             }
1555              
1556 15         58 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1557 15 50       59 DBUG_MASK (0) if ( $sensitive );
1558              
1559 15         57 DBUG_RETURN ( $value );
1560             }
1561              
1562              
1563             #######################################
1564              
1565             =item $value = $cfg->get_directory ( $tag[, $access[, %override_get_opts]] );
1566              
1567             Treats the B's value as a directory. If the referenced directory doesn't
1568             exist it returns I instead, as if the B didn't exist.
1569              
1570             B defines the minimum access required. If that minimum access isn't met
1571             it returns I instead, as if the B didn't exist. B may be
1572             I to just check for existence.
1573              
1574             The B levels are B for read and B for write. You may also combine
1575             them if you wish in any order. Ex: B or B.
1576              
1577              
1578             =cut
1579              
1580             sub get_directory
1581             {
1582 16     16 1 18121 DBUG_ENTER_FUNC ( @_ );
1583 16         8659 my $self = shift; # Reference to the current section.
1584 16         34 my $tag = shift; # The tag to look up ...
1585 16         32 my $access = shift; # undef or contains "r" and/or "w" ...
1586 16         87 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1587              
1588             # Verify that the tag's value points to an existing directory ...
1589             # Execute permission is always required to reference a directory's contents.
1590 16         50 local $opt_ref->{directory} = 1; # Existance ...
1591 16 100       50 if ( defined $access ) {
1592 4 50       24 $opt_ref->{directory} |= 2 | 8 if ( $access =~ m/[rR]/ ); # dr-x
1593 4 100       16 $opt_ref->{directory} |= 4 | 8 if ( $access =~ m/[wW]/ ); # d-wx
1594             }
1595              
1596 16         70 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1597 16 50       70 DBUG_MASK (0) if ( $sensitive );
1598              
1599 16         55 DBUG_RETURN ( $value );
1600             }
1601              
1602             #######################################
1603              
1604             =back
1605              
1606             =head2 Accessing the contents of an Advanced::Config object in LIST mode.
1607              
1608             These methods allow you to access the data loaded into each B in list mode.
1609             Splitting the B's data up into arrays and hashes. Otherwise these
1610             functions behave similarly to the one's above.
1611              
1612             Each function asks for a I used to split the B's value into an
1613             array of values. If the pattern is B it will use the default
1614             I specified during he call to F. Otherwise it can be
1615             either a string or a RegEx. See Perl's I function for more details.
1616             After the value has been split, it will perform any requested validation and
1617             most functions will return B if even one element in the list fails it's
1618             edits. It was added as its own argument, instead of just relying on the
1619             override option hash, since this option is probably the one that gets overridden
1620             most often.
1621              
1622             They also support the same I and I options described for the
1623             scalar functions as well.
1624              
1625             They also all allow F<%override_get_opts>, passed by value or by reference, as
1626             an optional argument that overrides the default options provided in the call
1627             to F. If you should use both option I and the I
1628             argument, the I argument takes precedence. So leave this optional
1629             hash argument off if you are happy with the current defaults.
1630              
1631             =over
1632              
1633             =item $array_ref = $cfg->get_list_values ( $tag[, $pattern[, $sort[, %override_get_opts ]]] );
1634              
1635             This function looks up the requested B's value and then splits it up into
1636             an array and returns a reference to it.
1637              
1638             If I is 1 it does an ascending sort. If I is -1, it will do a
1639             descending sort instead. By default it will do no sort.
1640              
1641             See the common section above for more details.
1642              
1643             =cut
1644              
1645             sub get_list_values
1646             {
1647 176     176 1 263601 DBUG_ENTER_FUNC ( @_ );
1648 176         79292 my $self = shift; # Reference to the current section.
1649 176         442 my $tag = shift; # The tag to look up ...
1650 176         449 my $split_ptrn = shift; # The split pattern to use to call to split().
1651 176         435 my $sort = shift; # The sort order.
1652 176         866 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1653              
1654             # Tells us to split the tag's value up into an array ...
1655 176         772 local $opt_ref->{split} = 1;
1656              
1657             # Tells how to spit up the tag's value ...
1658             local $opt_ref->{split_pattern} =
1659 176         984 $self->_evaluate_hash_values ("split_pattern", $opt_ref, $split_ptrn);
1660              
1661             # Tells how to sort the resulting array ...
1662             local $opt_ref->{sort} =
1663 176         552 $self->_evaluate_hash_values ("sort", $opt_ref, $sort);
1664              
1665 176         735 my ( $value, $sensitive ) = $self->_base_get2 ( $tag, $opt_ref );
1666 176 50       758 DBUG_MASK (0) if ( $sensitive );
1667              
1668 176         649 DBUG_RETURN ( $value ); # An array ref or undef.
1669             }
1670              
1671              
1672             #######################################
1673              
1674             =item $hash_ref = $cfg->get_hash_values ( $tag[, $pattern[, $value[, \%merge[, %override_get_opts]]]] );
1675              
1676             This method is a bit more complex than L. Like that method it
1677             splits up the B's value into an array. But it then converts that array
1678             into the keys of a hash whose value for each entry is set to I.
1679              
1680             Then if the optional I hash reference was provided, and that key isn't
1681             present in that hash, it adds the missing value to the I hash. It never
1682             overrides any existing entries in the I hash!
1683              
1684             It always returns the hash reference based on the B's split value or an
1685             empty hash if the B doesn't exist or has no value.
1686              
1687             =cut
1688              
1689             sub get_hash_values
1690             {
1691 17     17 1 17034 DBUG_ENTER_FUNC ( @_ );
1692 17         8547 my $self = shift; # Reference to the current section.
1693 17         48 my $tag = shift; # The tag to look up ...
1694 17         41 my $split_ptrn = shift; # The split pattern to use to call to split().
1695 17         36 my $hash_value = shift; # Value to assign to each hash member.
1696 17         38 my $merge_ref = shift; # A hash to merge the results into
1697             # my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1698              
1699 17         171 my $key_vals = $self->get_list_values ($tag, $split_ptrn, 0, @_);
1700              
1701 17         4123 my %my_hash;
1702 17 50       65 if ( $key_vals ) {
1703             # Will we be merging the results into a different hash?
1704 17 100 66     2402 my $m_flg = ( $merge_ref && ref ($merge_ref) eq "HASH" ) ? 1 : 0;
1705              
1706             # Build the hash(s) from the array ...
1707 17         53 foreach ( @{$key_vals} ) {
  17         52  
1708 106         265 $my_hash{$_} = $hash_value;
1709 106 100 100     288 if ( $m_flg && ! exists $merge_ref->{$_} ) {
1710 11         29 $merge_ref->{$_} = $hash_value;
1711             }
1712             }
1713             }
1714              
1715 17         64 DBUG_RETURN ( \%my_hash );
1716             }
1717              
1718              
1719             #######################################
1720              
1721             =item $array_ref = $cfg->get_list_integer ( $tag[, $rt_flag[, $pattern[, $sort[, %override_get_opts]]]] );
1722              
1723             This is the list version of F. See that function for the meaning
1724             of I<$rt_flag>. See F for the meaning of I<$pattern> and
1725             I<$sort>.
1726              
1727             =cut
1728              
1729             sub get_list_integer
1730             {
1731 54     54 1 15805 DBUG_ENTER_FUNC ( @_ );
1732 54         36111 my $self = shift; # Reference to the current section.
1733 54         269 my $tag = shift; # The tag to look up ...
1734 54         131 my $rt_flag = shift; # 1 - truncate, 0 - rounding.
1735 54         127 my $split_ptrn = shift; # The split pattern to use to call to split().
1736 54         97 my $sort = shift; # The sort order.
1737 54         316 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1738              
1739             # Tells us to split the tag's value up into an array ...
1740 54         232 local $opt_ref->{split} = 1;
1741              
1742             # Tells how to spit up the tag's value ...
1743             local $opt_ref->{split_pattern} =
1744 54         247 $self->_evaluate_hash_values ("split_pattern", $opt_ref, $split_ptrn);
1745              
1746             # Tells how to sort the resulting array ...
1747             local $opt_ref->{sort} =
1748 54         164 $self->_evaluate_hash_values ("sort", $opt_ref, $sort);
1749              
1750 54         217 my $value = $self->get_integer ( $tag, $rt_flag, $opt_ref );
1751              
1752 54         15831 DBUG_RETURN ( $value ); # An array ref or undef.
1753             }
1754              
1755              
1756             #######################################
1757              
1758             =item $array_ref = $cfg->get_list_numeric ( $tag[, $pattern[, $sort[, %override_get_opts]]] );
1759              
1760             This is the list version of F. See F for the
1761             meaning of I<$pattern> and I<$sort>.
1762              
1763             =cut
1764              
1765             sub get_list_numeric
1766             {
1767 27     27 1 55314 DBUG_ENTER_FUNC ( @_ );
1768 27         16966 my $self = shift; # Reference to the current section.
1769 27         80 my $tag = shift; # The tag to look up ...
1770 27         75 my $split_ptrn = shift; # The split pattern to use to call to split().
1771 27         72 my $sort = shift; # The sort order.
1772 27         181 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1773              
1774             # Tells us to split the tag's value up into an array ...
1775 27         131 local $opt_ref->{split} = 1;
1776              
1777             # Tells how to spit up the tag's value ...
1778             local $opt_ref->{split_pattern} =
1779 27         156 $self->_evaluate_hash_values ("split_pattern", $opt_ref, $split_ptrn);
1780              
1781             # Tells how to sort the resulting array ...
1782             local $opt_ref->{sort} =
1783 27         87 $self->_evaluate_hash_values ("sort", $opt_ref, $sort);
1784              
1785 27         138 my $value = $self->get_numeric ( $tag, $opt_ref );
1786              
1787 27         7935 DBUG_RETURN ( $value ); # An array ref or undef.
1788             }
1789              
1790              
1791             #######################################
1792              
1793             =item $array_ref = $cfg->get_list_boolean ( $tag[, $pattern[, %override_get_opts]] );
1794              
1795             This is the list version of F. See F for the
1796             meaning of I<$pattern>.
1797              
1798             =cut
1799              
1800             sub get_list_boolean
1801             {
1802 2     2 1 494 DBUG_ENTER_FUNC ( @_ );
1803 2         1068 my $self = shift; # Reference to the current section.
1804 2         7 my $tag = shift; # The tag to look up ...
1805 2         5 my $split_ptrn = shift; # The split pattern to use to call to split().
1806 2         11 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1807              
1808             # Tells us to split the tag's value up into an array ...
1809 2         8 local $opt_ref->{split} = 1;
1810              
1811             # Tells how to spit up the tag's value ...
1812             local $opt_ref->{split_pattern} =
1813 2         9 $self->_evaluate_hash_values ("split_pattern", $opt_ref, $split_ptrn);
1814              
1815 2         9 my $value = $self->get_boolean ( $tag, $opt_ref );
1816              
1817 2         525 DBUG_RETURN ( $value ); # An array ref or undef.
1818             }
1819              
1820              
1821             #######################################
1822              
1823             =item $array_ref = $cfg->get_list_date ( $tag, $pattern[, $language[, %override_get_opts]] );
1824              
1825             This is the list version of F. See F for the
1826             meaning of I<$pattern>. In this case I<$pattern> is a required option since
1827             dates bring unique parsing challenges and the default value usually isn't good
1828             enough.
1829              
1830             =cut
1831              
1832             sub get_list_date
1833             {
1834 2     2 1 499 DBUG_ENTER_FUNC ( @_ );
1835 2         1143 my $self = shift; # Reference to the current section.
1836 2         7 my $tag = shift; # The tag to look up ...
1837 2         192 my $split_ptrn = shift; # The split pattern to use to call to split().
1838 2         7 my $language = shift; # The languate the date appears in ...
1839 2         11 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1840              
1841             # Tells us to split the tag's value up into an array ...
1842 2         10 local $opt_ref->{split} = 1;
1843              
1844             # Tells how to spit up the tag's value ... (it's required this time!)
1845             # So allow in either place, argument or option.
1846 2 50       7 $split_ptrn = $opt_ref->{split_pattern} unless ( defined $split_ptrn );
1847 2 50       9 unless ( defined $split_ptrn ) {
1848 0         0 my $msg = "Missing required \$pattern argument in call to get_list_date()!\n";
1849 0         0 die ( $msg );
1850             }
1851              
1852 2         6 local $opt_ref->{split_pattern} = $split_ptrn;
1853              
1854 2         9 my $value = $self->get_date ( $tag, $language, $opt_ref );
1855              
1856 2         515 DBUG_RETURN ( $value ); # An array ref or undef.
1857             }
1858              
1859              
1860             #######################################
1861              
1862             =item $array_ref = $cfg->get_list_filename ( $tag[, $access[, $pattern[, %override_get_opts]]] );
1863              
1864             This is the list version of F. See that function for the meaning
1865             of I<$access>. See F for the meaning of I<$pattern>.
1866              
1867             =cut
1868              
1869             sub get_list_filename
1870             {
1871 2     2 1 2633 DBUG_ENTER_FUNC ( @_ );
1872 2         1223 my $self = shift; # Reference to the current section.
1873 2         6 my $tag = shift; # The tag to look up ...
1874 2         6 my $access = shift; # undef or contains "r", "w" and/or "x" ...
1875 2         5 my $split_ptrn = shift; # The split pattern to use to call to split().
1876 2         11 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1877              
1878             # Tells us to split the tag's value up into an array ...
1879 2         8 local $opt_ref->{split} = 1;
1880              
1881             # Tells how to spit up the tag's value ...
1882             local $opt_ref->{split_pattern} =
1883 2         9 $self->_evaluate_hash_values ("split_pattern", $opt_ref, $split_ptrn);
1884              
1885 2         9 my $value = $self->get_filename ( $tag, $access, $opt_ref );
1886              
1887 2         573 DBUG_RETURN ( $value ); # An array ref or undef.
1888             }
1889              
1890              
1891             #######################################
1892              
1893             =item $array_ref = $cfg->get_list_directory ( $tag[, $access[, $pattern[, %override_get_opts]]] );
1894              
1895             This is the list version of F. See that function for the meaning
1896             of I<$access>. See F for the meaning of I<$pattern>.
1897              
1898             =cut
1899              
1900             sub get_list_directory
1901             {
1902 2     2 1 7215 DBUG_ENTER_FUNC ( @_ );
1903 2         1138 my $self = shift; # Reference to the current section.
1904 2         5 my $tag = shift; # The tag to look up ...
1905 2         6 my $access = shift; # undef or contains "r", "w" and/or "x" ...
1906 2         5 my $split_ptrn = shift; # The split pattern to use to call to split().
1907 2         12 my $opt_ref = $self->_get_opt_args ( @_ ); # The override options ...
1908              
1909             # Tells us to split the tag's value up into an array ...
1910 2         8 local $opt_ref->{split} = 1;
1911              
1912             # Tells how to spit up the tag's value ...
1913             local $opt_ref->{split_pattern} =
1914 2         9 $self->_evaluate_hash_values ("split_pattern", $opt_ref, $split_ptrn);
1915              
1916 2         11 my $value = $self->get_directory ( $tag, $access, $opt_ref );
1917              
1918 2         608 DBUG_RETURN ( $value ); # An array ref or undef.
1919             }
1920              
1921              
1922             #######################################
1923             # Private method ...
1924             # Returns (Worked, Hide)
1925             # Caller either wants both values or none of them.
1926             # Should never write to fish ...
1927             sub _base_set
1928             {
1929 33482     33482   68579 my $self = shift;
1930 33482         65747 my $tag = shift;
1931 33482         63276 my $value = shift;
1932 33482   100     92328 my $file = shift || ""; # The file the tag was defined in.
1933 33482   100     127267 my $force_sensitive = shift || 0;
1934 33482   100     112780 my $still_encrypted = shift || 0;
1935 33482   100     105837 my $has_variables = shift || 0;
1936              
1937             # Get the main/parent section to work against!
1938             # my $pcfg = $self->get_section();
1939 33482   66     113014 my $pcfg = $self->{PARENT} || $self;
1940              
1941             # Check if case insensitive handling was requested ...
1942 33482 100       125870 $tag = lc ($tag) if ( $pcfg->{CONTROL}->{read_opts}->{tag_case} );
1943              
1944 33482 50       107649 if ( $tag =~ m/^shft3+$/i ) {
1945 0         0 return ( 0, 0 ); # Set failed ... tag name not allowed.
1946             }
1947              
1948 33482 100 100     147490 my $hide = ($force_sensitive || $self->{SENSITIVE_SECTION}) ? 1 : 0;
1949              
1950 33482 100       109576 if ( exists $self->{DATA}->{$tag} ) {
1951 1559 100       6288 $hide = 1 if ( $self->{DATA}->{$tag}->{MASK_IN_FISH} );
1952             } else {
1953 31923         56457 my %data;
1954 31923         136554 $self->{DATA}->{$tag} = \%data;
1955 31923 100       77806 unless ( $hide ) {
1956 31135 100       132862 $hide = 1 if ( should_we_hide_sensitive_data ($tag, 1) );
1957             }
1958             }
1959              
1960             # The value must never be undefined!
1961 33482 50       162039 $self->{DATA}->{$tag}->{VALUE} = (defined $value) ? $value : "";
1962              
1963             # What file the tag was found in ...
1964 33482         99999 $self->{DATA}->{$tag}->{FILE} = $file;
1965              
1966             # Must it be hidden in the fish logs?
1967 33482         78451 $self->{DATA}->{$tag}->{MASK_IN_FISH} = $hide;
1968              
1969             # Is the value still encrypted?
1970 33482 100       101633 $self->{DATA}->{$tag}->{ENCRYPTED} = $still_encrypted ? 1 : 0;
1971              
1972             # Does the value still reference variables?
1973 33482 100       94630 $self->{DATA}->{$tag}->{VARIABLE} = $has_variables ? 1 : 0;
1974              
1975 33482         328870 return ( 1, $hide );
1976             }
1977              
1978              
1979             #######################################
1980              
1981             =back
1982              
1983             =head2 Manipulating the contents of an Advanced::Config object.
1984              
1985             These methods allow you to manipulate the contents of an B
1986             object in many ways. They all just update what's in memory and not the contents
1987             of the config file itself.
1988              
1989             So should the contents of this module get refreshed, you will loose any changes
1990             made by these B<4> methods.
1991              
1992             =over
1993              
1994             =item $ok = $cfg->set_value ( $tag, $value );
1995              
1996             Adds the requested I<$tag> and it's I<$value> to the current section in the
1997             I object.
1998              
1999             If the I<$tag> already exists, it will be overridden with its new I<$value>.
2000              
2001             It returns B<1> on success or B<0> if your request was rejected!
2002             It will also print a warning if it was rejected.
2003              
2004             =cut
2005              
2006             sub set_value
2007             {
2008 27     27 1 20296 my $self = shift; # Reference to the current section of the object.
2009 27         73 my $tag = shift; # The tag set to value ...
2010 27         77 my $value = shift;
2011              
2012 27         110 my ( $worked, $sensitive ) = $self->_base_set ($tag, $value, undef);
2013              
2014 27 100       103 DBUG_MASK_NEXT_FUNC_CALL (2) if ( $sensitive );
2015 27         243 DBUG_ENTER_FUNC ( $self, $tag, $value, @_ );
2016              
2017 27 50       15872 unless ( $worked ) {
2018 0         0 warn ("You may not use \"${tag}\" as your tag name!\n");
2019             }
2020              
2021 27         101 DBUG_RETURN ($worked);
2022             }
2023              
2024             #######################################
2025              
2026             =item $bool = $cfg->rename_tag ( $old_tag, $new_tag );
2027              
2028             Renames the tag found in the current section to it's new name. If the
2029             I<$new_tag> already exists it is overwriting by I<$old_tag>. If I<$old_tag>
2030             doesn't exist the rename fails.
2031              
2032             Returns B<1> on success, B<0> on failure.
2033              
2034             =cut
2035              
2036             sub rename_tag
2037             {
2038 24     24 1 6262 DBUG_ENTER_FUNC (@_);
2039 24         12653 my $self = shift;
2040 24         51 my $old_tag = shift;
2041 24         57 my $new_tag = shift;
2042              
2043 24 50 33     135 unless ( defined $old_tag && defined $new_tag ) {
2044 0         0 warn ("All arguments to rename_tag() are required!\n");
2045 0         0 return DBUG_RETURN (0);
2046             }
2047              
2048 24 50       118 if ( $new_tag =~ m/^shft3+$/i ) {
2049 0         0 warn ("You may not use \"${new_tag}\" as your new tag name!\n");
2050 0         0 return DBUG_RETURN (0);
2051             }
2052              
2053             # Get the main/parent section to work against!
2054 24   33     110 my $pcfg = $self->{PARENT} || $self;
2055              
2056             # Check if a case insensitive lookup was requested ...
2057 24 50       72 if ( $pcfg->{CONTROL}->{read_opts}->{tag_case} ) {
2058 0 0       0 $old_tag = lc ($old_tag) if ( $old_tag );
2059 0 0       0 $new_tag = lc ($new_tag) if ( $new_tag );
2060             }
2061              
2062 24 50       97 if ( $old_tag eq $new_tag ) {
2063 0         0 warn ("The new tag name must be different from the old tag name!\n");
2064 0         0 return DBUG_RETURN (0);
2065             }
2066              
2067             # Was there something to rename ???
2068 24 50       71 if ( exists $self->{DATA}->{$old_tag} ) {
2069 24         70 $self->{DATA}->{$new_tag} = $self->{DATA}->{$old_tag};
2070 24         48 delete ( $self->{DATA}->{$old_tag} );
2071 24         88 return DBUG_RETURN (1);
2072             }
2073              
2074 0         0 DBUG_RETURN (0);
2075             }
2076              
2077             #######################################
2078              
2079             =item $bool = $cfg->move_tag ( $tag, $new_section[, $new_tag] );
2080              
2081             This function moves the tag from the current section to the specified new
2082             section. If I<$new_tag> was provided that will be the tag's new name in
2083             the new section. If the tag already exists in the new section it will be
2084             overwritten.
2085              
2086             If the tag or the new section doesn't exist, the move will fail! It will also
2087             fail if the new section is the current section.
2088              
2089             Returns B<1> on success, B<0> on failure.
2090              
2091             =cut
2092              
2093             sub move_tag
2094             {
2095 0     0 1 0 DBUG_ENTER_FUNC (@_);
2096 0         0 my $self = shift;
2097 0         0 my $tag = shift;
2098 0         0 my $new_section = shift;
2099 0         0 my $new_tag = shift;
2100              
2101 0 0       0 $new_tag = $tag unless ( defined $new_tag );
2102              
2103 0 0 0     0 unless ( defined $tag && defined $new_section ) {
2104 0         0 warn ("Both \$tag and \$new_section are required for move_tag()!\n");
2105 0         0 return DBUG_RETURN (0);
2106             }
2107              
2108 0 0       0 if ( $new_tag =~ m/^shft3+$/i ) {
2109 0         0 warn ("You may not use \"${new_tag}\" as your new tag name!\n");
2110 0         0 return DBUG_RETURN (0);
2111             }
2112              
2113             # Get the main/parent section to work against!
2114 0   0     0 my $pcfg = $self->{PARENT} || $self;
2115              
2116             # Check if a case insensitive lookup was requested ...
2117 0 0 0     0 $tag = lc ($tag) if ( $pcfg->{CONTROL}->{read_opts}->{tag_case} && $tag );
2118              
2119 0   0     0 my $cfg = $self->get_section ( $new_section ) || $self;
2120              
2121 0 0 0     0 if ( $self ne $cfg && exists $self->{DATA}->{$tag} ) {
2122 0         0 $cfg->{DATA}->{$new_tag} = $self->{DATA}->{$tag};
2123 0         0 delete ( $self->{DATA}->{$tag} );
2124 0         0 return DBUG_RETURN (1);
2125             }
2126              
2127 0         0 DBUG_RETURN (0);
2128             }
2129              
2130             #######################################
2131              
2132             =item $bool = $cfg->delete_tag ( $tag );
2133              
2134             This function removes the requested I<$tag> found in the current section from
2135             the configuration data in memory.
2136              
2137             Returns B<1> on success, B<0> if the I<$tag> didn't exist.
2138              
2139             =cut
2140              
2141             sub delete_tag
2142             {
2143 0     0 1 0 DBUG_ENTER_FUNC (@_);
2144 0         0 my $self = shift;
2145 0         0 my $tag = shift;
2146              
2147 0 0       0 unless ( defined $tag ) {
2148 0         0 return DBUG_RETURN (0); # Nothing to delete!
2149             }
2150              
2151             # Get the main/parent section to work against!
2152 0   0     0 my $pcfg = $self->{PARENT} || $self;
2153              
2154             # Check if a case insensitive lookup was requested ...
2155 0 0 0     0 $tag = lc ($tag) if ( $pcfg->{CONTROL}->{read_opts}->{tag_case} && $tag );
2156              
2157             # Was there something to delete ???
2158 0 0       0 if ( exists $self->{DATA}->{$tag} ) {
2159 0         0 delete ( $self->{DATA}->{$tag} );
2160 0         0 return DBUG_RETURN (1);
2161             }
2162              
2163 0         0 DBUG_RETURN (0);
2164             }
2165              
2166             #######################################
2167              
2168             =back
2169              
2170             =head2 Breaking your Advanced::Config object into Sections.
2171              
2172             Defining sections allow you to break up your configuration files into multiple
2173             independent parts. Or in advanced configurations using sections to override
2174             default values defined in the main/unlabled section.
2175              
2176             =over
2177              
2178             =item $section = $cfg->get_section ( [$section_name[, $required]] );
2179              
2180             Returns the I object for the requested section in your config
2181             file. If the I<$section_name> doesn't exist, it will return I. If
2182             I<$required> is set, it will call B instead.
2183              
2184             If no I<$section_name> was provided, it returns the default I
section.
2185              
2186             =cut
2187              
2188             sub get_section
2189             {
2190 72484     72484 1 1207203 DBUG_ENTER_FUNC ( @_ );
2191 72484         24859800 my $self = shift;
2192 72484         141907 my $section = shift;
2193 72484   100     271578 my $required = shift || 0;
2194              
2195 72484   66     300937 $self = $self->{PARENT} || $self; # Force to parent section ...
2196              
2197 72484 100       296638 unless ( defined $section ) {
    100          
2198 35155         81066 $section = DEFAULT_SECTION;
2199 0         0 } elsif ( $section =~ m/^\s*$/ ) {
2200 165         473 $section = DEFAULT_SECTION;
2201             } else {
2202 37164         103319 $section = lc ($section);
2203 37164         99713 $section =~ s/^\s+//;
2204 37164         104292 $section =~ s/\s+$//;
2205             }
2206              
2207 72484 100       245684 if ( exists $self->{SECTIONS}->{$section} ) {
2208 71805         246916 return DBUG_RETURN ( $self->{SECTIONS}->{$section} );
2209             }
2210              
2211 679 50       1970 if ( $required ) {
2212 0         0 die ("Section \"$section\" doesn't exist in this ", __PACKAGE__,
2213             " class!\n");
2214             }
2215              
2216 679         2468 DBUG_RETURN (undef);
2217             }
2218              
2219             #######################################
2220              
2221             =item $name = $cfg->section_name ( );
2222              
2223             This function returns the name of the current section I<$cfg> points to.
2224              
2225             =cut
2226              
2227             sub section_name
2228             {
2229 828     828 1 3355 DBUG_ENTER_FUNC ( @_ );
2230 828         355241 my $self = shift;
2231 828         3395 DBUG_RETURN ( $self->{SECTION_NAME} );
2232             }
2233              
2234             #######################################
2235              
2236             =item $scfg = $cfg->create_section ( $name );
2237              
2238             Creates a new section called I<$name> within the current Advanced::Config object
2239             I<$cfg>. It returns the I object that it created. If a
2240             section of that same name already exists it will return B.
2241              
2242             There is no such thing as sub-sections, so if I<$cfg> is already points to a
2243             section, then it looks up the parent object and associates the new section with
2244             the parent object instead.
2245              
2246             =cut
2247              
2248             sub create_section
2249             {
2250 333     333 1 3559 DBUG_ENTER_FUNC ( @_ );
2251 333         129637 my $self = shift;
2252 333         903 my $name = shift;
2253              
2254             # This test bypasses all the die logic in the special case constructor!
2255             # That constructor is no longer exposed in the POD.
2256 333 50       1321 if ( $self->get_section ( $name ) ) {
2257 0         0 return DBUG_RETURN (undef); # Name is already in use ...
2258             }
2259              
2260 333         66813 DBUG_RETURN ( $self->new_section ( $self, $name ) );
2261             }
2262              
2263             #######################################
2264              
2265             =back
2266              
2267             =head2 Searching the contents of an Advanced::Config object.
2268              
2269             This section deals with the methods available for searching for content within
2270             your B object.
2271              
2272             =over
2273              
2274             =item @list = $cfg->find_tags ( $pattern[, $override_inherit] );
2275              
2276             It returns a list of all tags whose name contains the passed pattern.
2277              
2278             If the pattern is B or the empty string, it will return all tags in
2279             the current section. Otherwise it does a case insensitive comparison of the
2280             pattern against each tag to see if it should be returned or not.
2281              
2282             If I is provided it overrides the current I option's
2283             setting. If B it uses the current I setting. If I
2284             evaluates to true, it looks in the current section I the main section for
2285             a match. Otherwise it just looks in the current section.
2286              
2287             The returned list of tags will be sorted in alphabetical order.
2288              
2289             =cut
2290              
2291             sub find_tags
2292             {
2293 1022     1022 1 677695 DBUG_ENTER_FUNC (@_);
2294 1022         306095 my $self = shift;
2295 1022         2818 my $pattern = shift;
2296 1022         2084 my $inherit = shift; # undef, 0, or 1.
2297              
2298 1022         1905 my @lst; # The list of tags found ...
2299              
2300 1022   66     5523 my $pcfg = $self->{PARENT} || $self;
2301              
2302 1022 100       4837 $inherit = $pcfg->{CONTROL}->{get_opts}->{inherit} unless (defined $inherit);
2303              
2304 1022         2211 foreach my $tag ( sort keys %{$self->{DATA}} ) {
  1022         87950  
2305 91335 100 66     260845 unless ( $pattern ) {
2306 42502         66951 push (@lst, $tag);
2307             } elsif ( $tag =~ m/${pattern}/i ) {
2308             push (@lst, $tag);
2309             }
2310             }
2311              
2312             # Are we searching the parent/main section as well?
2313 1022 100 100     12068 if ( $inherit && $pcfg != $self ) {
2314 4         59 DBUG_PRINT ("INFO", "Also searching the 'main' section ...");
2315 4         691 foreach my $tg ( sort keys %{$pcfg->{DATA}} ) {
  4         36  
2316             # Ignore tags repeated from the current section
2317 32 100       74 next if ( exists $self->{DATA}->{$tg} );
2318              
2319 21 50 0     101 unless ( $pattern ) {
2320 21         34 push (@lst, $tg);
2321             } elsif ( $tg =~ m/$pattern/i ) {
2322             push (@lst, $tg);
2323             }
2324             }
2325              
2326 4         33 @lst = sort ( @lst ); # Sort the merged list.
2327             }
2328              
2329 1022         5105 DBUG_RETURN ( @lst );
2330             }
2331              
2332              
2333             #######################################
2334             # No pod on purpose since exposing it would just cause confusion.
2335             # It's a special case variant for find_tags().
2336             # Just called from Advanced::Config::Reader::apply_modifier.
2337              
2338             sub _find_variables
2339             {
2340 2     2   7 DBUG_ENTER_FUNC (@_);
2341 2         963 my $self = shift;
2342 2         7 my $pattern = shift;
2343              
2344 2         4 my %res;
2345              
2346             # Find all tags begining with the pattern ...
2347 2         10 foreach ( $self->find_tags ("^${pattern}") ) {
2348 2         611 $res{$_} = 1;
2349             }
2350              
2351             # Find all environment variables starting with the given pattern ...
2352 2         23 foreach ( keys %ENV ) {
2353             # Never include these 2 special tags in any list ...
2354 60 50 33     121 next if ( defined $secret_tag && $secret_tag eq $_ );
2355 60 50 33     92 next if ( defined $fish_tag && $fish_tag eq $_ );
2356              
2357 60 100       161 $res{$_} = 4 if ( $_ =~ m/^${pattern}/ );
2358             }
2359              
2360             # Skip checking the Perl special variables we use (rule 5)
2361             # Since it's now part of (rule 6)
2362              
2363             # Check the pre-defined module variables ... (rule 6)
2364 2         16 foreach ( keys %begin_special_vars ) {
2365 20 50       72 $res{$_} = 6 if ( $_ =~ m/^${pattern}/ );
2366             }
2367              
2368             # The special date variables ... (rule 7)
2369 2   33     12 my $pcfg = $self->{PARENT} || $self;
2370 2         5 foreach ( keys %{$pcfg->{CONTROL}->{DATES}} ) {
  2         18  
2371 32 100       81 $res{$_} = 7 if ( $_ =~ m/^${pattern}/ );
2372             }
2373              
2374 2         15 DBUG_RETURN ( sort keys %res );
2375             }
2376              
2377              
2378             #######################################
2379              
2380             =item @list = $cfg->find_values ( $pattern[, $override_inherit] );
2381              
2382             It returns a list of all tags whose values contains the passed pattern.
2383              
2384             If the pattern is B or the empty string, it will return all tags in
2385             the current section. Otherwise it does a case insensitive comparison of the
2386             pattern against each tag's value to see if it should be returned or not.
2387              
2388             If I is provided it overrides the current I option's
2389             setting. If B it uses the current I setting. If I
2390             evaluates to true, it looks in the current section I the main section for
2391             a match. Otherwise it just looks in the current section.
2392              
2393             The returned list of tags will be sorted in alphabetical order.
2394              
2395             =cut
2396              
2397             sub find_values
2398             {
2399 0     0 1 0 DBUG_ENTER_FUNC (@_);
2400 0         0 my $self = shift;
2401 0         0 my $pattern = shift;
2402 0         0 my $inherit = shift;
2403              
2404 0         0 my @lst; # The list of tags found ...
2405              
2406 0   0     0 my $pcfg = $self->{PARENT} || $self;
2407              
2408 0 0       0 $inherit = $pcfg->{CONTROL}->{get_opts}->{inherit} unless (defined $inherit);
2409              
2410 0         0 foreach my $tag ( sort keys %{$self->{DATA}} ) {
  0         0  
2411 0 0       0 unless ( $pattern ) {
2412 0         0 push (@lst, $tag);
2413             } else {
2414 0         0 my $value = $self->{DATA}->{$tag}->{VALUE};
2415 0 0       0 if ( $value =~ m/$pattern/i ) {
2416 0         0 push (@lst, $tag);
2417             }
2418             }
2419             }
2420              
2421             # Are we searching the parent/main section as well?
2422 0 0 0     0 if ( $inherit && $pcfg != $self ) {
2423 0         0 DBUG_PRINT ("INFO", "Also searching the main section ...");
2424 0         0 foreach my $tg ( sort keys %{$pcfg->{DATA}} ) {
  0         0  
2425             # Ignore tags repeated from the current section
2426 0 0       0 next if ( exists $self->{DATA}->{$tg} );
2427              
2428 0 0       0 unless ( $pattern ) {
2429 0         0 push (@lst, $tg);
2430             } else {
2431 0         0 my $value = $pcfg->{DATA}->{$tg}->{VALUE};
2432 0 0       0 if ( $value =~ m/$pattern/i ) {
2433 0         0 push (@lst, $tg);
2434             }
2435             }
2436             }
2437              
2438 0         0 @lst = sort (@lst); # Sort the merged list.
2439             }
2440              
2441 0         0 DBUG_RETURN (@lst);
2442             }
2443              
2444             #######################################
2445              
2446             =item @list = $cfg->find_sections ( $pattern );
2447              
2448             It returns a list of all section names which match this pattern.
2449              
2450             If the pattern is B or the empty string, it will return all the section
2451             names. Otherwise it does a case insensitive comparison of the pattern against
2452             each section name to see if it should be returned or not.
2453              
2454             The returned list of section names will be sorted in alphabetical order.
2455              
2456             =cut
2457              
2458             sub find_sections
2459             {
2460 164     164 1 240713 DBUG_ENTER_FUNC (@_);
2461 164         80113 my $self = shift;
2462 164         490 my $pattern = shift;
2463              
2464 164   33     1278 $self = $self->{PARENT} || $self; # Force to parent section ...
2465              
2466 164         387 my @lst;
2467 164         353 foreach my $name ( sort keys %{$self->{SECTIONS}} ) {
  164         1828  
2468 920 100 66     1763 unless ( $pattern ) {
2469 908         1868 push (@lst, $name);
2470             } elsif ( $name =~ m/$pattern/i ) {
2471             push (@lst, $name);
2472             }
2473             }
2474              
2475 164         875 DBUG_RETURN (@lst);
2476             }
2477              
2478              
2479             #######################################
2480              
2481             =back
2482              
2483             =head2 Miscellaneous methods against Advanced::Config object.
2484              
2485             These methods while useful don't really fall into a category of their own. So
2486             they are collected here in the miscellaneous section.
2487              
2488             =over
2489              
2490             =item $file = $cfg->filename ( );
2491              
2492             Returns the fully qualified file name used to load the config file into memory.
2493              
2494             =cut
2495              
2496             sub filename
2497             {
2498 18     18 1 4862 DBUG_ENTER_FUNC ( @_ );
2499 18         9132 my $self = shift;
2500              
2501             # The request only applies to the parent instance ...
2502 18   33     159 $self = $self->{PARENT} || $self;
2503              
2504 18         103 DBUG_RETURN( $self->{CONTROL}->{filename} );
2505             }
2506              
2507              
2508             #######################################
2509              
2510             =item ($ropts, $gopts, $dopts) = $cfg->get_cfg_settings ( );
2511              
2512             This method returns references to copies of the current options used to
2513             manipulate the config file. It returns copies of these hashes so feel free to
2514             modify them without fear of affecting the behavior of this module.
2515              
2516             =cut
2517              
2518             sub get_cfg_settings
2519             {
2520 34337     34337 1 142633 DBUG_ENTER_FUNC (@_);
2521 34337         11579016 my $self = shift;
2522              
2523             # Get the main/parent section to work against!
2524 34337   66     151672 my $pcfg = $self->{PARENT} || $self;
2525              
2526 34337         78243 my $ctrl = $pcfg->{CONTROL};
2527              
2528 34337         67087 my (%r_opts, %g_opts, %d_opts);
2529 34337 50 33     188832 %r_opts = %{$ctrl->{read_opts}} if ( $ctrl && $ctrl->{read_opts} );
  34337         1267880  
2530 34337 50 33     243857 %g_opts = %{$ctrl->{get_opts}} if ( $ctrl && $ctrl->{get_opts} );
  34337         420893  
2531 34337 50 33     178359 %d_opts = %{$ctrl->{date_opts}} if ( $ctrl && $ctrl->{date_opts} );
  34337         207759  
2532              
2533 34337         148466 DBUG_RETURN ( \%r_opts, \%g_opts, \%d_opts );
2534             }
2535              
2536              
2537             #######################################
2538              
2539             =item $cfg->export_tag_value_to_ENV ( $tag, $value );
2540              
2541             Used to export the requested tag/value pair to the %ENV hash. If it's also
2542             marked as an %ENV tag the config file depends on, it updates internal
2543             bookkeeping so that it won't trigger false refreshes.
2544              
2545             Once it's been promoted to the %ENV hash the change can't be backed out again.
2546              
2547             =cut
2548              
2549             sub export_tag_value_to_ENV
2550             {
2551 4     4 1 12 my $self = shift;
2552 4         16 my $tag = shift;
2553 4         12 my $value = shift;
2554 4   50     20 my $hide = $_[0] || 0; # Not taken from stack on purpose ...
2555 4 50       33 DBUG_ENTER_FUNC ( $self, $tag, ($hide ? "*"x8 : $value), @_ );
2556              
2557 4         2524 $ENV{$tag} = $value;
2558              
2559             # Check if the change afects the refresh logic ...
2560 4   33     38 my $pcfg = $self->{PARENT} || $self;
2561 4 50       60 if ( exists $pcfg->{CONTROL}->{ENV}->{$tag} ) {
2562 0         0 $pcfg->{CONTROL}->{ENV}->{$tag} = $value; # It did ...
2563             }
2564              
2565 4         24 DBUG_VOID_RETURN ();
2566             }
2567              
2568             #######################################
2569              
2570             =item $sensitive = $cfg->chk_if_sensitive ( $tag[, $override_inherit] );
2571              
2572             This function looks up the requested tag in the current section of the config
2573             file and returns if this module thinks the existing value is sensitive (B<1>)
2574             or not (B<0>).
2575              
2576             If the tag doesn't exist, it will always return that it isn't sensitive. (B<0>)
2577              
2578             An existing tag references sensitive data if one of the following is true.
2579             1) Advanced::Config::Options::should_we_hide_sensitive_data() says it is
2580             or it says the section the tag was found in was sensitive.
2581             2) The config file marked the tag in its comment to HIDE it.
2582             3) The config file marked it as being encrypted.
2583             4) It referenced a variable that was marked as sensitive.
2584              
2585             If I is provided it overrides the current I option's
2586             setting. If B it uses the current I setting. If I
2587             evaluates to true, it looks in the current section I the main section for
2588             a match. Otherwise it just looks in the current section for the tag.
2589              
2590             =cut
2591              
2592             sub chk_if_sensitive
2593             {
2594 188     188 1 355258 DBUG_ENTER_FUNC ( @_ );
2595 188         113693 my $self = shift; # Reference to the current section.
2596 188         673 my $tag = shift; # The tag to look up ...
2597 188         463 my $inherit = shift; # undef, 0, or 1.
2598              
2599 188   66     1253 my $pcfg = $self->{PARENT} || $self;
2600              
2601 188 100       1039 $inherit = $pcfg->{CONTROL}->{get_opts}->{inherit} unless (defined $inherit);
2602 188         794 local $pcfg->{CONTROL}->{get_opts}->{inherit} = $inherit;
2603              
2604 188         915 my $sensitive = ($self->_base_get2 ( $tag ))[1];
2605              
2606 188         900 DBUG_RETURN ( $sensitive );
2607             }
2608              
2609              
2610             #######################################
2611              
2612             =item $encrypted = $cfg->chk_if_still_encrypted ( $tag[, $override_inherit] );
2613              
2614             This function looks up the requested tag in the current section of the config
2615             file and returns if this module thinks the existing value is still encrypted
2616             (B<1>) or not (B<0>).
2617              
2618             If the tag doesn't exist, it will always return B<0>!
2619              
2620             This module always automatically decrypts everything unless the "Read" option
2621             B was used. In that case this method was added to detect
2622             which tags still needed their values decrypted before they were used.
2623              
2624             If I is provided it overrides the current I option's
2625             setting. If B it uses the current I setting. If I
2626             evaluates to true, it looks in the current section I the main section for
2627             a match. Otherwise it just looks in the current section for the tag.
2628              
2629             =cut
2630              
2631             sub chk_if_still_encrypted
2632             {
2633 217     217 1 48907 DBUG_ENTER_FUNC ( @_ );
2634 217         97846 my $self = shift; # Reference to the current section.
2635 217         2943 my $tag = shift; # The tag to look up ...
2636 217         368 my $inherit = shift; # undef, 0, or 1.
2637              
2638 217   66     983 my $pcfg = $self->{PARENT} || $self;
2639              
2640 217 50       1050 $inherit = $pcfg->{CONTROL}->{get_opts}->{inherit} unless (defined $inherit);
2641 217         623 local $pcfg->{CONTROL}->{get_opts}->{inherit} = $inherit;
2642              
2643 217         734 my $encrypted = ($self->_base_get2 ( $tag ))[3];
2644              
2645 217         821 DBUG_RETURN ( $encrypted );
2646             }
2647              
2648              
2649             #######################################
2650              
2651             =item $bool = $cfg->chk_if_still_uses_variables ( $tag[, $override_inherit] );
2652              
2653             This function looks up the requested tag in the current section of the config
2654             file and returns if the tag's value contained variables that failed to expand
2655             when the config file was parsed. (B<1> - has variable, B<0> - none.)
2656              
2657             If the tag doesn't exist, or you called C to create it, this function
2658             will always return B<0> for that tag!
2659              
2660             There are only two cases where it can ever return true (B<1>). The first case
2661             is when you used the B option. The second case is if you
2662             used the B option and you had a variable that referenced
2663             a tag that is still encrypted. But use of those two options should be rare.
2664              
2665             If I is provided it overrides the current I option's
2666             setting. If B it uses the current I setting. If I
2667             evaluates to true, it looks in the current section I the main section for
2668             a match. Otherwise it just looks in the current section for the tag.
2669              
2670             =cut
2671              
2672             sub chk_if_still_uses_variables
2673             {
2674 415     415 1 102045 DBUG_ENTER_FUNC ( @_ );
2675 415         213140 my $self = shift; # Reference to the current section.
2676 415         819 my $tag = shift; # The tag to look up ...
2677 415         768 my $inherit = shift; # undef, 0, or 1.
2678              
2679 415   66     1902 my $pcfg = $self->{PARENT} || $self;
2680              
2681 415 50       1946 $inherit = $pcfg->{CONTROL}->{get_opts}->{inherit} unless (defined $inherit);
2682 415         1330 local $pcfg->{CONTROL}->{get_opts}->{inherit} = $inherit;
2683              
2684 415         1593 my $bool = ($self->_base_get2 ( $tag ))[4];
2685              
2686 415         1550 DBUG_RETURN ( $bool );
2687             }
2688              
2689              
2690             #######################################
2691              
2692             =item $string = $cfg->toString ( [$addEncryptFlags[, \%override_read_opts] );
2693              
2694             This function converts the current object into a string that is the equivalent
2695             of the config file loaded into memory without any comments.
2696              
2697             If I<$addEncryptFlags> is set to a non-zero value, it will add the needed
2698             comment to the end of each line saying it's waiting to be encrypted. So that
2699             you may later call B to encrypt it.
2700              
2701             If you provide I<%override_read_opts> it will use the information in that hash
2702             to format the string. Otherwise it will use the defaults from B.
2703              
2704             =cut
2705              
2706             sub toString
2707             {
2708 3     3 1 1970 DBUG_ENTER_FUNC ( @_ );
2709 3         1847 my $self = shift;
2710 3         11 my $encrypt_flag = shift;
2711 3         22 my $read_opts = $self->_get_opt_args ( @_ ); # The override options ...
2712              
2713 3   33     32 my $pcfg = $self->{PARENT} || $self;
2714 3         25 my $rOpts = get_read_opts ($read_opts, $pcfg->{CONTROL}->{read_opts});
2715              
2716 3         872 my $cmt = "";
2717 3 100       45 if ( $encrypt_flag ) {
2718 2         18 $cmt = " " . format_encrypt_cmt ( $rOpts );
2719             }
2720              
2721 3         539 my $line;
2722 3         9 my $string = "";
2723 3         8 my $cnt = 0;
2724 3         20 foreach my $name ( $self->find_sections () ) {
2725 6         911 my $cfg = $self->get_section ($name);
2726 6         1720 $line = format_section_line ($name, $rOpts);
2727 6         1722 $string .= "\n${line}\n";
2728              
2729 6 50       42 ++$cnt if ( should_we_hide_sensitive_data ( $name, 1 ) );
2730              
2731 6         43 foreach my $tag ( $cfg->find_tags (undef, 0) ) {
2732 24 100       2054 ++$cnt if ( $cfg->chk_if_sensitive ($tag, 0) );
2733              
2734 24         6956 $line = format_tag_value_line ($cfg, $tag, $rOpts);
2735 24         7160 $string .= " " . ${line} . ${cmt} . "\n";
2736             }
2737             }
2738              
2739             # Mask the return value if anything seems sensitive.
2740 3 50       32 DBUG_MASK (0) if ( $cnt > 0 );
2741              
2742 3         141 DBUG_RETURN ( $string );
2743             }
2744              
2745              
2746             #######################################
2747              
2748             =item $hashRef = $cfg->toHash ( [$dropIfSensitive] );
2749              
2750             This function converts the current object into a hash reference that is the
2751             equivalent of the config file loaded into memory. Modifying the returned
2752             hash reference will not modify this object's content.
2753              
2754             If a section has no members, it will not appear in the hash.
2755              
2756             If I<$dropIfSensitive> is set to a non-zero value, it will not export any data
2757             to the returned hash reference that this module thinks is sensitive.
2758              
2759             The returned hash reference has the following keys.
2760             S<$hash_ref-E{B
}-E{B}>.
2761              
2762             =cut
2763              
2764             sub toHash
2765             {
2766 7     7 1 16974 DBUG_ENTER_FUNC ( @_ );
2767 7         3701 my $self = shift;
2768 7         18 my $sensitive = shift;
2769              
2770 7         14 my %data;
2771              
2772 7         42 foreach my $sect ( $self->find_sections () ) {
2773             # Was the section name itself sensitive ...
2774 17 50 66     1901 next if ( $sensitive && should_we_hide_sensitive_data ( $sect, 1 ) );
2775              
2776 17         34 my %section_data;
2777 17         108 my $cfg = $self->get_section ($sect, 1);
2778              
2779 17         4345 my $cnt = 0;
2780 17         166 foreach my $tag ( $cfg->find_tags (undef, 0) ) {
2781 28         3060 my ($val, $hide) = $cfg->_base_get2 ($tag);
2782 28 100 100     119 next if ( $sensitive && $hide );
2783 23         68 $section_data{$tag} = $val;
2784 23         47 ++$cnt;
2785             }
2786              
2787             # Only add a section that has tags in it!
2788 17 100       1616 $data{$sect} = \%section_data if ( $cnt );
2789             }
2790              
2791 7         33 DBUG_RETURN ( \%data );
2792             }
2793              
2794              
2795             #######################################
2796              
2797             =back
2798              
2799             =head2 Encryption/Decryption of your config files.
2800              
2801             The methods here deal with the encryption/decryption of your config file before
2802             you use this module to load it into memory. They allow you to make the contents
2803             of your config files more secure.
2804              
2805             =over
2806              
2807             =item $status = $cfg->encrypt_config_file ( [$file[, $encryptFile[, \%rOpts]]] );
2808              
2809             This function encrypts all tag values inside the specified config file that are
2810             marked as ready for encryption and generates a new config file with everything
2811             encrypted. If a tag/value pair isn't marked as ready for encryption it is left
2812             alone. By default this label is B.
2813              
2814             After a tag's value has been encrypted, the label in the comment is updated
2815             from B to B in the config file.
2816              
2817             If you are adding new B tags to an existing config file that already
2818             has B tags in it, you must use the same encryption related options in
2819             I<%rOpts> as the last time. Otherwise you won't be able to decrypt all
2820             encrypted values.
2821              
2822             Finally if you provide argument I<$encryptFile>, it will write the encrypted
2823             file to that new file instead of overwriting the current file. But if you do
2824             this, you will require the use of the I option to be able to decrypt
2825             it again using the new name. This file only gets created if the return status
2826             is B<1>.
2827              
2828             If you leave off the I<$file> and I<\%rOpts>, it will instead use the values
2829             inherited from the call to B.
2830              
2831             This method ignores any request to source in other config files. You must
2832             encrypt each file individually.
2833              
2834             It is an error if basename(I<$file>) is a symbolic link and you didn't provide
2835             I<$encryptFile>.
2836              
2837             Returns: B<1> if something was encrypted. B<-1> if nothing was encrypted.
2838             Otherwise B<0> on error.
2839              
2840             =cut
2841              
2842             sub encrypt_config_file
2843             {
2844 5     5 1 13552 DBUG_ENTER_FUNC ( @_ );
2845 5         2677 my $self = shift;
2846 5         16 my $file = shift;
2847 5         11 my $newFile = shift;
2848 5         8 my $rOpts = shift;
2849              
2850 5   33     64 my $pcfg = $self->{PARENT} || $self;
2851              
2852 5         29 my $msg;
2853 5 100       37 if ( $file ) {
    50          
2854 3         15 $file = $self->_fix_path ( $file );
2855             } elsif ( $pcfg->{CONTROL}->{filename} ) {
2856 2         16 $file = $pcfg->{CONTROL}->{filename};
2857             } else {
2858 0         0 $msg = "You must provide a file name to encrypt!";
2859             }
2860              
2861 5 50 33     4121 unless ( $msg || -f $file ) {
2862 0         0 $msg = "No such file to encrypt or it's unreadable! -- $file";
2863             }
2864              
2865 5 50 33     135 if ( -l $file && ! $newFile ) {
2866 0         0 $msg = "You can't encrypt a file via it's symbolic link -- $file";
2867             }
2868              
2869 5         19 my $scratch;
2870 5 100       16 if ( $newFile ) {
2871 3         11 $scratch = $self->_fix_path ($newFile);
2872 3 50       826 if ( $scratch eq $file ) {
2873 0         0 $msg = "Args: file & encryptFile must be different!";
2874             }
2875             } else {
2876 2         17 $scratch = $file . ".$$.encrypted";
2877             }
2878              
2879 5 100       16 if ( $rOpts ) {
2880 3         20 $rOpts = get_read_opts ($rOpts, $pcfg->{CONTROL}->{read_opts});
2881             } else {
2882 2         14 $rOpts = $pcfg->{CONTROL}->{read_opts};
2883             }
2884              
2885 5 50       875 if ( $msg ) {
2886 0         0 return DBUG_RETURN ( croak_helper ( $rOpts, $msg, 0 ) );
2887             }
2888              
2889 5         50 my $status = encrypt_config_file_details ($file, $scratch, $rOpts);
2890              
2891             # Some type of error ... or nothing was encrypted ...
2892 5 50 33     1392 if ( $status == 0 || $status == -1 ) {
    100          
2893 0         0 unlink ( $scratch );
2894              
2895             # Replacing the original file ...
2896             } elsif ( ! $newFile ) {
2897 2         1007 unlink ( $file );
2898 2         94 move ( $scratch, $file );
2899             }
2900              
2901 5         605 DBUG_RETURN ( $status );
2902             }
2903              
2904              
2905             #######################################
2906              
2907             =item $status = $cfg->decrypt_config_file ( [$file[, $decryptFile[, \%rOpts]]] );
2908              
2909             This function decrypts all tag values inside the specified config file that are
2910             marked as ready for decryption and generates a new config file with everything
2911             decrypted. If a tag/value pair isn't marked as ready for decryption it is left
2912             alone. By default this label is B.
2913              
2914             After a tag's value has been decrypted, the label in the comment is updated
2915             from B to B in the config file.
2916              
2917             For this to work, the encryption related options in I<\%rOpts> must match what
2918             was used in the call to I or the decryption will fail.
2919              
2920             Finally if you provide argument I<$decryptFile>, it will write the decrypted
2921             file to that new file instead of overwriting the current file. This file only
2922             gets created if the return status is B<1>.
2923              
2924             If you leave off the I<$file> and I<\%rOpts>, it will instead use the values
2925             inherited from the call to B.
2926              
2927             This method ignores any request to source in other config files. You must
2928             decrypt each file individually.
2929              
2930             It is an error if basename(I<$file>) is a symbolic link and you didn't provide
2931             I<$decryptFile>.
2932              
2933             Returns: B<1> if something was decrypted. B<-1> if nothing was decrypted.
2934             Otherwise B<0> on error.
2935              
2936             =cut
2937              
2938             sub decrypt_config_file
2939             {
2940 8     8 1 14240 DBUG_ENTER_FUNC ( @_ );
2941 8         3875 my $self = shift;
2942 8         35 my $file = shift;
2943 8         16 my $newFile = shift;
2944 8         23 my $rOpts = shift;
2945              
2946 8   33     65 my $pcfg = $self->{PARENT} || $self;
2947              
2948 8         15 my $msg;
2949 8 100       37 if ( $file ) {
    50          
2950 6         30 $file = $self->_fix_path ( $file );
2951             } elsif ( $pcfg->{CONTROL}->{filename} ) {
2952 2         7 $file = $pcfg->{CONTROL}->{filename};
2953             } else {
2954 0         0 $msg = "You must provide a file name to encrypt!";
2955             }
2956              
2957 8 50 33     1711 unless ( $msg || -f $file ) {
2958 0         0 $msg = "No such file to decrypt or it's unreadable! -- $file";
2959             }
2960              
2961 8 50 33     115 if ( -l $file && ! $newFile ) {
2962 0         0 $msg = "You can't decrypt a file via it's symbolic link -- $file";
2963             }
2964              
2965 8         34 my $scratch;
2966 8 100       31 if ( $newFile ) {
2967 6         24 $scratch = $self->_fix_path ( $newFile );
2968 6 50       1357 if ( $scratch eq $file ) {
2969 0         0 $msg = "Args: file & decryptFile must be different!";
2970             }
2971             } else {
2972 2         23 $scratch = $file . ".$$.decrypted";
2973             }
2974              
2975 8 100       33 if ( $rOpts ) {
2976 6         39 $rOpts = get_read_opts ($rOpts, $pcfg->{CONTROL}->{read_opts});
2977             } else {
2978 2         31 $rOpts = $pcfg->{CONTROL}->{read_opts};
2979             }
2980              
2981 8 50       1516 if ( $msg ) {
2982 0         0 return DBUG_RETURN ( croak_helper ( $rOpts, $msg, undef ) );
2983             }
2984              
2985 8         63 my $status = decrypt_config_file_details ($file, $scratch, $rOpts);
2986              
2987             # Some type of error ... or nothing was decrypted ...
2988 8 50 33     2118 if ( $status == 0 || $status == -1 ) {
    100          
2989 0         0 unlink ( $scratch );
2990              
2991             # Replacing the original file ...
2992             } elsif ( ! $newFile ) {
2993 2         418 unlink ( $file );
2994 2         26 move ( $scratch, $file );
2995             }
2996              
2997 8         427 DBUG_RETURN ( $status );
2998             }
2999              
3000              
3001             #######################################
3002              
3003             =item $out_str = $cfg->encrypt_string ( $string, $alias[, \%rOpts] );
3004              
3005             This method takes the passed I<$string> and treats its value as the contents of
3006             a config file, comments and all. Modifying the I<$string> afterwards will not
3007             affect things.
3008              
3009             Since there is no filename to work with, it requires the I<$alias> to assist
3010             with the encryption. And since it's required its passed as a separate argument
3011             instead of being buried in the optional I<%rOpts> hash.
3012              
3013             It takes the I<$string> and encrypts all tag/value pairs per the rules defined
3014             by C. Once the contents of I$ has been encrypted,
3015             the encrypted string is returned as I<$out_str>. It will return B on
3016             failure.
3017              
3018             You can tell if something was encrypted by comparing I<$string> to I<$out_str>.
3019              
3020             =cut
3021              
3022             sub encrypt_string
3023             {
3024 2     2 1 22202 DBUG_MASK_NEXT_FUNC_CALL ( 2 ); # mask the alias.
3025 2         385 DBUG_ENTER_FUNC ( @_ );
3026              
3027 2         1416 my $self = shift;
3028 2         6 my $string = shift; # The string to treat as a config file's contents.
3029 2         7 my $alias = shift; # The alias to use during encryption ...
3030 2         45 my $read_opts = $self->_get_opt_args ( @_ ); # The override options ...
3031              
3032 2 50       13 unless ( $string ) {
3033 0         0 my $msg = "You must provide a string to use this method!";
3034 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
3035             }
3036              
3037 2 50       8 unless ( $alias ) {
3038 0         0 my $msg = "You must provide an alias to use this method!";
3039 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
3040             }
3041              
3042             # The filename is a reference to the string passed to this method!
3043 2         6 my $scratch;
3044 2         5 my $src_file = \$string;
3045 2         5 my $dst_file = \$scratch;
3046              
3047             # Put the alias into the read option hash ...
3048 2         127 local $read_opts->{alias} = basename ($alias);
3049              
3050 2   33     20 my $pcfg = $self->{PARENT} || $self;
3051 2         17 my $rOpts = get_read_opts ($read_opts, $pcfg->{CONTROL}->{read_opts});
3052              
3053 2         1006 my $status = encrypt_config_file_details ($src_file, $dst_file, $rOpts);
3054              
3055 2 50       611 $scratch = undef if ( $status == 0 );
3056              
3057 2         8 DBUG_RETURN ( $scratch );
3058             }
3059              
3060              
3061             #######################################
3062              
3063             =item $out_str = $cfg->decrypt_string ( $string, $alias[, \%rOpts] );
3064              
3065             This method takes the passed I<$string> and treats its value as the contents of
3066             an encrypted config file, comments and all. Modifying the I<$string> afterwards
3067             will not affect things.
3068              
3069             Since there is no filename to work with, it requires the I<$alias> to assist
3070             with the decryption. And since it's required its passed as a separate argument
3071             instead of being buried in the optional I<%rOpts> hash.
3072              
3073             It takes the I<$string> and decrypts all tag/value pairs per the rules defined
3074             by C. Once the contents of I$ has been decrypted,
3075             the decrypted string is returned as I<$out_str>. It will return B on
3076             failure.
3077              
3078             You can tell if something was decrypted by comparing I<$string> to I<$out_str>.
3079              
3080             =cut
3081              
3082             sub decrypt_string
3083             {
3084 1     1 1 317 DBUG_MASK_NEXT_FUNC_CALL ( 2 ); # mask the alias.
3085 1         50 DBUG_ENTER_FUNC ( @_ );
3086              
3087 1         694 my $self = shift;
3088 1         4 my $string = shift; # The string to treat as a config file's contents.
3089 1         3 my $alias = shift; # The alias to use during encryption ...
3090 1         9 my $read_opts = $self->_get_opt_args ( @_ ); # The override options ...
3091              
3092 1 50       7 unless ( $string ) {
3093 0         0 my $msg = "You must provide a string to use this method!";
3094 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
3095             }
3096              
3097 1 50       6 unless ( $alias ) {
3098 0         0 my $msg = "You must provide an alias to use this method!";
3099 0         0 return DBUG_RETURN ( croak_helper ($read_opts, $msg, undef) );
3100             }
3101              
3102             # The filename is a reference to the string passed to this method!
3103 1         3 my $scratch;
3104 1         3 my $src_file = \$string;
3105 1         3 my $dst_file = \$scratch;
3106              
3107             # Put the alias into the read option hash ...
3108 1         52 local $read_opts->{alias} = basename ($alias);
3109              
3110 1   33     12 my $pcfg = $self->{PARENT} || $self;
3111 1         9 my $rOpts = get_read_opts ($read_opts, $pcfg->{CONTROL}->{read_opts});
3112              
3113 1         336 my $status = decrypt_config_file_details ($src_file, $dst_file, $rOpts);
3114              
3115 1 50       288 $scratch = undef if ( $status == 0 );
3116              
3117 1         5 DBUG_RETURN ( $scratch );
3118             }
3119              
3120              
3121             #######################################
3122              
3123             =back
3124              
3125             =head2 Handling Variables in your config file.
3126              
3127             These methods are used to resolve variables defined in your config file when
3128             it gets loaded into memory by this module. It is not intended for general use
3129             except as an explanation on how variables work.
3130              
3131             =over
3132              
3133             =item ($value, $status) = $cfg->lookup_one_variable ( $variable_name );
3134              
3135             This method takes the given I<$variable_name> and returns its value.
3136              
3137             It returns I if the given variable doesn't exist. And the optional 2nd
3138             return value tells us about the B of the 1st return value.
3139              
3140             If the B is B<-1>, the returned value is still encrypted. If set to
3141             B<1>, the value is considered sensitive. In all other cases this B flag
3142             is set to B<0>.
3143              
3144             This method is frequently called internally if you define any variables inside
3145             your config files when they are loaded into memory.
3146              
3147             Variables in the config file are surrounded by anchors such as B<${>nameB<}>.
3148             But it's passed as B without any anchors when this method is called.
3149              
3150             The precedence for looking up a variable's value to return is as follows:
3151              
3152             0. Is it the special "shft3" variable or one of its variants?
3153             1. Look for a tag of that same name previously defined in the current section.
3154             2. If not defined there, look for the tag in the "main" section.
3155             3. Special Case, see note below about periods in the variable name.
3156             4. If not defined there, look for a value in the %ENV hash.
3157             5. If not defined there, does it represent a special Perl variable?
3158             6. If not defined there, is it a predefined Advanced::Config variable?
3159             7. If not defined there, is it some predefined special date variable?
3160             8. If not defined there, the result is undef.
3161              
3162             If a variable was defined in the config file, it uses the tag's value when the
3163             line gets parsed. But when you call this method in your code after the config
3164             file has been loaded into memory, it uses the final value for that tag.
3165              
3166             The special B<${>shft3B<}> variable is a way to insert comment chars into a
3167             tag's value in the config file when you can't surround it with quotes. This
3168             variable is always case insensitive and if you repeat the B<3> in the name, you
3169             repeat the comment chars in the substitution.
3170              
3171             * a = ${shft3} - Returns "#" for a.
3172             * b = ${SHFT33} - Returns "##" for b.
3173             * c = ${ShFt333} - Returns "###" for c.
3174             * etc ...
3175              
3176             And since this variable has special meaning, if you try to define one of the
3177             B variants as a tag in your config file, or call C with it,
3178             it will be ignored and a warning will be printed to your screen!
3179              
3180             If the variable had a period (B<.>) in it's name, and it doesn't match anything
3181             (rules 0 to 2), it follows rule B<3> and it treats it as a reference to a tag in
3182             another section. So see F for details on how this works.
3183              
3184             This module provides you special predefined variables (rules 5, 6 & 7) to help
3185             make your config files more dynamic without the need of a ton of code on your
3186             end. If you want to override the special meaning for these variables, all you
3187             have to do is define a tag in the config file of the same name to override it.
3188             Or just don't use these variables in the 1st place.
3189              
3190             For rule B<5>, the special Perl variables you are allowed to reference are:
3191             B<$$>, B<$0>, and B<$^O>. (Each must appear in the config file as: B<${$}>,
3192             B<${0}> or B<${^O}>.)
3193              
3194             For rule B<6>, the predefined module variables are: ${PID}, ${PPID}, ${user},
3195             ${hostname}, ${program}, ${flavor} and ${sep} (The ${flavor} is defined by
3196             F and ${sep} is the path separator defined by F
3197             for your OS.) The final variable ${section} tells which section this variable
3198             was used in.
3199              
3200             Finally for rule B<7> it provides some special date variables. See
3201             B> for a complete list of
3202             what date related variables are defined. The most useful being ${today} and
3203             ${yesterday} so that you can dynamically name your log files
3204             F and you won't need any special date roll logic
3205             to start a new log file.
3206              
3207             =cut
3208              
3209             sub lookup_one_variable
3210             {
3211 8047     8047 1 29628 DBUG_ENTER_FUNC ( @_ );
3212 8047         4274243 my $self = shift; # Reference to the current section.
3213 8047         17806 my $var = shift; # The name of the variable, minus the ${...}.
3214              
3215 8047   66     41403 my $pcfg = $self->{PARENT} || $self; # Get the main section ...
3216              
3217             # Silently disable calling "die" or "warn" on all get/set calls ...
3218 8047         36014 local $pcfg->{CONTROL}->{get_opts}->{required} = -9876;
3219              
3220 8047         19739 my $opts = $pcfg->{CONTROL}->{read_opts};
3221              
3222             # Did we earlier request case insensitive tag lookups?
3223 8047 100       26415 $var = lc ($var) if ( $opts->{tag_case} );
3224              
3225             # The default return values ...
3226 8047         25855 my ( $val, $mask_flag, $file, $encrypt_flag ) = ( undef, 0, "", 0 );
3227              
3228 8047 100       27214 if ( $var =~ m/^shft(3+)$/i ) {
3229             # 0. The special comment variable ... (Can't override)
3230 291         1048 $val = $1;
3231 291         733 my $c = $opts->{comment}; # Usually a "#".
3232 291         1713 $val =~ s/3/${c}/g;
3233              
3234             } else {
3235             # 1. Look in the current section ...
3236 7756         29919 ( $val, $mask_flag, $file, $encrypt_flag ) = $self->_base_get2 ( $var );
3237              
3238             # 2. Look in the parent section ... (if not already there)
3239 7756 100 100     48556 if ( ! defined $val && $self != $pcfg ) {
3240 4568         15511 ( $val, $mask_flag, $file, $encrypt_flag ) = $pcfg->_base_get2 ( $var );
3241             }
3242              
3243             # 3. Look in the requested section(s) ...
3244 7756 100 100     44143 if ( ! defined $val && $var =~ m/[.]/ ) {
3245 1655         7265 ($val, $mask_flag, $encrypt_flag) = $self->rule_3_section_lookup ( $var );
3246             }
3247              
3248             # 4. Look in the %ENV hash ...
3249 7756 100 100     380538 if ( ! defined $val && defined $ENV{$var} ) {
3250 1         5 $val = $ENV{$var};
3251 1         7 $mask_flag = should_we_hide_sensitive_data ($var);
3252              
3253             # Record so refresh logic will work when %ENV vars change.
3254 1         284 $pcfg->{CONTROL}->{ENV}->{$var} = $val;
3255             }
3256              
3257             # 5. Look at the special Perl variables ... (now done as part of 6.)
3258             # 6. Is it one of the predefined module variables ...
3259             # Variables should either be all upper case or all lower case!
3260             # But allowing for mixed case.
3261 7756 100       24606 if ( ! defined $val ) {
3262 2769 100       15135 if ( exists $begin_special_vars{$var} ) {
    50          
    50          
    100          
3263 1663         4715 $val = $begin_special_vars{$var};
3264             } elsif ( exists $begin_special_vars{lc ($var)} ) {
3265 0         0 $val = $begin_special_vars{lc ($var)};
3266             } elsif ( exists $begin_special_vars{uc ($var)} ) {
3267 0         0 $val = $begin_special_vars{uc ($var)};
3268             } elsif ( $var eq "section" ) {
3269 8         37 $val = $self->section_name ();
3270             }
3271             }
3272              
3273             # 7. Is it one of the special date variables ...
3274             # All these date vars only use lower case!
3275 7756 100       22250 if ( ! defined $val ) {
3276 1098         3065 my $lc_var = lc ($var);
3277 1098 100       6607 if ( defined $pcfg->{CONTROL}->{DATES}->{$lc_var} ) {
3278 420         1350 $val = $pcfg->{CONTROL}->{DATES}->{$lc_var};
3279              
3280             # Record so refresh logic will work when the date changes.
3281             # Values:
3282             # 0 - unknown date variable. (so refresh will ignore it.)
3283             # 1 - MM/DD/YYYY referenced. (refresh on date change.)
3284             # 2 - MM or MM/YYYY referenced. (refresh if the month changes.)
3285             # 3 - YYYY referenced. (refresh if the year changes.)
3286 420         843 my $rule = 0;
3287 420 100       3122 if ( $lc_var =~ m/^((yesterday)|(today)|(tomorrow)|(dow)|(doy)||(dom))$/ ) {
    100          
    100          
    100          
3288 330         717 $rule = 1;
3289              
3290             } elsif ( $lc_var =~ m/^((last)|(this)|(next))_month$/ ) {
3291 27         52 $rule = 2;
3292              
3293             } elsif ( $lc_var =~ m/^((last)|(this)|(next))_period$/ ) {
3294 27         101 $rule = 2;
3295              
3296             } elsif ( $lc_var =~ m/^((last)|(this)|(next))_year$/ ) {
3297 27         56 $rule = 3;
3298             }
3299             # Don't record if {timestamp} used. (rule == 0)
3300              
3301             # Save the smallest rule referenced ...
3302 420 100       1376 if ( $rule != 0 ) {
3303 411 100       2296 if ( $pcfg->{CONTROL}->{DATE_USED} == 0 ) {
    50          
3304 42         161 $pcfg->{CONTROL}->{DATE_USED} = $rule;
3305             } elsif ( $pcfg->{CONTROL}->{DATE_USED} > $rule ) {
3306 0         0 $pcfg->{CONTROL}->{DATE_USED} = $rule;
3307             }
3308             }
3309             }
3310             }
3311              
3312             # 8. Then it must be undefined ... (IE: an unknown variable)
3313             }
3314              
3315             # Mask the return value in fish ???
3316 8047 100       22101 DBUG_MASK ( 0 ) if ( $mask_flag);
3317              
3318             # Is the return value still encryped ???
3319 8047 100       33584 $mask_flag = -1 if ( $encrypt_flag );
3320              
3321 8047         25329 DBUG_RETURN ( $val, $mask_flag )
3322             }
3323              
3324             # ==============================================================
3325              
3326             =item ($value, $sens, $encrypt) = $cfg->rule_3_section_lookup ( $variable_name );
3327              
3328             When a variable has a period (B<.>) in its name, it could mean that this
3329             variable is referencing a tag from another section of the config file. So this
3330             helper method to F exists to perform this complex check.
3331              
3332             For example, a variable called B<${>xxx.extraB<}> would look in Section "xxx"
3333             for tag "extra".
3334              
3335             Here's another example with multiple B<.>'s in its name this time. It would
3336             look up variable B<${>one.two.threeB<}> in Section "one.two" for tag "three".
3337             And if it didn't find it, it would next try Section "one" for tag "two.three".
3338              
3339             If it found such a variable, it returns it's value. If it didn't find anything
3340             it returns B. The optional 2nd and 3rd values tells you more about the
3341             returned value.
3342              
3343             I<$sens> is a flag that tells if the data value should be considered sensitive
3344             or not.
3345              
3346             I<$encrypt> is a flag that tells if the value still needs to be decrypted or
3347             not.
3348              
3349             =cut
3350              
3351             sub rule_3_section_lookup
3352             {
3353 1685     1685 1 13688 DBUG_ENTER_FUNC ( @_ );
3354 1685         702084 my $self = shift;
3355 1685         3867 my $var_name = shift; # EX: abc.efg.xyz ...
3356              
3357 1685         5432 my ( $val, $fish_mask, $f, $encrypted ) = ( undef, 0, "", 0 );
3358              
3359             # If the variable name isn't named correctly ...
3360 1685 50       9421 if ( $var_name !~ m/\./ ) {
3361 0         0 return DBUG_RETURN ($val, $fish_mask, $encrypted);
3362             }
3363              
3364             # Silently disable calling "die" or "warn" on all get/set calls ...
3365 1685   66     6763 my $pcfg = $self->{PARENT} || $self; # Get the main section ...
3366 1685         6671 local $pcfg->{CONTROL}->{get_opts}->{required} = -9876;
3367              
3368             # So trailing ... in varname won't cause issues ...
3369 1685         17306 my @parts = split (/\s*[.]\s*/, $var_name . ".!");
3370 1685         3509 pop (@parts); # Remove that pesky trailing "!" I just added!
3371              
3372             # Now look for the requested tag in the proper section ...
3373 1685         7555 for ( my $i = $#parts - 1; $i >= 0; --$i ) {
3374 1693         8386 my $section = join (".", (@parts)[0..$i]);
3375 1693         6554 my $sect = $self->get_section ( $section );
3376 1693 100       362268 next unless ( defined $sect );
3377              
3378 1678         8353 my $tag = join (".", (@parts)[$i+1..$#parts]);
3379 1678         6445 ( $val, $fish_mask, $f, $encrypted ) = $sect->_base_get2 ( $tag );
3380              
3381             # Stop looking if we found anything ...
3382 1678 50       6696 if ( defined $val ) {
3383 1678         6504 DBUG_PRINT ("RULE-3", "Found Section/Tag: %s/%s", $section, $tag);
3384 1678         322320 last;
3385             }
3386             }
3387              
3388             # Controls if the return value needs to be masked in fish ...
3389 1685 100       7154 DBUG_MASK ( 0 ) if ( $fish_mask );
3390              
3391 1685         6102 DBUG_RETURN ( $val, $fish_mask, $encrypted );
3392             }
3393              
3394             # ======================================================================
3395              
3396             =item $cfg->print_special_vars ( [\%date_opts] );
3397              
3398             This function is for those individuals who don't like to read the POD too
3399             closely, but still need a quick and dirty way to list all the special config
3400             file variables supported by this module.
3401              
3402             It prints to STDERR the list of these special variables and their current
3403             values. These values can change based on the options used in the call to new()
3404             or what OS you are running under. Or even what today's date is.
3405              
3406             Please remember it is possible to override most of these variables if you first
3407             define them in your own config file or with an environment variable of the
3408             same name. But this function doesn't honor any overrides. It just provides
3409             this list on an FYI basis.
3410              
3411             The optional I hash allows you to play with the various date formats
3412             available for the special date vars. See B
3413             Options> section of the Options module for what these options are. Used to
3414             override what was set in the call to new().
3415              
3416             =cut
3417              
3418             sub print_special_vars
3419             {
3420 0     0 1   DBUG_ENTER_FUNC ( @_ );
3421 0           my $self = $_[0]; # Will shift later if it's an object as expected!
3422              
3423             # Detect if called as part of the object or not.
3424 0   0       my $is_obj = ( defined $self && ref($self) eq __PACKAGE__ );
3425 0 0 0       if ( $is_obj ) {
    0          
3426 0           shift; # $cfg->print_special_vars();
3427             } elsif ( defined $self && $self eq __PACKAGE__ ) {
3428 0           shift; # Advanced::Config->print_special_vars();
3429             } else {
3430             # No shift, called via: Advanced::Config::print_special_vars();
3431             }
3432              
3433 0           my $date_opts = $_[0]; # The optional argument ...
3434              
3435             # If it wasn't a hash reference, assume passed by value ...
3436 0 0 0       if ( defined $date_opts && ref ($date_opts) eq "" ) {
3437 0           my %data = @_;
3438 0           $date_opts = \%data;
3439             }
3440              
3441             # -------------------------------------------------------------
3442             # Start of real work ...
3443             # -------------------------------------------------------------
3444              
3445 0           my ($pcfg, $cmt, $la, $ra, $asgn) = (undef, '#', '${', '}', '=');
3446 0 0         if ( $is_obj ) {
3447             # Get the main/parent section to work against!
3448 0   0       $pcfg = $self->{PARENT} || $self;
3449              
3450             # Look in the Read Options hash for current settings ...
3451 0           $cmt = $pcfg->{CONTROL}->{read_opts}->{comment};
3452 0           $la = $pcfg->{CONTROL}->{read_opts}->{variable_left};
3453 0           $ra = $pcfg->{CONTROL}->{read_opts}->{variable_right};
3454 0           $asgn = $pcfg->{CONTROL}->{read_opts}->{assign};
3455             }
3456              
3457 0           print STDERR "\n";
3458 0           print STDERR "${cmt} Examples of the Special Predefined Comment Variable ... (controlled via new)\n";
3459 0           print STDERR "${cmt} You can't override these variables.\n";
3460              
3461 0 0         unless ( $is_obj ) {
3462 0           print STDERR " \${shft3} = #\n";
3463 0           print STDERR " \${shft33} = ##\n";
3464 0           print STDERR " \${shft333} = ###\n";
3465             } else {
3466             # Works since Rule # 0 and can't be overridden.
3467 0           foreach ( "shft3", "shft33", "shft333" ) {
3468 0           my $v = $self->lookup_one_variable ($_);
3469 0           print STDERR " ${la}$_${ra} ${asgn} ${v}\n";
3470             }
3471             }
3472 0           print STDERR " ...\n\n";
3473              
3474 0           print STDERR "${cmt} Any of the variables below can be overridden by putting them\n";
3475 0           print STDERR "${cmt} into %ENV or predefining them inside your config files!\n\n";
3476              
3477 0           print STDERR "${cmt} The Special Predefined Variables ... (OS/Environment dependant)\n";
3478 0           foreach my $k ( sort keys %begin_special_vars ) {
3479 0           print STDERR " ${la}$k${ra} ${asgn} $begin_special_vars{$k}\n";
3480             }
3481              
3482 0           print STDERR "\n";
3483 0           print STDERR "${cmt} The value of this variable changes based on which section of the config file\n";
3484 0           print STDERR "${cmt} it's used in! It's value will always match the name of the current section!\n";
3485 0 0         my $section = $is_obj ? $self->section_name () : DEFAULT_SECTION;
3486 0           print STDERR " ${la}section${ra} ${asgn} $section\n";
3487              
3488 0           print STDERR "\n";
3489              
3490 0           my ($opts, %dt);
3491 0 0         unless ( $is_obj ) {
3492 0           $opts = get_date_opts ( $date_opts );
3493             } else {
3494 0           $opts = get_date_opts ( $date_opts, $pcfg->{CONTROL}->{date_opts} );
3495             }
3496 0           my $language = $opts->{month_language};
3497 0 0         my $type = ( $opts->{use_gmt} ) ? "gmtime" : "localtime";
3498              
3499 0           print STDERR "${cmt} The Special Predefined Date Variables ... (in ${language})\n";
3500 0           print STDERR "${cmt} The format and language used can vary based on the date options selected.\n";
3501 0           print STDERR "${cmt} Uses ${type} to convert the current timestamp into the other values.\n";
3502              
3503 0           set_special_date_vars ( $opts, \%dt );
3504 0           foreach my $k ( sort keys %dt ) {
3505 0           print STDERR " ${la}$k${ra} ${asgn} $dt{$k}\n";
3506             }
3507              
3508 0           print STDERR "\n";
3509              
3510 0           DBUG_VOID_RETURN ();
3511             }
3512              
3513             # ======================================================================
3514              
3515             =back
3516              
3517             =head1 ENVIRONMENT
3518              
3519             Expects PERL5LIB to point to the root of the custom Module directory if not
3520             installed in Perl's default location.
3521              
3522             =head1 COPYRIGHT
3523              
3524             Copyright (c) 2007 - 2026 Curtis Leach. All rights reserved.
3525              
3526             This program is free software. You can redistribute it and/or modify it under
3527             the same terms as Perl itself.
3528              
3529             =head1 SEE ALSO
3530              
3531             L - Handles the configuration of the config object.
3532              
3533             L - Handles date parsing for get_date().
3534              
3535             L - Handles the parsing of the config file.
3536              
3537             L - Provides some sample config files and commentary.
3538              
3539             =cut
3540              
3541             ###################################################
3542             #required if module is included w/ require command;
3543             1;