File Coverage

blib/lib/Advanced/Config/Options.pm
Criterion Covered Total %
statement 396 431 91.8
branch 150 202 74.2
condition 65 94 69.1
subroutine 28 28 100.0
pod 14 14 100.0
total 653 769 84.9


line stmt bran cond sub pod time code
1             ###
2             ### Copyright (c) 2007 - 2026 Curtis Leach. All rights reserved.
3             ###
4             ### Module: Advanced::Config::Options
5              
6             =head1 NAME
7              
8             Advanced::Config::Options - Options manager for L.
9              
10             =head1 SYNOPSIS
11              
12             use Advanced::Config::Options;
13             or
14             require Advanced::Config::Options;
15              
16             =head1 DESCRIPTION
17              
18             F is a helper module to L. So it
19             should be very rare to directly call any methods defined by this module.
20              
21             It's main job is to help manage the settings of the B, B and B
22             options hashes. It was implemented as a separate module to make it simpler to
23             document the various supported options without cluttering up the POD of the main
24             module. So you are not expected to ever call any of these methods yourself.
25             It's here mainly as an FYI.
26              
27             If you don't specify the options below, this module will assume you wish to use
28             the default behavior for that option. So only override what you need to.
29             Also all options are in lower case. But you may provide them in mixed case if
30             you wish. This module will auto downshift them for you.
31              
32             If an option is misspelled, or you don't provide a valid value, a warning will
33             be written to the screen and that option will be ignored.
34              
35             =head1 ==================================================================
36              
37             =head2 Z<>
38              
39             =head1 The Read Options
40              
41             In most cases the defaults should do nicely for you. But when you share config
42             files between applications, you may not have any control over the config file's
43             format. This may also apply if your organization requires a specific format
44             for its config files.
45              
46             So this section deals with the options you can use to override how it parses and
47             interprets the config file when it is loaded into memory. None of these options
48             below allows leading or trailing spaces in the option's value. And if any are
49             found, they will be automatically trimmed off before their value is used.
50             Internal spaces are OK when non-numeric values are expected. In most cases
51             values with a length of B<0> or B are not allowed.
52              
53             Just be aware that some combinations of I options may result in this
54             module being unable to parse the config file. If you encounter such a
55             combination open a CPAN ticket and I'll see what I can do about it. But some
56             combinations may just be too ambiguous to handle.
57              
58             Also note that some I options have B and B variants. These
59             options are used in pairs and both must anchor the target in order for the rule
60             to be applied to it. These start/end anchors can be set to the same string or
61             different strings. Your choice.
62              
63             =head2 Tag(s) Best Set in Call to the Constructor new().
64              
65             While not required to set these options during the call to B, changing
66             their settings later on can cause unexpected issues if you are not careful.
67              
68             But it's still recommended that most I Options be set during the call to
69             B to avoid having to keep on resetting them all the time and limit these
70             later changes to handle exceptions to your defaults.
71              
72             =over 4
73              
74             B - Config files are made up of tag/value pairs. This option controls
75             whether the tags are case sensitive (B<0>, the default) or case insensitive
76             (B<1>). IE do tags B and B represent the same tag or not? So if set,
77             all tags are assumed to be in lower case for the get/set methods!
78              
79             =back
80              
81             =head2 Generic Read Options
82              
83             These options are also usually set during the call to B, but setting them
84             later on doesn't produce strange behavior if you change the settings later on.
85              
86             =over 4
87              
88             B - This controls what happens when a function hits an unexpected error
89             while parsing the config file. Set to B<0> to return an error code (default),
90             B<-1> to return an error code and print a warning to your screen, B<1> to call
91             die and terminate your program.
92              
93             B - Tells if we should export all tag/value pairs to perl's %ENV hash
94             or not. The default is B<0> for I. Set to B<1> if you want this to happen.
95             But if set, it reverses the meaning of the B option defined later
96             on.
97              
98             B - Defaults to B<0>. Set to B<1> if the config file was created
99             using utf8 encoding. (IE Unicode or Wide Characters.) Guessing this
100             setting wrong means the file will be unusable as a config file.
101              
102             B - Defaults to B<0>. Set to B<1> if you want to disallow
103             the stripping of balanced quotes in your config files.
104              
105             B - Defaults to B<0>. Set to B<1> if you want to disable
106             variable expansion in your config files when they are loaded into memory.
107              
108             B - Defaults to B<0>. Set to B<1> if you want to
109             disable this feature. See L for more
110             details. This feature allows you to put logic into your config files via
111             your variable definitions. Automatically disabled when variables are
112             disabled. Useful when you put a lot of special chars into your variable
113             names.
114              
115             B - Defaults to B<0>. Set to B<1> if you want to disable
116             decrypting values that have been marked as encrypted. If a variable references
117             an encrypted value while disable_decription is active, that variable isn't
118             expanded.
119              
120             =cut
121              
122             # B - Defaults to B<0>. Set to B<1> if you want to enable
123             # this feature. It's disabled by default since it can be considered a security
124             # hole if an unauthorized user can modify your config file or your code.
125              
126             =pod
127              
128             B - Defaults to B<0>. Set to B<1> if you want to treat
129             recursion as a fatal error when loading a config file. By default it just
130             ignores the recursion request to prevent infinite loops.
131              
132             B - A work area for holding values between calls to the
133             callback function. This is expected to be a hash reference to provide any
134             needed configuration values needed to parse the next config file. This way
135             you can avoid global variables. Defaults to an empty hash reference.
136              
137             B - An optional callback routine called each time your config file
138             sources in another config file. It's main use is when the I
139             and/or I required to parse each config file change between
140             files. It's automatically called right before the sourced in file is opened up
141             for parsing.
142              
143             Once the new file is sourced in, it inherits most of the options currently used
144             unless you override them. The only ones not inherited deal with decryption.
145              
146             Here is the callback function's expected definition:
147              
148             my ($rOpts, $dOpts) = source_callback_func ($file[, $cbOpts]);
149              
150             $file --> The file being sourced in.
151              
152             $cbOpts --> A hash reference containing values needed by your callback
153             function to decide what options are required to source in the
154             requested file. You may update the contents of this hash to
155             preserve info between calls. This module will "never" examine
156             the contents of this hash!
157              
158             $rOpts --> A reference to the "Read Options" hash used to parse the file
159             you want to source in. Returns "undef" if the options don't
160             change. The returned options override what's currently in use by
161             "load_config" when loading the current file.
162              
163             $dOpts --> A reference to the "Date Formatting Options" hash used to tell how
164             to format the special date variables. Returns "undef" if the
165             options don't change. The returned options override what's
166             currently in use by "load_config" when loading the current file.
167              
168             =back
169              
170             =head2 Parse Read Options
171              
172             These options deal with how to parse the config file itself. All values are
173             literal values. No regular expressions are supported. If you don't want to
174             allow a particular option to be supported in your config file, and there is
175             no disable option, feel free to set it to some unlikely long string of
176             characters that will never match anything in your config files. Such as
177             "#"x100. (A string of 100 #'s.)
178              
179             =over 4
180              
181             B - Defaults to B<=>. You may use this option to override what string
182             of characters make up the assignment operator. It's used to split a line
183             into a tag/value pair. If you want the special case of no separator, IE the
184             first space separates a tag/value pair, try setting it to B<\\s> since the
185             interface doesn't allow whitespace as a value.
186              
187             B - Defaults to B<#>. This is the comment symbol used when parsing
188             your config file and everything after it is ignored in most cases. The first
189             case is when it appears between balanced quotes as part of a tag's value, it's
190             not considered the start of a comment. The other case is when you put one
191             of the labels in the comments to override default behavior. (See next section)
192              
193             B - Defaults to "B<.>". When followed by a file name, this is an
194             instruction to source in another config file (similar to how it works in a
195             I shell script.) Another common setting for this option is "include".
196              
197             B & B - This pair is used to anchor breaking
198             your config file into multiple independent sections. The defaults are B<[>
199             and B<]>.
200              
201             B & B - This pair is used to anchor a variable
202             definition. Any value between these anchors will be a variable name and it's
203             value will be used instead, unless you've disabled this expansion. The defaults
204             are B<${> and B<}>. If you override these anchors to both have the same value,
205             then the optional variable modifiers are not supported nor are nested variables.
206              
207             B & B - This pair is used to define what balanced
208             quotes look like in your config file. By default, it allows you to use either
209             B<"> or B<'> as a matching pair. But if you override one of them you must
210             override both. And in that case it can only be with literal values. If the
211             quotes surrounding a tag's value are balanced, the quotes will be automatically
212             removed from the value. If they are unbalanced the quotes will not be removed.
213              
214             =cut
215              
216             # B & B - This pair is used to surround a command
217             # you wish to run, just like in Perl itself. What the command writes to STDOUT
218             # becomes the tag's value. Assumes the command takes nothing from STDIN. Due to
219             # security concerns you must explicitly set these values yourself before they are
220             # usable. A good value is the backqoute itself (B<`>). But use something else
221             # if you don't want to be so obvious about it.
222              
223             =pod
224              
225             =back
226              
227             =head2 Modifiers in the trailing Comments for tag/value pairs.
228              
229             In some cases we need to handle exceptions to the rule. So we define labels
230             to tell this module that we need to apply special rules to this tag/value pair.
231             These labels may appear anywhere in the comment. So when looking for "EXPORT",
232             it will match "B<# Please EXPORT me.>", but won't match "B<# EXPORTED>". This
233             allows you to put multiple labels in a single comment if needed.
234              
235             As long as the text is surrounded by white space or punctuation a match will
236             be found. It is strongly recommended that you don't use punctuation in your
237             label when you override one with values of your own.
238              
239             Here are the labels you may override.
240              
241             =over 4
242              
243             B - Defaults to "B". Tells this module to export this
244             particular tag/value pair to perl's B<%ENV> hash. If the I option
245             was also set, it inverts the meaning of this label to mean don't export it!
246             You can also gain the same functionality by doing one of the following
247             instead:
248              
249             export tag = value # Optional unix type shell script prefix.
250              
251             set tag = value # Optional windows type batch file prefix.
252              
253             These prefixes allow you to easily use shell/batch files as config files if
254             they contain no logic.
255              
256             B - Defaults to "B". Tells this module that this tag's value
257             contains sensitive information. So when fish logging is turned on, this module
258             will never write it to these logs. If the parser thinks a tag's name suggests
259             it's a password, it will assume that you put this label in the comment. This
260             is what triggers the sensitive/mask arguments and return values that some
261             methods use.
262              
263             B - Defaults to "B". Tells this module that you are
264             waiting for this tag's value to be encrypted in the config file. It assumes
265             the value is still in clear text. When present it assumes the value is
266             sensitive as well.
267              
268             B - Defaults to "B". Tells this module that this value
269             has already been encrypted and needs to be decrypted before it is used. When
270             present it assumes that the value is sensitive as well.
271              
272             B - Defaults to "B". Tells this module to
273             use the current section as the default/unlabeled section in the file being
274             source in. This new value will be inherited should the sourced in file source
275             in any further files.
276              
277             =back
278              
279             =head2 Encryption/Decryption options. (or Encode/Decode options.)
280              
281             The following options deal with the encryption/decryption of the contents of a
282             config file. Only the encryption of a tag's value is supported. And this is
283             triggered by the appropriate label in the comment on the same line after the
284             value.
285              
286             Unless you use the B option, this module isn't using true
287             encryption. It's more a complex obscuring of the tag's value making it very
288             difficult to retrieve a tag's value without using this module to examine the
289             config file's contents. It's main use is to prevent casual browsers of your
290             file system from being able to examine your config files using their favorite
291             editor to capture sensitive data from your config files.
292              
293             By default, the I of the config file's name and the tag's name are the
294             keys used to encode each value in the config file. This means that each tag's
295             value in the config file uses a different key to obscure it. But by using just
296             the defaults, anyone using this module may automatically decode everything in
297             the config file just by writing a perl program that uses this module.
298              
299             But by using the options below, you gain additional security even without using
300             true encryption. Since if you don't know the options used, you can't easily
301             decode each tag's value even by examining the code. Just be aware that using
302             too many keys with too similar values could cancel each other out and weaken
303             the results.
304              
305             These options are ignored if you've disabled decryption.
306              
307             When you source in another file in your config files, the current values
308             for B, B and B are not inherited. But the
309             remaining options are. See option B if you need to set them in this
310             case.
311              
312             =over 4
313              
314             B - Defaults to the empty string. (Meaning no alias provided.) This
315             option is used to override using the file's I as one of the
316             encryption/decryption keys with the I of the value you provide here.
317              
318             If you encrypt a file with no I, and then rename the config file, you
319             must set the I to the original filename to be able to decrypt anything.
320             If you encrypt a file with an I, you must use the same I to
321             decrypt things again.
322              
323             If your config file is a symbolic link to another name, it will auto set this
324             option for you using the file's real name as the alias if you don't override
325             it by setting the alias yourself.
326              
327             B - Defaults to the empty string. If you used a pass phrase to
328             encrypt the value, then you need to use the same pass phrase again when
329             decrypting each tag's value.
330              
331             B - Defaults to 0 (no). Set to 1 if you want to use the
332             same B when you source in a sub-file in your config files.
333              
334             B - Defaults to 0 (no). Set to 1 if you want use the user
335             name you are running the program under as part of the encryption key. So only
336             the user who encrypted the file can decrypt it.
337              
338             B - A work area for holding values between calls to the
339             callback function. This is expected to be a hash reference to provide any
340             values needed by your encryption efforts. So you can avoid global variables
341             and having to figure out the correct context of the call. Defaults to an empty
342             hash reference.
343              
344             B - An optional callback function to provide hooks for B
345             encryption> or an additional layer of masking. It defaults to no callback
346             function used. This callback function is called in addition to any obscuring
347             work done by this module.
348              
349             Here is the callback function's expected definition:
350              
351             my $new_value = encrypt_callback_func ($mode, $tag, $value, $file[, $cbOpts]);
352              
353             $mode ==> 1 - Encrypt this value, 0 - Decrypt this value.
354              
355             $tag ==> The name of the tag whose value is being encrypted/decrypted.
356              
357             $value ==> The value to encrypt/decrypt.
358              
359             $file ==> The basename of the file the tag/value pair came from. If the
360             "alias" option was used, the basename of that "alias" is
361             passed as "$file" instead.
362              
363             $cbOpts ==> A hash reference containing values needed by your function to
364             do it's custom encrypt/decrypt duties. You may update the
365             contents of this hash to preserve info between calls. This
366             module will "never" examine the contents of this hash!
367              
368             =back
369              
370             =head1 ==================================================================
371              
372             =head2 Z<>
373              
374             =head1 The Get Options
375              
376             This section deals with the options you can use to override how the I>
377             methods behave when you try to access the values for individual tags. None
378             of the options below allows leading or trailing spaces in it's value. If any
379             are found, they will be automatically trimmed off before their value is used.
380             Internal spaces are OK.
381              
382             These options can be set as global defaults via the call to the constructor,
383             B, or for individual B calls if you don't like the defaults
384             for individual calls.
385              
386             But it is strongly recommended that the B option only be set in the
387             constructor and not changed elsewhere. Changing its value between calls can
388             cause strange behavior if you do so. Since it globally affects how this
389             module locates the requested tag and affects variable lookups when the
390             config file is parsed.
391              
392             After that, where to set the other options is more a personal choice than
393             anything else.
394              
395             =over 4
396              
397             B - Defaults to B<0> where each section is independent, the tag either
398             exists or it doesn't in the section. Set to B<1> if each section should be
399             considered an override for what's in the main section. IE if tag "abc" doesn't
400             exist in the current section, it next looks in the main section for it.
401              
402             B - This controls what happens when the requested tag doesn't exist
403             in your I object. Set to B<0> to return B (default),
404             B<-1> to return B and write a warning to your screen, B<1> to call
405             die and terminate your program.
406              
407             B - Controls what case to force all values to. Defaults to B<0> which
408             says to preserve the case as entered in the config file. Use B<1> to convert
409             everything to upper case. Use B<-1> to convert everything to lower case.
410              
411             B - Defaults to B. The pattern to use when splitting
412             a tag's value into an array via perl's C function. It can be a string
413             or a regular expression. For example to split on a comma separated string
414             you could do: B.
415              
416             B - Defaults to I. Tells what language I
417             should use when converting the date into a standard format. Can be almost any
418             language supported by I.
419              
420             B - Defaults to B<0> (no). Should I
421             methods print out warnings?
422              
423             B - Defaults to B<0> (no). When parsing dates, should we
424             enable recognizing two digit years as valid?
425              
426             B - Numeric dates are inherently ambiguous so hints are required
427             in order to eliminate ambiguities. For example is 01/02/03 I (USA)
428             or I (European) or even I (ISO). To a lesser extent
429             this is also true when you use 4-digit years. So this option was added for
430             you to provide parsing hints on the order to try out.
431              
432             0 - ISO only
433             1 - USA only
434             2 - European only
435             3 - ISO, USA, European (default)
436             4 - ISO, European, USA
437             5 - USA, European, ISO
438             6 - USA, ISO, European
439             7 - European, USA, ISO
440             8 - European, ISO, USA
441             If you provide an invalid choice, it will assume the default format.
442              
443             B - Defaults to B<0> (no). When parsing dates, should we
444             be using L, if it's installed, for additional parsing of dates
445             if nothing else works?
446              
447             There are many other I not exposed in the POD. They are only set
448             via the specialized B functions. So they are not documented here.
449              
450             =back
451              
452             =head1 ==================================================================
453              
454             =head2 Z<>
455              
456             =head1 The Special Date Variable Formatting Options
457              
458             This module allows for special predefined date related variables for use in your
459             config files. These options deal with how to format these dates when these
460             variables are referenced. These formatting rules apply to all of the special
461             date variables.
462              
463             =over 4
464              
465             B - Used to define the ordering of the parts of the dates.
466             0 - YMD (ISO), 1 - MDY (American), 2 - DMY (European). The default is B<0>.
467              
468             B - The separator to use with the date. Defaults to "-".
469              
470             B - How to display the month variables. 0 - numeric, 1 -
471             abbreviate names, 2 - full names. The default is B<0>.
472              
473             B - What language to use when using month names. Defaults
474             to I.
475              
476             B - How to calculate the date values. 0 - use localtime, 1 - use
477             gmtime. The default is B<0>.
478              
479             =back
480              
481             =head1 ==================================================================
482              
483             =head2 Z<>
484              
485             =head1 FUNCTIONS
486              
487             As a reminder, there is no need to directly call any of the following functions.
488             They are documented mostly for the benefit of the developer who uses them to
489             implement the internals to L.
490              
491             Most of them are too specialized to be of much use to you.
492              
493             =over 4
494              
495             =cut
496              
497             package Advanced::Config::Options;
498              
499 27     27   123394 use strict;
  27         61  
  27         1201  
500 27     27   153 use warnings;
  27         72  
  27         1975  
501              
502 27     27   162 use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION );
  27         50  
  27         1952  
503 27     27   157 use Exporter;
  27         79  
  27         2623  
504              
505             $VERSION = "1.14";
506             @ISA = qw( Exporter );
507              
508             @EXPORT = qw( get_read_opts get_get_opts get_date_opts
509             apply_get_rules
510             is_assign_spaces
511             using_default_quotes
512             convert_to_regexp_string
513             convert_to_regexp_modifier
514             should_we_hide_sensitive_data
515             make_it_sensitive
516             sensitive_cnt
517             croak_helper
518             set_special_date_vars
519             change_special_date_vars
520             );
521              
522             @EXPORT_OK = qw( );
523              
524 27     27   3180 use Advanced::Config::Date;
  27         60  
  27         3644  
525 27     27   194 use Fred::Fish::DBUG 2.09 qw / on_if_set ADVANCED_CONFIG_FISH /;
  27         701  
  27         239  
526              
527             # The name of the default section ... (even if no sections are defined!)
528 27     27   9786 use constant DEFAULT_SECTION_NAME => "main"; # Must be in lower case!
  27         54  
  27         23175  
529              
530             my %default_read_opts;
531             my %default_get_opts;
532             my %default_date_opts;
533             my @hide_from_fish;
534              
535              
536             # ==============================================================
537             # Get who you're currrently logged in as.
538             # Put here to avoid circular references between modules.
539             sub _get_user_id
540             {
541 53     53   505 DBUG_ENTER_FUNC ( @_ );
542 53         13468 my $user = "??";
543 53         125 eval {
544             # Mostly used on unix like systms.
545 53   50     10163 $user = getpwuid ($<) || "??";
546             };
547 53 50       258 if ( $@ ) {
548             # Can't use on unix due to sudo issue returns wrong user.
549 0   0     0 $user = getlogin () || "??";
550             }
551 53         291 DBUG_RETURN ($user);
552             }
553              
554             # ==============================================================
555             # A stub of the source callback function ...
556             sub _source_callback_stub
557             {
558 20     20   75 DBUG_ENTER_FUNC ( @_ );
559 20         11208 my $file = shift;
560 20         48 my $opts = shift;
561 20         69 DBUG_RETURN ( undef, undef );
562             }
563              
564              
565             # ==============================================================
566             # A stub of the encryption/decryption callback function ...
567             sub _encryption_callback_stub
568             {
569 18382     18382   71697 DBUG_MASK_NEXT_FUNC_CALL (2); # Mask $value!
570 18382         760804 DBUG_ENTER_FUNC ( @_ );
571 18382         8637117 my $mode = shift;
572 18382         42634 my $tag = shift;
573 18382         34395 my $value = shift; # Clear text sensitive value ...
574 18382         37450 my $file = shift;
575 18382         33526 my $cbOpts = shift;
576 18382         62889 DBUG_MASK ( 0 );
577 18382         647276 DBUG_RETURN ( $value );
578             }
579              
580              
581             # ==============================================================
582             # Initialize the global hashes with their default values ...
583             BEGIN
584             {
585 27     27   270 DBUG_ENTER_FUNC ();
586              
587             # ---------------------------------------------------------------------
588             # Make sure no hash value is undef !!!
589             # ---------------------------------------------------------------------
590              
591             # You can only add to this list, you can't remove anything from it!
592             # See should_we_hide_sensitive_data () on how this list is used.
593 27         9330 DBUG_PRINT ("INFO", "Initializing the tag patterns to hide from fish ...");
594 27         4957 push ( @hide_from_fish, "password" );
595 27         63 push ( @hide_from_fish, "pass" );
596 27         71 push ( @hide_from_fish, "pwd" );
597              
598             # ---------------------------------------------------------------------
599              
600 27         88 DBUG_PRINT ("INFO", "Initializing the READ options global hash ...");
601             # Should always be set in the constructor ...
602 27         4398 $default_read_opts{tag_case} = 0; # Case sensitive tags.
603              
604             # The generic options ...
605 27         94 my %src_empty;
606 27         57 $default_read_opts{croak} = 0; # Don't croak by default.
607 27         105 $default_read_opts{export} = 0; # Don't export any tag/val pairs.
608 27         145 $default_read_opts{use_utf8} = 0; # Doesn't support utf8/Unicode/Wide Chars.
609 27         85 $default_read_opts{disable_quotes} = 0; # Don't disable balanced quotes.
610 27         88 $default_read_opts{disable_variables} = 0; # Don't disable variables!
611 27         114 $default_read_opts{disable_variable_modifiers} = 0; # Don't disable variable modifiers!
612 27         145 $default_read_opts{disable_decryption} = 0; # Don't disable decryption!
613             # $default_read_opts{enable_backquotes} = 0; # Don't allow random command execution.
614 27         87 $default_read_opts{trap_recursion} = 0; # Recursion is ignored, not fatal
615 27         397 $default_read_opts{source_cb} = __PACKAGE__->can ("_source_callback_stub");
616 27         91 $default_read_opts{source_cb_opts} = \%src_empty;
617              
618             # The file parsing options ...
619 27         292 $default_read_opts{assign} = '='; # The assignment operator
620 27         125 $default_read_opts{comment} = '#'; # The comment symbol
621 27         87 $default_read_opts{source} = '.'; # The file source symbol
622 27         93 $default_read_opts{section_left} = '['; # The start section string
623 27         108 $default_read_opts{section_right} = ']'; # The end section string
624 27         71 $default_read_opts{variable_left} = '${'; # The start variable string
625 27         65 $default_read_opts{variable_right} = '}'; # The end variable string
626              
627             # Unlikely default values due to security concerns.
628             # $default_read_opts{backquote_left} = '`'x101; # The start backquote string
629             # $default_read_opts{backquote_right} = '`'x102; # The end backquote string
630              
631             # The quote chars ... (Special case doesn't work for anything else.)
632             # See using_default_quotes() if this changes ...
633 27         66 $default_read_opts{quote_left} = $default_read_opts{quote_right} = "['\"]";
634              
635             # The tag/value modifiers. These labels are found inside the comments!
636 27         67 $default_read_opts{export_lbl} = "EXPORT"; # Label for a single %ENV.
637 27         97 $default_read_opts{hide_lbl} = "HIDE"; # Mark as sensitive.
638 27         60 $default_read_opts{encrypt_lbl} = "ENCRYPT"; # Pending encryption.
639 27         70 $default_read_opts{decrypt_lbl} = "DECRYPT"; # Already encrypted.
640 27         57 $default_read_opts{source_file_section_lbl} = "DEFAULT"; # Override default.
641              
642             # The Encrypt/Decrypt options ... (Encode/Decode)
643 27         59 my %empty_encrypt;
644 27         51 $default_read_opts{alias} = "";
645 27         49 $default_read_opts{pass_phrase} = "";
646 27         52 $default_read_opts{inherit_pass_phrase} = 0;
647 27         45 $default_read_opts{encrypt_by_user} = 0;
648 27         187 $default_read_opts{encrypt_cb} = __PACKAGE__->can ("_encryption_callback_stub");
649 27         112 $default_read_opts{encrypt_cb_opts} = \%empty_encrypt;
650              
651             # Special undocumented test prog option for overriding fish in parse_line().
652 27         317 $default_read_opts{dbug_test_use_case_parse_override} = 0; # Always off.
653              
654             # Special undocumented test prog option for overriding fish in read_config().
655 27         190 $default_read_opts{dbug_test_use_case_hide_override} = 0; # Always off.
656              
657              
658             # ---------------------------------------------------------------------
659              
660 27         179 DBUG_PRINT ("INFO", "Initializing the GET options global hash ...");
661             # Should always be set in the constructor ...
662 27         4732 $default_get_opts{inherit} = 0; # Can inherit from the parent section.
663              
664             # The generic options ... Who cares where set!
665 27         120 $default_get_opts{required} = 0; # Return undef by default.
666 27         86 $default_get_opts{vcase} = 0; # Case of the value. (0 = as is)
667 27         219 $default_get_opts{split_pattern} = qr /\s+/; # Space separated lists.
668              
669             # Used in parsing dates for get_date() ...
670 27         89 $default_get_opts{date_language} = "English"; # The language to use in parsing dates.
671 27         86 $default_get_opts{date_language_warn} = 0; # Disable warnings in Date.pm.
672 27         113 $default_get_opts{date_dl_conversion} = 0; # 1-Enable 0-Disable using Date::Language for parsing.
673 27         54 $default_get_opts{date_enable_yy} = 0; # 1-Enable 0-Disable using 2 digit years in a date!
674 27         58 $default_get_opts{date_format} = 3; # Hints are 0 to 8.
675              
676             # These special case options not to show up in the POD ...
677             # All associated with special "get_*()" functions that will auto set if needed.
678 27         70 $default_get_opts{numeric} = 0; # 0-no, 1-integer (truncate), 2-integer (round), 3-real.
679 27         270 $default_get_opts{auto_true} = 0; # Don't return as boolean.
680 27         162 $default_get_opts{filename} = 0; # Tag doesn't do a file test.
681 27         164 $default_get_opts{directory} = 0; # Tag doesn't do a directory test.
682 27         88 $default_get_opts{split} = 0; # Don't split the value.
683 27         76 $default_get_opts{sort} = 0; # Don't sort the split value. (1 - sort, -1 - reverse sort)
684 27         65 $default_get_opts{date_active} = 0; # 0-No, 1-Yes expecing it to be a date.
685              
686              
687             # ---------------------------------------------------------------------
688              
689 27         106 DBUG_PRINT ("INFO", "Initializing the DATE formatting options global hash ...");
690 27         4667 $default_date_opts{date_order} = 0; # 0 - YMD, 1 - MDY, 2 - DMY
691 27         71 $default_date_opts{date_sep} = "-"; # Separator to format dates with.
692 27         50 $default_date_opts{month_type} = 0; # 0 - numeric, 1 - abbreviate, 2 - full.
693 27         62 $default_date_opts{month_language} = "English"; # See Date::Language.
694 27         61 $default_date_opts{use_gmt} = 0; # 0 - localtime, 1 - gmtime.
695             # $default_date_opts{timestamp} = ?; # Special case can't set directly.
696              
697             # ---------------------------------------------------------------------
698              
699              
700 27         128 DBUG_VOID_RETURN ();
701             }
702              
703             # ==============================================================
704             # A private helper method ... (not exported)
705             sub _get_opt_base
706             {
707 7031     7031   24969 DBUG_ENTER_FUNC ( @_ );
708 7031         1966407 my $user_opts = shift;
709 7031         13338 my $defaults = shift; # Which default hash to validate against ...
710              
711             # Make own copy of the defaults hash ...
712 7031         11576 my %result = %{$defaults};
  7031         102800  
713              
714             # Must warn about invalid key values ...
715 7031         24449 foreach ( sort keys %{$user_opts} ) {
  7031         63361  
716 74714         127906 my $k = lc ($_);
717 74714         127012 my $val = $user_opts->{$_};
718              
719 74714 50       158949 unless ( exists $defaults->{$k} ) {
720 0         0 warn "Unknown option '$k'. Option ignored.\n";
721 0         0 next;
722             }
723              
724             # -------------------------------------
725             # Trim it to make sure it's valid ...
726             # -------------------------------------
727 74714         111750 my $no_spaces_allowed = 1;
728 74714 50       135765 if ( defined $val ) {
729 74714 100       130361 if ( $k eq "date_sep" ) {
730 7         13 $no_spaces_allowed = 0;
731             } else {
732 74707         169523 $val =~ s/^\s+//;
733 74707         152085 $val =~ s/\s+$//;
734             }
735              
736             } else {
737 0 0       0 if ( defined $defaults->{$k} ) {
738 0         0 warn "Option '$k' has no defined value. Override ignored.\n";
739             } else {
740 0         0 $result{$k} = undef;
741             }
742 0         0 next;
743             }
744              
745             # Making sure never undef for easier comparisons later on ...
746 74714 50       160615 my $expect = ( defined $defaults->{$k} ) ? $defaults->{$k} : "";
747              
748             # -------------------------------------
749             # Is this a call back reference ...
750             # -------------------------------------
751 74714 100       148097 if ( ref ( $expect ) eq "CODE" ) {
752 906         2433 my $call;
753 906 100       1970 if ( ref ($val) eq "CODE" ) {
    50          
754 904         1569 $call = $val;
755             } elsif ( ref ($val) eq "") {
756 2 50       17 if ( $val =~ m/^(.*)::([^:]+)$/ ) {
    0          
757 2         14 my ($pkg, $func) = ($1, $2);
758 2         79 $call = $pkg->can ($func);
759             } elsif ( $val ne "" ) {
760 0         0 $call = "main"->can ($val);
761             }
762             }
763              
764 906 50       1955 if ( $call ) {
765 906         1925 $result{$k} = $call;
766             } else {
767 0         0 warn "Option '$k' must be a callback function. Can't reference '$val'. Override ignored.\n";
768             }
769 906         2402 next;
770             }
771              
772             # -------------------------------------
773             # Is this a regular expression?
774             # Used in calls to split ...
775             # -------------------------------------
776 73808 100       136081 if ( ref ( $expect ) eq "Regexp" ) {
777 3448 50 0     13733 if ( ref ( $val ) eq "Regexp" ) {
    0          
778 3448         9700 $result{$k} = $val;
779             } elsif ( ref ( $val ) eq "" && $val ) {
780 0         0 $result{$k} = $val;
781             } else {
782 0         0 warn "Option '$k' must be a Regexp or a string, not '$val'. Override ignored.\n";
783             }
784             }
785              
786             # -------------------------------------
787             # Setting up a work area hash ...
788             # -------------------------------------
789 73808 100       135229 if ( ref ( $expect ) eq "HASH" ) {
790 872 50       2126 if ( ref ( $val ) eq "HASH" ) {
791 872         1660 $result{$k} = $val;
792             } else {
793 0         0 warn "Option '$k' must be a hash reference, not '$val'. Override ignored.\n";
794             }
795 872         1747 next;
796             }
797              
798             # -------------------------------------
799 72936 50 100     151893 if ( $val eq "" && $expect ne "" && $no_spaces_allowed ) {
      66        
800 0         0 warn "Option '$k' can't be set to the empty string. Override ignored.\n";
801 0         0 next;
802             }
803              
804             # -------------------------------------
805 72936 50 66     307943 if ( $expect =~ m/^-?\d+$/ && $val !~ m/^-?\d+$/ ) {
806 0         0 warn "Option '$k' must be numeric ($val). Override ignored.\n";
807 0         0 next;
808             }
809              
810             # -------------------------------------
811 72936 50 66     233728 if ( $expect !~ m/^-?\d+$/ && $val =~ m/^-?\d+$/ ) {
812 0         0 warn "Option '$k' may not be numeric ($val). Override ignored.\n";
813 0         0 next;
814             }
815              
816 72936         179364 $result{$k} = $val;
817             }
818              
819 7031         35950 DBUG_RETURN ( \%result );
820             }
821              
822             # ==============================================================
823              
824             =item $ropts = get_read_opts ( [\%user_opts[, \%current_opts]] )
825              
826             This method takes the I options that override the behavior for reading
827             in your config file by this module and merges it into the I options.
828             If no I options hash reference is given, it will use the module's
829             defaults instead.
830              
831             It returns a hash reference of all applicable "Read" options.
832              
833             =cut
834              
835             # ==============================================================
836             sub get_read_opts
837             {
838 483     483 1 1611372 DBUG_ENTER_FUNC ( @_ );
839 483         260229 my $user_opts = shift;
840 483         1363 my $current = shift;
841              
842             # Get the default values ...
843 483         14095 my %def = %default_read_opts;
844 483         2026 my $ref = \%def;
845              
846 483 100       2232 $ref = _get_opt_base ( $current, $ref ) if ( defined $current );
847 483 100       225501 $ref = _get_opt_base ( $user_opts, $ref ) if ( defined $user_opts );
848              
849             # Some additional validation ...
850 483 50       102918 if ( $ref->{encrypt_lbl} eq $ref->{decrypt_lbl} ) {
851 0         0 my $val = $ref->{encrypt_lbl};
852 0         0 $ref->{encrypt_lbl} = $default_read_opts{encrypt_lbl};
853 0         0 $ref->{decrypt_lbl} = $default_read_opts{decrypt_lbl};
854 0         0 warn ("Options 'encrypt_lbl' and 'decrypt_lbl' may not be set to the same value ($val).\n",
855             "Resetting both to their default settings!\n");
856             }
857              
858 483         1642 DBUG_RETURN ( $ref );
859             }
860              
861             # ==============================================================
862              
863             =item $gopts = get_get_opts ( [\%user_opts[, \%current_opts]] )
864              
865             This method takes the I options that override the behavior of I
866             methods for this module and merges it into the I options. If no
867             I options hash reference is given, it will use the module's defaults
868             instead.
869              
870             It returns a hash reference of all applicable "Get" options.
871              
872             =cut
873              
874             # ==============================================================
875             sub get_get_opts
876             {
877 3269     3269 1 13372 DBUG_ENTER_FUNC ( @_ );
878 3269         797778 my $user_opts = shift;
879 3269         8033 my $current = shift;
880              
881             # Get the default values ...
882 3269         43112 my %def = %default_get_opts;
883 3269         11622 my $ref = \%def;
884              
885 3269 100       16153 $ref = _get_opt_base ( $current, $ref ) if ( defined $current );
886 3269 100       474503 $ref = _get_opt_base ( $user_opts, $ref ) if ( defined $user_opts );
887              
888             # Some additional validation ...
889 3269 50 33     478961 unless ( 0 <= $ref->{date_format} && $ref->{date_format} <= 8 ) {
890 0         0 my $val = $ref->{date_format};
891 0         0 $ref->{date_format} = $default_read_opts{date_format};
892 0         0 warn ("Option 'date_format' is invalid ($val). Resetting to it's default!\n");
893             }
894              
895 3269         9638 DBUG_RETURN ( $ref );
896             }
897              
898             # ==============================================================
899              
900             =item $dopts = get_date_opts ( [\%user_opts[, \%current_opts]] )
901              
902             This method takes the I options that override the behavior of I
903             formatting for this module and merges it into the I options. If no
904             I options hash reference is given, it will use the module's defaults
905             instead.
906              
907             It returns a hash reference of all applicable "Date" formatting options.
908              
909             =cut
910              
911             # ==============================================================
912             sub get_date_opts
913             {
914 91     91 1 2116 DBUG_ENTER_FUNC ( @_ );
915 91         47331 my $user_opts = shift;
916 91         262 my $current = shift;
917              
918             # Get the default values ...
919 91         819 my %def = %default_date_opts;
920 91         325 my $ref = \%def;
921              
922 91 100       547 $ref = _get_opt_base ( $current, $ref ) if ( defined $current );
923 91 100       728 $ref = _get_opt_base ( $user_opts, $ref ) if ( defined $user_opts );
924              
925 91         10275 DBUG_RETURN ( $ref );
926             }
927              
928             # ==============================================================
929              
930             =item $ref = apply_get_rules ( $tag, $section, $val1, $val2, $wide, $getOpts )
931              
932             Returns an updated hash reference containing the requested data value after all
933             the I<$getOpts> rules have been applied. If the I<$tag> doesn't exist then it
934             will return B instead or B if it's I.
935              
936             I<$val1> is the DATA hash value from the specified section.
937              
938             I<$val2> is the DATA hash value from the parent section. This value is ignored
939             unless the I option was specified via I<$getOpts>.
940              
941             I<$wide> tells if UTF-8 dates are allowed.
942              
943             =cut
944              
945             # ==============================================================
946             sub apply_get_rules
947             {
948 67201     67201 1 244975 DBUG_ENTER_FUNC (@_);
949 67201         25116112 my $tag = shift; # The tag we are processing ...
950 67201         140022 my $section = shift; # The name of the current section ...
951 67201         138597 my $value1 = shift; # The value hash from the current section ...
952 67201         128389 my $value2 = shift; # The value hash from the "main" section ...
953 67201         104506 my $wide_flg = shift; # Tells if langages like Greek are allowed ...
954 67201         109193 my $get_opts = shift; # The current "Get" options hash ...
955              
956             # Did we find a value to process?
957 67201         108414 my $data = $value1;
958 67201 100 100     251166 if ( $get_opts->{inherit} && (! defined $data) ) {
959 32         51 $data = $value2;
960             }
961 67201 100       174137 unless ( defined $data ) {
962 9028         38683 return DBUG_RETURN ( croak_helper ( $get_opts,
963             "No such tag ($tag) in section ($section).",
964             undef ) );
965             }
966              
967             # Make a local copy to work with, we don't want to modify the source.
968             # We're only interested in two entries from the hash: VALUE & MASK_IN_FISH.
969             # All others are ignored by this method.
970 58173         94254 my %result = %{$data};
  58173         487371  
971              
972             # Do we split up the value? ( Took 2 options to implement the split. )
973 58173         136503 my @vals;
974 58173 100       172663 unless ( $get_opts->{split} ) {
975 57908         157910 push (@vals, $result{VALUE}); # Nope!
976              
977             } else {
978 265         4283 @vals = split ( $get_opts->{split_pattern}, $result{VALUE} );
979 265         877 $result{VALUE} = \@vals;
980             }
981              
982             # Only if sorting, assume everything in the list is numeric ...
983 58173 100       136032 my $is_all_numbers = $get_opts->{sort} ? 1 : 0;
984              
985             # Do any validation that needs to be done against the individual parts ...
986 58173         147599 foreach my $v ( @vals ) {
987 59083         101045 my $old = $v; # Save in case someone modifies $v!
988              
989             # -------------------------------------------------------------------
990             # Do we need to convert to upper or lower case?
991 59083 50       210056 if ( $get_opts->{vcase} > 0 ) {
    50          
992 0         0 $v = uc ( $v );
993             } elsif ( $get_opts->{vcase} < 0 ) {
994 0         0 $v = lc ( $v );
995             }
996              
997             # -------------------------------------------------------------------
998             # Convert into a boolean value ??? (you never see the original value)
999 59083 100       136600 if ( $get_opts->{auto_true} ) {
1000 89         188 $result{MASK_IN_FISH} = 0; # Boolean values are never sensitive!
1001              
1002 89         172 my $numeric = 0;
1003 89 100 100     635 if ( $old =~ m/^[-+]?\d+([.]\d*)?$/ ||
1004             $old =~ m/^[-+]?[.]\d+$/ ) {
1005 48         100 $numeric = 1;
1006 48         168 $old += 0; # Convert string to a number ...
1007             }
1008              
1009 89         173 $v = 0; # Assume FALSE ...
1010 89 100 66     443 unless ( $old ) {
    100          
1011             ;
1012 0         0 } elsif ( $numeric ) {
1013 24         65 $v = 1; # It's TRUE for a non-zero numeric value ...
1014             } elsif ( $old =~ m/(^true[.!;]?$)|(^yes[.!;]?$)|(^good[.!;]?$)|(^[TYG]$)|(^on[.!;]?$)/i ) {
1015             $v = 1; # It's TRUE for certain text strings ...
1016             }
1017             }
1018              
1019             # -------------------------------------------------------------------
1020             # Are we requiring it to be a numeric value?
1021             # Also run if we want to test if something is numeric for the later sort!
1022             # 0 - Skip test.
1023             # 1 - integer (round).
1024             # 2 - integer (truncate).
1025             # 3 - real.
1026 59083 100 100     297315 if ( $get_opts->{numeric} || $is_all_numbers ) {
1027 459         855 my $fp = 0;
1028 459         847 my $err;
1029 459         1134 my $run_flg = ($get_opts->{numeric} != 0);
1030              
1031 459 50 33     4680 if ( $v =~ m/^[+-]?\d+([.]\d*)?[Ee][+-]?\d+$/ ||
    100 100        
    100          
1032             $v =~ m/^[+-]?[.]\d+[Ee][+-]?\d$/ ) {
1033 0         0 $fp = 1; # In Scientific Notiation ...
1034 0 0       0 if ( $run_flg ) {
1035 0         0 $v += 0; # Converts out of Scientific Notiation if possible!
1036             }
1037             } elsif ( $v =~ m/^[+-]?\d+$/ ) {
1038 244         517 $fp = 0; # It was an integer ...
1039             } elsif ( $v =~ m/^[+-]?\d+[.]\d*$/ ||
1040             $v =~ m/^[+-]?[.]\d+$/ ) {
1041 168         373 $fp = 1; # A floating point numeric value ...
1042 168 100       968 $v += 0 if ( $run_flg );
1043             } else {
1044 47         87 $err = 1; # Not a valid number!
1045 47         88 $is_all_numbers = 0;
1046             }
1047              
1048             # If really a floating point number & asking for an integer ...
1049 459 100 100     2081 if ( $run_flg && $fp && $get_opts->{numeric} != 3 ) {
      100        
1050 80 100       329 if ( $get_opts->{numeric} == 1 ) {
1051 40         143 $v = sprintf ("%.0f", $v); # Round it up ...
1052             } else {
1053 40         227 $v = sprintf ("%d", $v); # Truncate it ...
1054             }
1055             }
1056              
1057 459 100 100     1456 if ( $err && $run_flg ) {
1058 15         80 return DBUG_RETURN ( croak_helper ( $get_opts,
1059             "Value is not numeric ($v) for tag ($tag) in section ($section).",
1060             undef ) );
1061             }
1062             }
1063              
1064             # -------------------------------------------------------------------
1065             # Are we expecting to find a date someplace inside this string?
1066 59068 100       167316 if ( $get_opts->{date_active} ) {
1067 2633         11409 my @order = ( "1", "2", "3", "1,2,3", "1,3,2", "2,3,1", "2,1,3", "3,2,1", "3,1,2" );
1068             my $l = swap_language ( $get_opts->{date_language},
1069             $get_opts->{date_language_warn},
1070 2633         16268 $wide_flg );
1071             my $date = parse_date ( $v, $order[$get_opts->{date_format}],
1072             $get_opts->{date_dl_conversion},
1073 2633         309596 $get_opts->{date_enable_yy} );
1074 2633 100       288528 if ( $date ) {
1075 2619         11337 $v = $date;
1076             } else {
1077 14   33     71 my $l2 = $get_opts->{date_language} || $l;
1078 14         110 return DBUG_RETURN ( croak_helper ( $get_opts,
1079             "Value is not a date ($v) for tag ($tag) in section ($section) for language ($l2).",
1080             undef ) );
1081             }
1082             }
1083              
1084             # -------------------------------------------------------------------
1085             # Are we referencing a file?
1086 59054 100       151542 if ( $get_opts->{filename} ) {
1087 18         31 my $valid = 1; # Assume it's a filename ...
1088 18 100       394 $valid = 0 unless ( -f $v );
1089 18 50 33     86 $valid = 0 if ( ($get_opts->{filename} & 2) && ! -r _ );
1090 18 50 33     76 $valid = 0 if ( ($get_opts->{filename} & 4) && ! -w _ );
1091 18 50 33     52 $valid = 0 if ( ($get_opts->{filename} & 8) && ! -x _ );
1092 18 100       78 unless ( $valid ) {
1093 10         77 return DBUG_RETURN ( croak_helper ( $get_opts,
1094             "Tag ${tag} doesn't reference a valid filename or it doesn't have the requested permissions! ($v)",
1095             undef ) );
1096             }
1097             }
1098              
1099             # -------------------------------------------------------------------
1100             # Are we referencing a directory?
1101 59044 100       137240 if ( $get_opts->{directory} ) {
1102 19         39 my $valid = 1; # Assume it's a directory ...
1103 19 100       547 $valid = 0 unless ( -d $v );
1104 19 50 66     154 $valid = 0 if ( ($get_opts->{directory} & 2) && ! -r _ );
1105 19 50 66     78 $valid = 0 if ( ($get_opts->{directory} & 4) && ! -w _ );
1106 19 50 66     84 $valid = 0 if ( ($get_opts->{directory} & 8) && ! -x _ );
1107 19 100       57 unless ( $valid ) {
1108 10         89 return DBUG_RETURN ( croak_helper ( $get_opts,
1109             "Tag ${tag} doesn't reference a valid directory or it doesn't have the requested permissions! ($v)",
1110             undef ) );
1111             }
1112             }
1113              
1114             # -------------------------------------------------------------------
1115             # If not splitting after all, save any changes ... (keep last in loop)
1116 59034 100 100     269518 if ( (! $get_opts->{split}) && $old ne $v ) {
1117 2609         9134 $result{VALUE} = $v;
1118             }
1119             } # End foreach @vals loop ...
1120              
1121              
1122             # Do we need to sort the results ???
1123 58124 100 100     129749 if ( $get_opts->{split} && $get_opts->{sort} ) {
1124 125 100       346 if ( $is_all_numbers ) {
1125 93         535 @{$result{VALUE}} = sort { $a <=> $b } @{$result{VALUE}};
  93         409  
  379         921  
  93         692  
1126             } else {
1127 32         71 @{$result{VALUE}} = sort ( @{$result{VALUE}} );
  32         133  
  32         120  
1128             }
1129 125 100       484 @{$result{VALUE}} = reverse ( @{$result{VALUE}} ) if ( $get_opts->{sort} < 0 );
  60         183  
  60         252  
1130             }
1131              
1132 58124         197656 DBUG_RETURN ( \%result );
1133             }
1134              
1135             # ==============================================================
1136              
1137             =item $boolean = is_assign_spaces ( $ropts )
1138              
1139             Tells if the assignment operator selected is the special case of using spaces
1140             to separate the tag/value pair. Only returns true if it's B<\\s>.
1141              
1142             =cut
1143              
1144             # No fish since it's called so frequently, over & over again ...
1145             sub is_assign_spaces
1146             {
1147             # Checking the ${rOpts} settings ...
1148 128873   100 128873 1 869638 return ( exists $_[0]->{assign} && $_[0]->{assign} eq "\\s" );
1149             }
1150              
1151             # ==============================================================
1152              
1153             =item $boolean = using_default_quotes ( $ropts )
1154              
1155             This function tells if you are currently using the default quotes. This is the
1156             only case where there can be multiple values for the quote string anchors. All
1157             other cases allow only for a single value for each of the quote string anchors.
1158              
1159             =cut
1160              
1161             sub using_default_quotes
1162             {
1163 75336     75336 1 257923 DBUG_ENTER_FUNC ( @_ );
1164 75336         24552637 my $ropts = shift;
1165              
1166 75336         160629 my $def = 0; # Assume not using the default quotes ...
1167              
1168 75336 50       263815 unless ( $ropts->{disable_quotes} ) {
1169 75336 100       278688 if ( $ropts->{quote_left} eq $ropts->{quote_right} ) {
1170 75035 100 66     257316 if ( $ropts->{quote_left} eq "['\"]" ||
1171             $ropts->{quote_left} eq "[\"']" ) {
1172 67694         118486 $def = 1;
1173             }
1174             }
1175             }
1176              
1177 75336         215963 DBUG_RETURN ( $def );
1178             }
1179              
1180              
1181             # ==============================================================
1182              
1183             =item $str = convert_to_regexp_string ( $string[, $no_logs] )
1184              
1185             Converts the passed string that may contain special chars for a Perl RegExp
1186             into something that is a literal constant value to Perl's RegExp engine by
1187             turning these problem chars into escape sequences.
1188              
1189             It then returns the new string.
1190              
1191             If I<$no_logs> is set to a non-zero value, it won't write anything to the logs.
1192              
1193             =cut
1194              
1195             sub convert_to_regexp_string
1196             {
1197 453535     453535 1 2250351 my $no_fish = $_[1];
1198 453535 100       1171119 DBUG_ENTER_FUNC ( @_ ) unless ( $no_fish );;
1199 453535         19016495 my $str = shift;
1200              
1201             # The 8 problem chars with special meaning in a RegExp ...
1202             # Chars: . + ^ | $ \ * ?
1203 453535         1845946 $str =~ s/([.+^|\$\\*?])/\\$1/g;
1204              
1205             # As do these 3 types of brackets: (), {}, []
1206 453535         1378855 $str =~ s/([(){}[\]])/\\$1/g;
1207              
1208 453535 100       1107907 return DBUG_RETURN ( $str ) unless ( $no_fish );
1209 401352         1156913 return ( $str );
1210             }
1211              
1212             # ==============================================================
1213              
1214             =item $str = convert_to_regexp_modifier ( $string )
1215              
1216             Similar to C except that it doesn't convert
1217             all the wild card chars.
1218              
1219             Leaves the following RegExp wild card's unescaped!
1220             S<(B<*>, B, B<[>, and B<]>)>
1221              
1222             Used when processing variable modifier rules.
1223              
1224             =cut
1225              
1226             sub convert_to_regexp_modifier
1227             {
1228 11     11 1 34 DBUG_ENTER_FUNC ( @_ );
1229 11         4680 my $str = shift;
1230              
1231             # The 6 problem chars with special meaning in a RegExp ...
1232             # Chars: . + ^ | $ \ (Skips * ?)
1233 11         28 $str =~ s/([.+^|\$\\])/\\$1/g;
1234              
1235             # As do these 2 of 3 types of brackets: () & {}, not []
1236 11         21 $str =~ s/([(){}])/\\$1/g;
1237              
1238 11         26 DBUG_RETURN ( $str );
1239             }
1240              
1241             # ==============================================================
1242              
1243             =item $sensitive = should_we_hide_sensitive_data ( $tag )
1244              
1245             Checks the tag against an internal list of patterns to see if there is a match.
1246             This check is done in a case insensitive way.
1247              
1248             If there is a match it will return true and the caller should take care about
1249             writing anything about this tag to any log files.
1250              
1251             If there is no match it will return false, and you can write what you please to
1252             your logs.
1253              
1254             See I to add additional patterns to the list.
1255              
1256             =cut
1257              
1258             sub should_we_hide_sensitive_data
1259             {
1260 54390     54390 1 108974 my $tag = shift;
1261 54390         87347 my $skip_fish = shift; # Undocumented ...
1262              
1263 54390         91650 my $sensitive = 0; # Assume it's not to be hidden!
1264              
1265 54390         128333 foreach my $hide ( @hide_from_fish ) {
1266 165514 100       1907041 if ( $tag =~ m/${hide}/i ) {
1267 253         779 $sensitive = 1; # We found a match! It's sensitive!
1268             }
1269             }
1270              
1271 54390 100       135030 unless ( $skip_fish ) {
1272 653         3153 DBUG_ENTER_FUNC ( $tag, $skip_fish, @_ );
1273 653         256906 return DBUG_RETURN ( $sensitive );
1274             }
1275              
1276 53737         220008 return ( $sensitive );
1277             }
1278              
1279             # ==============================================================
1280              
1281             =item make_it_sensitive ( @patterns )
1282              
1283             Add these pattern(s) to the internal list of patterns that this module considers
1284             sensitive. Should any tag contain this pattern, that tag's value will be
1285             masked when written to this module's internal logs. Leading/trailing spaces
1286             will be ignored in the pattern. Wild cards are not honored.
1287              
1288             The 3 default patterns are password, pass, and pwd.
1289              
1290             This pattern affects all L objects loaded into memory. Not
1291             just the current one.
1292              
1293             =cut
1294              
1295             sub make_it_sensitive
1296             {
1297 4     4 1 386739 DBUG_ENTER_FUNC ( @_ );
1298 4         1852 my @tags = @_;
1299              
1300 4         12 foreach my $tag ( @tags ) {
1301 8 50       22 if ( $tag ) {
1302 8         20 $tag =~ s/^\s+//;
1303 8         17 $tag =~ s/\s+$//;
1304 8 50       22 if ( $tag ) {
1305 8         18 $tag = convert_to_regexp_string ( $tag, 1 );
1306 8         24 push ( @hide_from_fish, $tag );
1307             }
1308             }
1309             }
1310              
1311 4         20 DBUG_VOID_RETURN ();
1312             }
1313              
1314             # ==============================================================
1315              
1316             =item $cnt = sensitive_cnt ( )
1317              
1318             Returns a count of how many sensitive patterns are being used.
1319              
1320             =cut
1321              
1322             sub sensitive_cnt
1323             {
1324 233     233 1 953 DBUG_ENTER_FUNC ( @_ );
1325 233         77305 DBUG_RETURN ( scalar (@hide_from_fish) );
1326             }
1327              
1328             # ==============================================================
1329              
1330             =item @ret = croak_helper ($opts, $croak_message, @croak_return_vals)
1331              
1332             This helper method helps standardizes what to do on fatal errors when reading
1333             the config file or what to do if you can't find the tag on lookups.
1334              
1335             It knows I<\%opts> is a "Read" option hash if B is a member and it's
1336             a "Get" option hash if B is a member. Both options use the same
1337             logic when called.
1338              
1339             See B and B on what these options do.
1340              
1341             Returns whatever I<@croak_return_vals> references. It may be a single value or
1342             an array of values.
1343              
1344             It calls B or B with the message passed.
1345              
1346             =cut
1347              
1348             # ==============================================================
1349             # No ENTER/RETURN fish calls on purpose here ...
1350              
1351             sub croak_helper
1352             {
1353 9084     9084 1 15393 my $opts = shift;
1354 9084         15804 my $msg = shift;
1355 9084         23392 my @ret = @_; # Use whatever was passed to me ...
1356              
1357             # Look up the needed value in the hash we'd like to test out.
1358 9084         15459 my $croak = 0;
1359 9084 100       34087 if ( exists $opts->{croak} ) {
    50          
1360 5         14 $croak = $opts->{croak}; # From the Read Opt Hash ...
1361             } elsif ( exists $opts->{required} ) {
1362 9079         19568 $croak = $opts->{required}; # From the Get Opt Hash ...
1363             }
1364              
1365 9084 100       30056 if ( $croak > 0 ) {
    100          
    50          
1366 2         42 die ($msg, "\n");
1367              
1368             # The -9876 value is undocumented where we don't even want the msg in fish!
1369             } elsif ( $croak == -9876 ) {
1370             ;
1371              
1372             } elsif ( $croak < 0 ) {
1373 0         0 warn ($msg, "\n");
1374              
1375             } else {
1376 96         744 DBUG_PRINT ("WARN", $msg);
1377             }
1378              
1379 9082 100       62092 return ( wantarray ? @ret : $ret[0] );
1380             }
1381              
1382             # ==============================================================
1383              
1384             =item $lvl = set_special_date_vars ( $date_opts_ref, $date_hash_ref[, $old_hash_ref] )
1385              
1386             The I<$date_opts_ref> contains the special date variable formatting options
1387             used to control the formattiong of the data returned via I<$date_hash_ref>.
1388             The relevant tags are: I, I, I, I
1389             and I. Any missing hash key and it's default is used.
1390              
1391             This function populates the following date keys in I<$date_hash_ref> for use
1392             by the config object using the current date/time. These keys are also defined
1393             as the date variables available for use by your config files.
1394              
1395             The keys set are: (Shown using the default formats)
1396              
1397             today, yesterday, tomorrow -- A formatted date in YYYY-MM-DD format.
1398             this_month, last_month, next_month -- The Month.
1399             this_year, last_year, next_year -- A 4 digit year.
1400             this_period, last_period, next_period -- The YYYY-MM part of a date.
1401             dow -- The day of the week (Sunday to Saturday or 1..7).
1402             doy -- The day of the year (1..365 most years, 1..366 in leap years).
1403             dom -- The day of the month. (1..31)
1404             timestamp -- The time used to generate the above variables with. [time()]
1405              
1406             The I<$old_hash_ref> contains the values from the previous call to this
1407             function. If missing, assumes 1st time called. If provided and the date
1408             options for this call doesn't match what was used to create this hash
1409             the return value is unreliable.
1410              
1411             Returns the level of what changed in ${date_hash_ref}:
1412              
1413             0 -- Nothing changed from previous call or it's the 1st time called.
1414             1 -- Just the day of month changed.
1415             2 -- The month also changed.
1416             3 -- The year also changed.
1417              
1418             =cut
1419              
1420             # ==============================================================
1421              
1422             sub set_special_date_vars
1423             {
1424 136     136 1 45301 DBUG_ENTER_FUNC (@_);
1425 136         70733 my $opts = shift; # The date formatting options ...
1426 136         341 my $dates = shift; # A hash reference of dates to return ...
1427 136         348 my $prev = shift; # The previous hash reference to see what changed ...
1428              
1429 136         296 my %empty;
1430 136 50       670 %{$dates} = %empty if (defined $dates);
  136         340  
1431 136 100       626 $prev = \%empty unless (defined $prev);
1432              
1433 136         563 my ($t1, $t2, $t3) = ("month_language", "month_type", "");
1434 136 50       896 my $lang = (exists $opts->{$t1}) ? $opts->{$t1} : $default_date_opts{$t1};
1435 136 50       684 my $mtyp = (exists $opts->{$t2}) ? $opts->{$t2} : $default_date_opts{$t2};
1436 136         1182 my ($month_ref, $week_day_ref) = init_special_date_arrays ($lang, $mtyp, 0, 0);
1437              
1438             # The formatting info ...
1439 136         35989 ($t1, $t2, $t3) = ("date_order", "date_sep", "use_gmt");
1440 136 50       799 my $order = (exists $opts->{$t1}) ? $opts->{$t1} : $default_date_opts{$t1};
1441 136 50       540 my $sep = (exists $opts->{$t2}) ? $opts->{$t2} : $default_date_opts{$t2};
1442 136 50       492 my $gmt = (exists $opts->{$t3}) ? $opts->{$t3} : $default_date_opts{$t3};
1443              
1444 136         326 my $what_changed = 0; # Nothing ...
1445              
1446             # -------------------------------------------------------------------------
1447             # Initialize the date to use properly
1448             # -------------------------------------------------------------------------
1449 136         303 my $now;
1450 136 100       496 if ( $opts->{timestamp} ) {
1451             # Only set by change_special_date_vars() ... (So undocumented)
1452 1         4 $now = $opts->{timestamp}; # Re-use a previous timestamp.
1453             } else {
1454 135         349 $now = time (); # Start a new timestamp.
1455             }
1456              
1457 136         458 $dates->{timestamp} = $now;
1458              
1459             # -------------------------------------------------------------------------
1460             # Get the desired dates ...
1461              
1462             # Get today ...
1463 136 50       6256 my ($yr, $mon, $day, $hr, $dow, $doy) = $gmt
1464             ? (gmtime ($now))[5,4,3,2,6,7]
1465             : (localtime ($now))[5,4,3,2,6,7];
1466 136         604 $yr += 1900;
1467 136         434 my $month = $month_ref->[$mon];
1468 136         744 $dates->{today} = _fmt_date ($sep, $order, $yr, $month, $day);
1469              
1470             # Get yesterday's date ...
1471 136         419 my $sec = ($hr + 2) * 3600 + 2; # Convert hours to seconds ...
1472 136 50       2237 my ($yr2, $mon2, $day2) = $gmt ? (gmtime ($now - $sec))[5,4,3]
1473             : (localtime ($now - $sec))[5,4,3];
1474 136         455 $yr2 += 1900;
1475 136         381 my $month2 = $month_ref->[$mon2];
1476 136         394 $dates->{yesterday} = _fmt_date ($sep, $order, $yr2, $month2, $day2);
1477              
1478             # Get tomorrow's date ...
1479 136         502 $sec = (24 - $hr + 1) * 3600 + 2; # Convert hours to seconds ...
1480 136 50       1803 my ($yr3, $mon3, $day3) = $gmt ? (gmtime ($now + $sec))[5,4,3]
1481             : (localtime ($now + $sec))[5,4,3];
1482 136         416 $yr3 += 1900;
1483 136         340 my $month3 = $month_ref->[$mon3];
1484 136         440 $dates->{tomorrow} = _fmt_date ($sep, $order, $yr3, $month3, $day3);
1485              
1486             DBUG_PRINT (" DATES ($day)", "LAST: %s, NOW: %s, NEXT: %s",
1487 136         1008 $dates->{yesterday}, $dates->{today}, $dates->{tomorrow});
1488              
1489 136 50 66     41658 if ( $prev->{today} && $prev->{today} ne $dates->{today} ) {
1490 0         0 $what_changed = 1; # The date changed ...
1491             }
1492              
1493             # -------------------------------------------------------------------------
1494             # Get the desired months ... ($mon == 0..11)
1495 136         590 $dates->{this_month} = $month_ref->[$mon];
1496 136 50       773 $dates->{last_month} = ( $mon == 0 ) ? $month_ref->[11] : $month_ref->[$mon - 1];
1497 136 50       725 $dates->{next_month} = ( $mon == 11 ) ? $month_ref->[0] : $month_ref->[$mon + 1];
1498              
1499             DBUG_PRINT (" MONTHS ($mon)", "LAST: %s, NOW: %s, NEXT: %s",
1500 136         927 $dates->{last_month}, $dates->{this_month}, $dates->{next_month});
1501              
1502             # -------------------------------------------------------------------------
1503             # Get the desired periods Year-Month ... ($mon == 0..11)
1504 136 50       33484 my $lyr = ( $mon == 0 ) ? ($yr - 1) : $yr;
1505 136 50       508 my $nyr = ( $mon == 11 ) ? ($yr + 1) : $yr;
1506 136         718 $dates->{this_period} = _fmt_period ($sep, $order, $yr, $dates->{this_month});
1507 136         407 $dates->{last_period} = _fmt_period ($sep, $order, $lyr, $dates->{last_month});
1508 136         431 $dates->{next_period} = _fmt_period ($sep, $order, $nyr, $dates->{next_month});
1509              
1510             DBUG_PRINT ("PERIODS ($mon)", "LAST: %s, NOW: %s, NEXT: %s",
1511 136         837 $dates->{last_period}, $dates->{this_period}, $dates->{next_period});
1512              
1513             # -------------------------------------------------------------------------
1514              
1515 136 50 66     33211 if ( $prev->{this_month} && $prev->{this_month} ne $dates->{this_month} ) {
1516 0         0 $what_changed = 2; # The month & periods changed ...
1517             }
1518              
1519             # -------------------------------------------------------------------------
1520             # Get the desired years ...
1521 136         943 $dates->{this_year} = sprintf ("%04d", $yr);
1522 136         655 $dates->{last_year} = sprintf ("%04d", $yr - 1);
1523 136         554 $dates->{next_year} = sprintf ("%04d", $yr + 1);
1524              
1525             DBUG_PRINT (" YEARS", "LAST: %s, NOW: %s, NEXT: %s",
1526 136         659 $dates->{last_year}, $dates->{this_year}, $dates->{next_year});
1527              
1528 136 50 66     33632 if ( $prev->{this_year} && $prev->{this_year} ne $dates->{this_year} ) {
1529 0         0 $what_changed = 3; # The year changed ...
1530             }
1531              
1532             # -------------------------------------------------------------------------
1533             # Get the miscellanious vars ...
1534 136         624 $dates->{dow} = $week_day_ref->[$dow]; # 1..7 or spelled out.
1535 136         439 $dates->{doy} = $doy + 1; # 1..365 normal, 1..366 in leap years.
1536 136         435 $dates->{dom} = $day; # 1..31, range based on month.
1537              
1538             DBUG_PRINT (" MISC", " DOW: %s, DOY: %d, DOM: %d",
1539 136         713 $dates->{dow}, $dates->{doy}, $dates->{dom});
1540              
1541 136         32385 DBUG_RETURN ($what_changed);
1542             }
1543              
1544             # ==============================================================
1545              
1546             =item change_special_date_vars ( $timestamp, $date_opts_ref, $date_hash_ref )
1547              
1548             Same as L except it uses the specified date/time to
1549             convert.
1550              
1551             =cut
1552              
1553             sub change_special_date_vars
1554             {
1555 1     1 1 6 DBUG_ENTER_FUNC (@_);
1556 1         737 my $timestamp = shift;
1557 1         3 my $date_opts = shift;
1558 1         3 my $dates = shift;
1559              
1560             # Special flag for special handling ... (undocumented)
1561 1         5 local $date_opts->{timestamp} = $timestamp;
1562              
1563             # Forces all dates to use the specified date/time
1564 1         7 set_special_date_vars ($date_opts, $dates);
1565              
1566 1         349 DBUG_VOID_RETURN ();
1567             }
1568              
1569             # ==============================================================
1570             # For formatting the full dates ...
1571              
1572             sub _fmt_date
1573             {
1574 408     408   737 my $sep = shift;
1575 408         676 my $order = shift;
1576 408         681 my $year = shift;
1577 408         767 my $month = shift; # 1..12 or the name.
1578 408         689 my $day = shift; # 1..31
1579              
1580 408         708 my $dt;
1581 408 100       1214 if ( $order == 1 ) {
    100          
1582             # MM-DD-YYYY format
1583 12         58 $dt = sprintf ("%s%s%02d%s%04d", $month, $sep, $day, $sep, $year);
1584             } elsif ( $order == 2 ) {
1585             # DD-MM-YYYY format
1586 12         55 $dt = sprintf ("%02d%s%s%s%04d", $day, $sep, $month, $sep, $year);
1587             } else {
1588             # YYYY-MM-DD order ...
1589 384         1744 $dt = sprintf ("%04d%s%s%s%02d", $year, $sep, $month, $sep, $day);
1590             }
1591              
1592 408         1490 return ($dt);
1593             }
1594              
1595             # ==============================================================
1596             # Formatting to be "year-month" or "month-year".
1597              
1598             sub _fmt_period
1599             {
1600 408     408   840 my $sep = shift;
1601 408         649 my $order = shift;
1602 408         696 my $year = shift;
1603 408         719 my $month = shift; # 1..12 or the name.
1604              
1605 408         645 my $dt;
1606 408 100 100     1719 if ( $order == 1 || $order == 2 ) {
1607             # MM-YYYY format
1608 24         114 $dt = sprintf ("%s%s%04d", $month, $sep, $year);
1609             } else {
1610             # YYYY-MM format
1611 384         1087 $dt = sprintf ("%04d%s%s", $year, $sep, $month);
1612             }
1613              
1614 408         1397 return ($dt);
1615             }
1616              
1617             # ==============================================================
1618              
1619             =back
1620              
1621             =head1 COPYRIGHT
1622              
1623             Copyright (c) 2007 - 2026 Curtis Leach. All rights reserved.
1624              
1625             This program is free software. You can redistribute it and/or modify it under
1626             the same terms as Perl itself.
1627              
1628             =head1 SEE ALSO
1629              
1630             L - The main user of this module. It defines the Config object.
1631              
1632             L - Handles date parsing for get_date().
1633              
1634             L - Handles the parsing of the config file.
1635              
1636             L - Provides some sample config files and commentary.
1637              
1638             =cut
1639              
1640             # ==============================================================
1641             #required if module is included w/ require command;
1642             1;
1643