File Coverage

blib/lib/Xcruciate/UnitConfig.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package Xcruciate::UnitConfig;
2              
3 2     2   49272 use Exporter;
  2         6  
  2         177  
4             @ISA = ('Exporter');
5             @EXPORT = qw();
6             our $VERSION = 0.21;
7              
8 2     2   12 use strict;
  2         4  
  2         71  
9 2     2   12 use warnings;
  2         3  
  2         66  
10 2     2   10 use Carp;
  2         5  
  2         135  
11 2     2   112 use Xcruciate::Utils 0.21;
  0            
  0            
12              
13             =head1 NAME
14              
15             Xcruciate::UnitConfig - OO API for reading xacerbate/xteriorize unit config files.
16              
17             =head1 SYNOPSIS
18              
19             my $config=Xcruciate::UnitConfig->new('unit.conf');
20              
21             my $cm=$config->chime_multiplier;
22              
23             my @mdf=$config->modifiable_data_files;
24              
25              
26             =head1 DESCRIPTION
27              
28             Xcruciate::UnitConfig is part of the Xcruciate project (F). It provides an
29             OO interface to an xacerbate/xteriorize unit configuration file.
30              
31             Accessor functions return scalars for entry types and lists for entry types.
32             The values returned are those found in the config file, with the exception of yes_no datatypes
33             which are converted into perlish boolean values (1 or 0).
34              
35             All xte*() methods will return an undefined value unless the xte_start entry is set.
36              
37             The entry() method can be used to access any entry including unofficial extensions. However,
38             it is safer to use the named methods where possible, to avoid inventing unofficial extensions through typos.
39              
40             =head1 AUTHOR
41              
42             Mark Howe, Emelonman@cpan.orgE
43              
44             =head2 EXPORT
45              
46             None
47              
48             =cut
49              
50             #Records fields:
51             # scalar/list
52             # Optional? (1 means 'yes')
53             # data type
54             # data type specific fields:
55             # min, max for numbers
56             # required permissions for files/directories
57              
58             my $xac_settings = {
59             'accept_from',
60             [ 'scalar', 1, 'word' ],
61             'access_log_path',
62             [ 'scalar', 0, 'abs_create', 'rw' ],
63             'backup_path',
64             [ 'scalar', 1, 'abs_create', 'rw' ],
65             'boot_log_path',
66             [ 'scalar', 0, 'abs_create', 'rw' ],
67             'chime_multiplier',
68             [ 'scalar', 0, 'integer', 2 ],
69             'clean_states_path',
70             [ 'scalar', 0, 'path' ],
71             'config_type',
72             [ 'scalar', 0, 'word' ],
73             'current_states_path',
74             [ 'scalar', 0, 'path' ],
75             'debug_level',
76             [ 'scalar', 0, 'debug_list' ],
77             'debug_log_path',
78             [ 'scalar', 0, 'abs_create', 'rw' ],
79             'error_log_path',
80             [ 'scalar', 0, 'abs_create', 'rw' ],
81             'log_file_paths',
82             [ 'list', 1, 'abs_create', 'rw' ],
83             'max_buffer_size',
84             [ 'scalar', 0, 'integer', 1 ],
85             'max_connections',
86             [ 'scalar', 0, 'integer', 1 ],
87             'max_input_length',
88             [ 'scalar', 0, 'integer', 1 ],
89             'modifiable_data_files',
90             [ 'list', 1, 'abs_file', 'r', 'xml', 'clean_states_path' ],
91             'modifiable_transform_files',
92             [ 'list', 1, 'abs_file', 'r', 'xml', 'clean_states_path' ],
93             'path',
94             [ 'scalar', 1, 'abs_dir', 'r' ],
95             'peel_multiplier',
96             [ 'scalar', 0, 'integer', 2 ],
97             'persistent_modifiable_files',
98             [ 'list', 1, 'abs_file', 'r', 'xml', 'clean_states_path' ],
99             'port',
100             [ 'scalar', 0, 'integer', 1, 65535 ],
101             'server_ip',
102             [ 'scalar', 0, 'ip' ],
103             'start_xte',
104             [ 'scalar', 0, 'yes_no' ],
105             'startup_commands',
106             [ 'list', 1, 'abs_file', 'r', 'xml', 'startup_files_path' ],
107             'startup_files_path',
108             [ 'scalar', 1, 'path' ],
109             'tick_interval',
110             [ 'scalar', 0, 'duration' ],
111             'transform_xsl',
112             [ 'scalar', 0, 'abs_file', 'r', 'xsl' ],
113             'very_persistent_modifiable_files',
114             [ 'list', 1, 'abs_file', 'r', 'xml', 'clean_states_path' ],
115             };
116              
117             my $xte_settings = {
118             'xte_captcha_bgcolors', [ 'list', 0, 'hexbyte' ],
119             'xte_captcha_colors', [ 'list', 0, 'hexbyte' ],
120             'xte_captcha_height', [ 'scalar', 0, 'integer', 10, 512 ],
121             'xte_captcha_max_angle', [ 'scalar', 0, 'integer', 0, 90 ],
122             'xte_captcha_max_line_thickness', [ 'scalar', 0, 'integer', 1, 10 ],
123             'xte_captcha_max_lines', [ 'scalar', 0, 'integer', 1, 10 ],
124             'xte_captcha_min_line_thickness', [ 'scalar', 0, 'integer', 1, 10 ],
125             'xte_captcha_min_lines', [ 'scalar', 0, 'integer', 0, 10 ],
126             'xte_captcha_particle_count', [ 'scalar', 0, 'integer', 0, 1000 ],
127             'xte_captcha_particle_size', [ 'scalar', 0, 'integer', 1, 10 ],
128             'xte_captcha_styles', [ 'list', 0, 'captchastyle' ],
129             'xte_captcha_ttfont_size', [ 'scalar', 0, 'integer', 8, 72 ],
130             'xte_captcha_ttfonts', [ 'list', 0, 'abs_file', 'r' ],
131             'xte_captcha_width', [ 'scalar', 0, 'integer', 20, 1024 ],
132             'xte_check_for_waiting', [ 'scalar', 1, 'integer', 0 ],
133             'xte_cidr_allow', [ 'list', 1, 'cidr' ],
134             'xte_cidr_deny', [ 'list', 1, 'cidr' ],
135             'xte_docroot', [ 'scalar', 0, 'abs_dir', 'rw' ],
136             'xte_enable_captcha', [ 'scalar', 1, 'yes_no' ],
137             'xte_enable_email', [ 'scalar', 1, 'yes_no' ],
138             'xte_enable_file_writing', [ 'scalar', 1, 'yes_no' ],
139             'xte_enable_fop', [ 'scalar', 1, 'yes_no' ],
140             'xte_enable_json', [ 'scalar', 1, 'yes_no' ],
141             'xte_enable_mxmlc', [ 'scalar', 1, 'yes_no' ],
142             'xte_enable_static_serving', [ 'scalar', 1, 'yes_no' ],
143             'xte_enable_uploads', [ 'scalar', 1, 'yes_no' ],
144             'xte_enable_xmlroff', [ 'scalar', 1, 'yes_no' ],
145             'xte_error_i18n', [ 'scalar', 0, 'abs_file', 'r' ],
146             'xte_from_address', [ 'scalar', 0, 'email' ],
147             'xte_gateway_auth', [ 'scalar', 0, 'word' ],
148             'xte_group', [ 'scalar', 1, 'word' ],
149             'xte_image_sizes', [ 'list', 0, 'imagesize' ],
150             'xte_i18n_list', [ 'list', 1, 'abs_file', 'r', 'xml' ],
151             'xte_server_ip', [ 'scalar', 0, 'ip' ],
152             'xte_log_file', [ 'scalar', 1, 'abs_create', 'rw' ],
153             'xte_log_level', [ 'scalar', 1, 'integer', 0, 4 ],
154             'xte_max_image_size', [ 'scalar', 1, 'imagesize' ],
155             'xte_max_requests', [ 'scalar', 1, 'integer', 1 ],
156             'xte_max_servers', [ 'scalar', 1, 'integer', 1 ],
157             'xte_max_spare_servers', [ 'scalar', 1, 'integer', 1 ],
158             'xte_max_upload_size', [ 'scalar', 1, 'integer', 1 ],
159             'xte_mimetype_path', [ 'scalar', 1, 'abs_file', 'r' ],
160             'xte_min_servers', [ 'scalar', 1, 'integer', 1 ],
161             'xte_min_spare_servers', [ 'scalar', 1, 'integer', 1 ],
162             'xte_port', [ 'scalar', 0, 'integer', 1, 65535 ],
163             'xte_post_max', [ 'scalar', 0, 'integer', 1 ],
164             'xte_report_benchmarks', [ 'scalar', 1, 'yes_no' ],
165             'xte_site_language', [ 'scalar', 0, 'language' ],
166             'xte_smtp_charset', [ 'scalar', 0 ],
167             'xte_smtp_encoding', [ 'scalar', 0 ],
168             'xte_smtp_host', [ 'scalar', 0, 'ip' ],
169             'xte_smtp_port', [ 'scalar', 0, 'integer', 1, 65535 ],
170             'xte_static_directories', [ 'list', 1, 'word' ],
171             'xte_splurge_input', [ 'scalar', 1, 'yes_no' ],
172             'xte_splurge_output', [ 'scalar', 1, 'yes_no' ],
173             'xte_temporary_file_path', [ 'scalar', 0, 'abs_create', 'rw' ],
174             'xte_user', [ 'scalar', 1, 'word' ],
175             'xte_use_xca', [ 'scalar', 0, 'yes_no' ],
176             'xte_xac_timeout', [ 'scalar', 0, 'duration' ]
177             };
178              
179             my $xca_settings = {
180             'xca_captcha_timeout',
181             [ 'scalar', 0, 'duration' ],
182             'xca_castes',
183             [ 'list', 1, 'word' ],
184             'xca_confirmation_timeout',
185             [ 'scalar', 0, 'duration' ],
186             'xca_date_formats',
187             [ 'list', 1, 'dateformat' ],
188             'xca_datetime_formats',
189             [ 'list', 1, 'dateformat' ],
190             'xca_default_email_contact',
191             [ 'scalar', 0, 'yes_no' ],
192             'xca_default_pm_contact',
193             [ 'scalar', 0, 'yes_no' ],
194             'xte_enable_captcha',
195             [ 'scalar', 1, 'yes_no' ],
196             'xte_enable_email',
197             [ 'scalar', 1, 'yes_no' ],
198             'xte_enable_file_writing',
199             [ 'scalar', 1, 'yes_no' ],
200             'xte_enable_fop',
201             [ 'scalar', 1, 'yes_no' ],
202             'xte_enable_json',
203             [ 'scalar', 1, 'yes_no' ],
204             'xte_enable_mxmlc',
205             [ 'scalar', 1, 'yes_no' ],
206             'xte_enable_xmlroff',
207             [ 'scalar', 1, 'yes_no' ],
208             'xca_favicon',
209             [ 'scalar', 0, 'url' ],
210             'xca_failed_login_lockout',
211             [ 'scalar', 0, 'integer' ],
212             'xca_failed_login_lockout_reset',
213             [ 'scalar', 0, 'duration' ],
214             'xca_from_address',
215             [ 'scalar', 0, 'email' ],
216             'xca_gateway_authenticate_timeout',
217             [ 'scalar', 0, 'duration' ],
218             'xca_http_domain',
219             [ 'scalar', 0, 'word' ],
220             'xca_manual_registration_activation',
221             [ 'scalar', 0, 'yes_no' ],
222             'xca_path',
223             [ 'scalar', 0, 'abs_dir', 'r' ],
224             'xca_profile_template_path',
225             [ 'scalar', 0, 'abs_file', 'r', 'xml' ],
226             'xca_script_debug_caste',
227             [ 'scalar', 0, 'word' ],
228             'xca_session_timeout',
229             [ 'scalar', 0, 'duration' ],
230             'xca_site_path',
231             [ 'scalar', 0, 'abs_dir', 'rw' ],
232             'xca_time_offset',
233             [ 'scalar', 0, 'timeoffset' ],
234             'xca_unique_registration_email',
235             [ 'scalar', 0, 'yes_no' ]
236             };
237              
238             my $stop_settings = {
239             'server_ip' => 1,
240             'port' => 1,
241             'start_xte' => 1,
242             'xte_server_ip' => 1,
243             'xte_port' => 1
244             };
245              
246             =head1 CREATOR METHODS
247              
248             =head2 new(config_file_path,verbose,stop_only [,lax])
249              
250             Creates and returns an Xcruciate::UnitConfig object which can then be queried.
251             If the optional verbose argument is perlishly true it will show its working to STDOUT. If
252             the stop_only argument is perlishly true it will only bother about the information needed
253             to stop processes (ie hosts and ports).
254              
255             By default it looks for configuration errors and die noisily if it finds any.
256             This is useful behaviour for management scripts - continuing to set up server daemons
257             on the basis of broken configurations is not best practice. If the fourth argument (lax) is
258             perlishly true, errors will be signalled but the possibly broken object will be created anyway.
259             This is useful behaviour for development purposes, especially when changing config options, but
260             should not be used in a production setting. Note that even the lax version of new() will die
261             if the config file does not look anything like a config file.
262              
263             =cut
264              
265             sub new {
266             my $class = shift;
267             my $path = shift;
268             my $verbose = shift || 0;
269             my $stop_only = shift;
270             my $stop_only_parse_text = "";
271             $stop_only_parse_text = " (hosts and ports only)" if $stop_only;
272             my $lax = shift || 0;
273             my $self = {};
274              
275             # Check that there's a file at the end of the config file option
276             local_croak(
277             Xcruciate::Utils::check_path( 'unit config file', $path, 'r', 1 ) );
278              
279             # Parse config file
280             print "Attempting to parse unit config file$stop_only_parse_text... "
281             if $verbose;
282             my $parser = XML::LibXML->new();
283             my $xac_dom = $parser->parse_file($path);
284             print "done\n" if $verbose;
285              
286             #Bail out if config file isn't even close to what is expected
287             my @config = $xac_dom->findnodes("/config/scalar");
288             croak
289             "Config file doesn't look anything like a config file - 'xcruciate file_help' for some clues"
290             unless $config[0];
291             my @config_type =
292             $xac_dom->findnodes("/config/scalar[\@name='config_type']/text()");
293             croak "config_type entry not found in unit config file"
294             unless $config_type[0];
295             my $config_type = $config_type[0]->toString;
296             croak
297             "config_type in unit config file is '$config_type' (should be 'unit') - are you confusing xcruciate and unit config files?"
298             unless $config_type eq 'unit';
299             my @config_path =
300             $xac_dom->findnodes("/config/scalar[\@name='path']/text()");
301             my $config_path = $config_path[0];
302             $config_path = $config_path->toString if $config_path;
303              
304             # Work through config options in config file
305             my @errors = ();
306             foreach my $entry (
307             $xac_dom->findnodes(
308             "/config/*[(local-name() = 'scalar') or (local-name() = 'list')]")
309             )
310             {
311              
312             # Does it have a name attribute?
313             push @errors,
314             sprintf( "No name attribute for element '%s'", $entry->nodeName )
315             unless $entry->hasAttribute('name');
316             my $entry_record =
317             $xac_settings->{ $entry->getAttribute('name') }
318             || $xte_settings->{ $entry->getAttribute('name') }
319             || $xca_settings->{ $entry->getAttribute('name') };
320              
321             #Skip checks if stop_only and this entry isn't needed to stop
322             next
323             if ( $stop_only
324             and not( $stop_settings->{ $entry->getAttribute('name') } ) );
325              
326             # Warn about entries in config file that are not defined, but continue.
327             if ( not defined $entry_record ) {
328             carp "WARNING: Unknown unit config entry '"
329             . ( $entry->getAttribute('name') ) . "'";
330             }
331             elsif ( not( $entry->nodeName eq $entry_record->[0] ) ) {
332              
333             # Is it a scalar or list as expected?
334             push @errors,
335             sprintf(
336             "Entry called %s should be a %s not a %s",
337             $entry->getAttribute('name'),
338             $entry_record->[0], $entry->nodeName
339             );
340             }
341             elsif ( ( not $entry->textContent )
342             and
343             ( ( not $entry_record->[1] ) or $entry->textContent !~ /^\s*$/s ) )
344             {
345              
346             #Entry, but value missing and not optional
347             push @errors,
348             sprintf( "Entry called %s requires a value",
349             $entry->getAttribute('name') );
350             }
351             elsif (
352             ( $entry->nodeName eq 'scalar' )
353             and $entry_record->[2]
354             and ( ( not $entry_record->[1] )
355             or $entry->textContent !~ /^\s*$/s
356             or $entry->textContent )
357             )
358             {
359              
360             #Produce path for this field
361             my $entry_path = $config_path;
362             if ( ( $entry_record->[2] eq 'abs_file' ) and $entry_record->[5] ) {
363             my @entry_config_path = $xac_dom->findnodes(
364             "/config/*[\@name='$entry_record->[5]']/text()");
365             $entry_path .= '/' . $entry_config_path[0]->toString
366             if $entry_config_path[0];
367             }
368              
369             #Entry is a scalar - type check
370             push @errors,
371             Xcruciate::Utils::type_check( $entry_path,
372             $entry->getAttribute('name'),
373             $entry->textContent, $entry_record );
374             }
375             elsif ( ( $entry->nodeName eq 'list' ) and $entry_record ) {
376              
377             #Entry is a list...
378              
379             #Non-optional list entries require at least one item
380             my @items = $entry->findnodes('item/text()');
381             push @errors,
382             sprintf( "Entry called %s requires at least one item",
383             $entry->getAttribute('name') )
384             if ( ( not $entry_record->[2] ) and ( not @items ) );
385              
386             #Produce path for this field
387             my $entry_path = $config_path;
388             if ( ( $entry_record->[2] eq 'abs_file' ) and $entry_record->[5] ) {
389             my @entry_config_path = $xac_dom->findnodes(
390             "/config/*[\@name='$entry_record->[5]']/text()");
391             $entry_path .= '/' . $entry_config_path[0]->toString
392             if $entry_config_path[0];
393             }
394              
395             # Type check each item in list
396             my $count = 1;
397             foreach my $item (@items) {
398             push @errors,
399             Xcruciate::Utils::type_check( $entry_path,
400             $entry->getAttribute('name'),
401             $item->textContent, $entry_record, $count );
402             $count++;
403             }
404             }
405              
406             # Duplicate entries not allowed
407             push @errors,
408             sprintf( "Duplicate entry called %s", $entry->getAttribute('name') )
409             if defined $self->{ $entry->getAttribute('name') };
410              
411             # Add entry value to object hash
412             if ( $entry->nodeName eq 'scalar' ) {
413             $self->{ $entry->getAttribute('name') } = $entry->textContent;
414             }
415             else {
416             $self->{ $entry->getAttribute('name') } = []
417             unless defined $self->{ $entry->getAttribute('name') };
418             foreach my $item ( $entry->findnodes('item/text()') ) {
419             push @{ $self->{ $entry->getAttribute('name') } },
420             $item->textContent;
421             }
422             }
423             }
424              
425             # Report missing entries
426             foreach my $entry ( keys %{$xac_settings} ) {
427             next if ( $stop_only and not( $stop_settings->{$entry} ) );
428             push @errors, sprintf( "No xacerbate entry called %s", $entry )
429             unless ( ( defined $self->{$entry} )
430             or ( $xac_settings->{$entry}->[1] ) );
431             }
432             if ( ( defined $self->{start_xte} ) and ( $self->{start_xte} eq "yes" ) ) {
433             foreach my $entry ( keys %{$xte_settings} ) {
434             next if ( $stop_only and not( $stop_settings->{$entry} ) );
435             push @errors, sprintf( "No xteriorize entry called %s", $entry )
436             unless ( ( defined $self->{$entry} )
437             or ( $xte_settings->{$entry}->[1] ) );
438             }
439             if ( ( defined $self->{xte_use_xca} )
440             and ( $self->{xte_use_xca} eq "yes" ) )
441             {
442             foreach my $entry ( keys %{$xca_settings} ) {
443             next if ( $stop_only and not( $stop_settings->{$entry} ) );
444             push @errors, sprintf( "No xcathedra entry called %s", $entry )
445             unless ( ( defined $self->{$entry} )
446             or ( $xca_settings->{$entry}->[1] ) );
447             }
448             }
449             }
450              
451             # And the final scores are...
452             if ( @errors and $lax ) {
453             if ($verbose) {
454             foreach (@errors) {
455             print "ERROR: $_\n";
456             }
457             }
458             carp
459             "WARNING: Errors in unit config file, but lax flag set, so proceeding anyway. This could be exciting...\n";
460             bless( $self, $class );
461             return $self;
462             }
463             elsif (@errors) {
464             foreach (@errors) {
465             print "ERROR: $_\n";
466             }
467             croak
468             "Errors in unit config file - cannot continue (force at your own risk using --lax flag)";
469             }
470             else {
471             bless( $self, $class );
472             return $self;
473             }
474             }
475              
476             =head1 UTILITY METHODS
477              
478             =head2 xac_file_format_description()
479              
480             Returns multi-lined human-friendly description of the xac config file
481              
482             =cut
483              
484             sub xac_file_format_description {
485             my $self = shift;
486             my $ret = '';
487             foreach my $entry (
488             sort ( keys %{$xac_settings}, keys %{$xte_settings},
489             keys %{$xca_settings} ) )
490             {
491             my $record =
492             $xac_settings->{$entry}
493             || $xte_settings->{$entry}
494             || $xca_settings->{$entry};
495             $ret .= "$entry (";
496             $ret .= "optional " if $record->[1];
497             $ret .= "$record->[0])";
498             if ( not $record->[2] ) {
499             }
500             elsif ( ( $record->[2] eq 'integer' ) or ( $record->[2] eq 'float' ) ) {
501             $ret .= " - $record->[2]";
502             $ret .= " >= $record->[3]" if defined $record->[3];
503             $ret .= " and <= $record->[4]" if defined $record->[4];
504             }
505             elsif ( $record->[2] eq 'ip' ) {
506             $ret .= " - ip address";
507             }
508             elsif ( $record->[2] eq 'word' ) {
509             $ret .= " - word (ie no whitespace)";
510             }
511             elsif ( $record->[2] eq 'path' ) {
512             $ret .= " - path (currently a word)";
513             }
514             elsif ( $record->[2] eq 'cidr' ) {
515             $ret .= " - an ip range in CIDR format";
516             }
517             elsif ( $record->[2] eq 'dateformat' ) {
518             $ret .= " - date format";
519             }
520             elsif ( $record->[2] eq 'url' ) {
521             $ret .= " - url (starts with http or /)";
522             }
523             elsif ( $record->[2] eq 'duration' ) {
524             $ret .= " - duration in XML Schema format";
525             }
526             elsif ( $record->[2] eq 'timeoffset' ) {
527             $ret .= " - timezone offset (-11 to 12)";
528             }
529             elsif ( $record->[2] eq 'xml_leaf' ) {
530             $ret .= " - filename with an xml suffix";
531             }
532             elsif ( $record->[2] eq 'xsl_leaf' ) {
533             $ret .= " - filename with an xsl suffix";
534             }
535             elsif ( $record->[2] eq 'yes_no' ) {
536             $ret .= " - 'yes' or 'no'";
537             }
538             elsif ( $record->[2] eq 'email' ) {
539             $ret .= " - email address";
540             }
541             elsif ( $record->[2] eq 'debug_list' ) {
542             $ret .=
543             " - comma-separated list of debugging options (or 'all'/'none')";
544             }
545             elsif ( $record->[2] eq 'abs_dir' ) {
546             $ret .= " - absolute directory path with $record->[3] permissions";
547             }
548             elsif ( $record->[2] eq 'abs_file' ) {
549             $ret .= " - absolute file path with $record->[3] permissions";
550             }
551             elsif ( $record->[2] eq 'abs_create' ) {
552             $ret .=
553             " - absolute file path with $record->[3] permissions for directory";
554             }
555             else { $ret .= " - UNKNOWN TYPE $record->[2]" }
556             $ret .= "\n";
557             }
558             return $ret;
559             }
560              
561             =head1 ACCESSOR METHODS
562              
563             =head2 accept_from()
564              
565             Returns the ip range from which connections are accepted.
566              
567             =cut
568              
569             sub accept_from {
570             my $self = shift;
571             return $self->{accept_from};
572             }
573              
574             =head2 access_log_path()
575              
576             Returns the path to the access log.
577              
578             =cut
579              
580             sub access_log_path {
581             my $self = shift;
582             return $self->{access_log_path};
583             }
584              
585             =head2 backup_path()
586              
587             Returns the path to which the backup zip file should be written.
588              
589             =cut
590              
591             sub backup_path {
592             my $self = shift;
593             return $self->{backup_path};
594             }
595              
596             =head2 boot_log_path()
597              
598             Returns the path to the boot log.
599              
600             =cut
601              
602             sub boot_log_path {
603             my $self = shift;
604             return $self->{boot_log_path};
605             }
606              
607             =head2 chime_multiplier()
608              
609             Returns the number of ticks per chime
610              
611             =cut
612              
613             sub chime_multiplier {
614             my $self = shift;
615             return $self->{chime_multiplier};
616             }
617              
618             =head2 clean_states_path()
619              
620             Returns the path to the directory containing clean versions of modifiable files.
621              
622             =cut
623              
624             sub clean_states_path {
625             my $self = shift;
626             return $self->{clean_states_path};
627             }
628              
629             =head2 config_type()
630              
631             Returns the type of config file, which in this case should always be 'unit'.
632              
633             =cut
634              
635             sub config_type {
636             my $self = shift;
637             return $self->{config_type};
638             }
639              
640             =head2 current_states_path()
641              
642             Returns the path to the directory containing current versions of modifiable files.
643              
644             =cut
645              
646             sub current_states_path {
647             my $self = shift;
648             return $self->{current_states_path};
649             }
650              
651             =head2 debug_level()
652              
653             Returns the xacerbate debug level.
654              
655             =cut
656              
657             sub debug_level {
658             my $self = shift;
659             return $self->{debug_level};
660             }
661              
662             =head2 debug_log_path()
663              
664             Returns the path to the xacerbate debug log.
665              
666             =cut
667              
668             sub debug_log_path {
669             my $self = shift;
670             return $self->{debug_log_path};
671             }
672              
673             =head2 entry(name)
674              
675             Returns the entry called name. Lists will be returned by reference. Use named methods in preference to this one where possible.
676              
677             =cut
678              
679             sub entry {
680             my $self = shift;
681             my $name = shift;
682             return $self->{$name};
683             }
684              
685             =head2 error_log_path()
686              
687             Returns the path to the xacerbate error log.
688              
689             =cut
690              
691             sub error_log_path {
692             my $self = shift;
693             return $self->{error_log_path};
694             }
695              
696             =head2 log_file_paths()
697              
698             Returns a list of locations to which xacerbate application code can write logs.
699              
700             =cut
701              
702             sub log_file_paths {
703             my $self = shift;
704             return @{ $self->{log_file_paths} || [] };
705             }
706              
707             =head2 max_buffer_size()
708              
709             Returns the maximum buffer size allowed for any one connection.
710              
711             =cut
712              
713             sub max_buffer_size {
714             my $self = shift;
715             return $self->{max_buffer_size};
716             }
717              
718             =head2 max_connections()
719              
720             Returns the maximum number of connections accepted by xacerbate.
721              
722             =cut
723              
724             sub max_connections {
725             my $self = shift;
726             return $self->{max_connections};
727             }
728              
729             =head2 max_input_length()
730              
731             Returns the maximum character length of each XML document.
732              
733             =cut
734              
735             sub max_input_length {
736             my $self = shift;
737             return $self->{max_input_length};
738             }
739              
740             =head2 modifiable_data_files()
741              
742             Returns a list of modifiable data filenames.
743              
744             =cut
745              
746             sub modifiable_data_files {
747             my $self = shift;
748             return @{ $self->{modifiable_data_files} || [] };
749             }
750              
751             =head2 modifiable_transform_files()
752              
753             Returns a list of modifiable XSL filenames.
754              
755             =cut
756              
757             sub modifiable_transform_files {
758             my $self = shift;
759             return @{ $self->{modifiable_transform_files} || [] };
760             }
761              
762             =head2 path()
763              
764             Returns the path that is prefixed by xacerbate to various other settings.
765              
766             =cut
767              
768             sub path {
769             my $self = shift;
770             return $self->{path};
771             }
772              
773             =head2 peel_multiplier()
774              
775             Returns the number of chimes per peel.
776              
777             =cut
778              
779             sub peel_multiplier {
780             my $self = shift;
781             return $self->{peel_multiplier};
782             }
783              
784             =head2 port()
785              
786             Returns the port used by xacerbate.
787              
788             =cut
789              
790             sub port {
791             my $self = shift;
792             return $self->{port};
793             }
794              
795             =head2 persistent_modifiable_files()
796              
797             Returns a list of modifiable files that should persist from session to session, ie they are not overwritten from clean on startup.
798              
799             =cut
800              
801             sub persistent_modifiable_files {
802             my $self = shift;
803             return @{ $self->{persistent_modifiable_files} || [] };
804             }
805              
806             =head2 prepend_to_path(path)
807              
808             Expects an absolute or relative path. If the path is relative, and if there was a path entry in the config file, the path entry is prepended to the relative path. Otherwise the supplied path is returned unchanged.
809              
810             =cut
811              
812             sub prepend_to_path {
813             my $self = shift;
814             my $supplied_path = shift;
815             my $config_path = $self->path;
816             if ( $config_path and $supplied_path !~ m!^/! ) {
817             return "$config_path/$supplied_path";
818             }
819             else {
820             return $supplied_path;
821             }
822             }
823              
824             =head2 server_ip()
825              
826             Returns the address on which xacerbate listens.
827              
828             =cut
829              
830             sub server_ip {
831             my $self = shift;
832             return $self->{server_ip};
833             }
834              
835             =head2 start_xte()
836              
837             Returns start_xte value (true or false), ie whether xteriorize should be started alongside xacerbate.
838              
839             =cut
840              
841             sub start_xte {
842             my $self = shift;
843             if ( lc( $self->{start_xte} ) eq 'yes' ) {
844             return 1;
845             }
846             else { return 0 }
847             }
848              
849             =head2 startup_commands()
850              
851             Returns a list of startup command filenames.
852              
853             =cut
854              
855             sub startup_commands {
856             my $self = shift;
857             return @{ $self->{startup_commands} || [] };
858             }
859              
860             =head2 startup_files_path()
861              
862             Returns the path to the startup command files.
863              
864             =cut
865              
866             sub startup_files_path {
867             my $self = shift;
868             return $self->{startup_files_path};
869             }
870              
871             =head2 tick_interval()
872              
873             Returns the interval between ticks (or twice the interval between a tick and a tock).
874              
875             =cut
876              
877             sub tick_interval {
878             my $self = shift;
879             return $self->{tick_interval};
880             }
881              
882             =head2 transform_xsl()
883              
884             Returns the name of the main transform file used by xacerbate.
885              
886             =cut
887              
888             sub transform_xsl {
889             my $self = shift;
890             return $self->{transform_xsl};
891             }
892              
893             =head2 very_persistent_modifiable_files()
894              
895             Returns a list of modifiable files that should persist from session to session, even when xcruciate is reset (they will still be reinitialised by a factory reset).
896              
897             =cut
898              
899             sub very_persistent_modifiable_files {
900             my $self = shift;
901             return @{ $self->{very_persistent_modifiable_files} || [] };
902             }
903              
904             =head2 xca_captcha_timeout()
905              
906             Returns the time limit after which captchas time out
907              
908             =cut
909              
910             sub xca_captcha_timeout {
911             my $self = shift;
912             if ( ( lc( $self->{start_xte} ) eq 'yes' )
913             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
914             {
915             return $self->{xca_captcha_timeout};
916             }
917             else {
918             return undef;
919             }
920             }
921              
922             =head2 xca_castes()
923              
924             Returns a list of site-specific castes, in ascending order of rights.
925              
926             =cut
927              
928             sub xca_castes {
929             my $self = shift;
930             if ( ( lc( $self->{start_xte} ) eq 'yes' )
931             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
932             {
933             return @{ $self->{xca_castes} || [] };
934             }
935             else {
936             return undef;
937             }
938             }
939              
940             =head2 xca_confirmation_timeout()
941              
942             Returns the time limit after which confirmation codes time out.
943              
944             =cut
945              
946             sub xca_confirmation_timeout {
947             my $self = shift;
948             if ( ( lc( $self->{start_xte} ) eq 'yes' )
949             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
950             {
951             return $self->{xca_confirmation_timeout};
952             }
953             else {
954             return undef;
955             }
956             }
957              
958             =head2 xca_date_formats()
959              
960             Returns a list of date formats.
961              
962             =cut
963              
964             sub xca_date_formats {
965             my $self = shift;
966             if ( lc( ( $self->{start_xte} ) eq 'yes' )
967             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
968             {
969             return @{ $self->{xca_date_formats} || [] };
970             }
971             else {
972             return undef;
973             }
974             }
975              
976             =head2 xca_datetime_formats()
977              
978             Returns a list of datetime formats.
979              
980             =cut
981              
982             sub xca_datetime_formats {
983             my $self = shift;
984             if ( ( lc( $self->{start_xte} ) eq 'yes' )
985             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
986             {
987             return @{ $self->{xca_datetime_formats} || [] };
988             }
989             else {
990             return undef;
991             }
992             }
993              
994             =head2 xca_default_email_contact()
995              
996             Returns a flag signifying whether, by default, users accept contact via email.
997              
998             =cut
999              
1000             sub xca_default_email_contact {
1001             my $self = shift;
1002             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1003             and ( lc( $self->{xte_use_xca} ) eq 'yes' )
1004             and ( lc( $self->{xca_default_email_contact} ) eq 'yes' ) )
1005             {
1006             return 1;
1007             }
1008             else {
1009             return 0;
1010             }
1011             }
1012              
1013             =head2 xca_default_pm_contact()
1014              
1015             Returns a flag signifying whether, by default, users accept contact via pm.
1016              
1017             =cut
1018              
1019             sub xca_default_pm_contact {
1020             my $self = shift;
1021             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1022             and ( lc( $self->{xte_use_xca} ) eq 'yes' )
1023             and ( lc( $self->{xca_default_pm_contact} ) eq 'yes' ) )
1024             {
1025             return 1;
1026             }
1027             else {
1028             return 0;
1029             }
1030             }
1031              
1032             =head2 xca_failed_login_lockout()
1033              
1034             Returns the number of failed logins after which an account will be locked.
1035              
1036             =cut
1037              
1038             sub xca_failed_login_lockout {
1039             my $self = shift;
1040             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1041             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1042             {
1043             return $self->{xca_failed_login_lockout};
1044             }
1045             else {
1046             return undef;
1047             }
1048             }
1049              
1050             =head2 xca_failed_login_lockout_reset()
1051              
1052             Returns the time delay after which a locked account will be unlocked.
1053              
1054             =cut
1055              
1056             sub xca_failed_login_lockout_reset {
1057             my $self = shift;
1058             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1059             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1060             {
1061             return $self->{xca_failed_login_lockout_reset};
1062             }
1063             else {
1064             return undef;
1065             }
1066             }
1067              
1068             =head2 xca_favicon()
1069              
1070             Returns the url of the site favicon (either a fully-qualified url or a local, absolute url).
1071              
1072             =cut
1073              
1074             sub xca_favicon {
1075             my $self = shift;
1076             if ( lc( ( $self->{start_xte} ) eq 'yes' )
1077             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1078             {
1079             return $self->{xca_favicon};
1080             }
1081             else {
1082             return undef;
1083             }
1084             }
1085              
1086             =head2 xca_from_address()
1087              
1088             Returns the email address used for outgoing mail.
1089              
1090             =cut
1091              
1092             sub xca_from_address {
1093             my $self = shift;
1094             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1095             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1096             {
1097             return $self->{xca_from_address};
1098             }
1099             else {
1100             return undef;
1101             }
1102             }
1103              
1104             =head2 xca_gateway_authenticate_timeout()
1105              
1106             Returns the timeout for Xteriorize gateways authenticating with Xcathedra.
1107              
1108             =cut
1109              
1110             sub xca_gateway_authenticate_timeout {
1111             my $self = shift;
1112             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1113             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1114             {
1115             return $self->{xca_gateway_authenticate_timeout};
1116             }
1117             else {
1118             return undef;
1119             }
1120             }
1121              
1122             =head2 xca_http_domain()
1123              
1124             Returns the website domain.
1125              
1126             =cut
1127              
1128             sub xca_http_domain {
1129             my $self = shift;
1130             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1131             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1132             {
1133             return $self->{http_domain};
1134             }
1135             else {
1136             return undef;
1137             }
1138             }
1139              
1140             =head2 xca_manual_registration_activation()
1141              
1142             Returns a flag signifying whether manual admin approval of new user accounts is currently activated.
1143              
1144             =cut
1145              
1146             sub xca_manual_registration_activation {
1147             my $self = shift;
1148             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1149             and ( lc( $self->{xte_use_xca} ) eq 'yes' )
1150             and ( lc( $self->{xca_manual_registration_activation} ) eq 'yes' ) )
1151             {
1152             return 1;
1153             }
1154             else {
1155             return 0;
1156             }
1157             }
1158              
1159             =head2 xca_path()
1160              
1161             Returns the path to the directory containing xcathedra (if defined).
1162              
1163             =cut
1164              
1165             sub xca_path {
1166             my $self = shift;
1167             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1168             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1169             {
1170             return $self->{xca_path};
1171             }
1172             else {
1173             return undef;
1174             }
1175             }
1176              
1177             =head2 xca_profile_template_path()
1178              
1179             Returns the path to the site-specific template for user profiles.
1180              
1181             =cut
1182              
1183             sub xca_profile_template_path {
1184             my $self = shift;
1185             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1186             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1187             {
1188             return $self->{xca_profile_template_path};
1189             }
1190             else {
1191             return undef;
1192             }
1193             }
1194              
1195             =head2 xca_script_debug_caste()
1196              
1197             Returns the minimum caste which will see extended script error diagnostics.
1198              
1199             =cut
1200              
1201             sub xca_script_debug_caste {
1202             my $self = shift;
1203             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1204             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1205             {
1206             return $self->{xca_script_debug_caste};
1207             }
1208             else {
1209             return undef;
1210             }
1211             }
1212              
1213             =head2 xca_session_timeout()
1214              
1215             Returns the delay after which a session will time out.
1216              
1217             =cut
1218              
1219             sub xca_session_timeout {
1220             my $self = shift;
1221             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1222             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1223             {
1224             return $self->{xca_session_timeout};
1225             }
1226             else {
1227             return undef;
1228             }
1229             }
1230              
1231             =head2 xca_site_path()
1232              
1233             Returns the path to the directory containing the site-specific files.
1234              
1235             =cut
1236              
1237             sub xca_site_path {
1238             my $self = shift;
1239             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1240             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1241             {
1242             return $self->{xca_site_path};
1243             }
1244             else {
1245             return undef;
1246             }
1247             }
1248              
1249             =head2 xca_time_offset()
1250              
1251             Returns the default time zone offset.
1252              
1253             =cut
1254              
1255             sub xca_time_offset {
1256             my $self = shift;
1257             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1258             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
1259             {
1260             return $self->{xca_time_offset};
1261             }
1262             else {
1263             return undef;
1264             }
1265             }
1266              
1267             =head2 xca_unique_registration_email()
1268              
1269             Returns a flag signifying whether each user must use a unique email to register.
1270              
1271             =cut
1272              
1273             sub xca_unique_registration_email {
1274             my $self = shift;
1275             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1276             and ( lc( $self->{xte_use_xca} ) eq 'yes' )
1277             and ( lc( $self->{xca_unique_registration_email} ) eq 'yes' ) )
1278             {
1279             return 1;
1280             }
1281             else {
1282             return 0;
1283             }
1284             }
1285              
1286             =head2 xte_captcha_bgcolors()
1287              
1288             Returns a list of hex bytes (00 to FF) to be used to construct captcha background RGB values.
1289              
1290             =cut
1291              
1292             sub xte_captcha_bgcolors {
1293             my $self = shift;
1294             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1295             and $self->{xte_captcha_bgcolors} )
1296             {
1297             return @{ $self->{xte_captcha_bgcolors} };
1298             }
1299             else {
1300             return ();
1301             }
1302             }
1303              
1304             =head2 xte_captcha_colors()
1305              
1306             Returns a list of hex bytes (00 to FF) to be used to construct captcha foreground RGB values.
1307              
1308             =cut
1309              
1310             sub xte_captcha_colors {
1311             my $self = shift;
1312             if ( ( lc( $self->{start_xte} ) eq 'yes' ) and $self->{xte_captcha_colors} )
1313             {
1314             return @{ $self->{xte_captcha_colors} };
1315             }
1316             else {
1317             return ();
1318             }
1319             }
1320              
1321             =head2 xte_captcha_height()
1322              
1323             Returns the pixel height of captchas.
1324              
1325             =cut
1326              
1327             sub xte_captcha_height {
1328             my $self = shift;
1329             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1330             return $self->{xte_captcha_height};
1331             }
1332             else {
1333             return undef;
1334             }
1335             }
1336              
1337             =head2 xte_captcha_max_angle()
1338              
1339             Returns the maximum angle by which TrueType text will be rotated in a captcha.
1340              
1341             =cut
1342              
1343             sub xte_captcha_max_angle {
1344             my $self = shift;
1345             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1346             return $self->{xte_captcha_max_angle};
1347             }
1348             else {
1349             return undef;
1350             }
1351             }
1352              
1353             =head2 xte_captcha_max_line_thickness()
1354              
1355             Returns the maximum thickness of captcha lines.
1356              
1357             =cut
1358              
1359             sub xte_captcha_max_line_thickness {
1360             my $self = shift;
1361             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1362             return $self->{xte_captcha_max_line_thickness};
1363             }
1364             else {
1365             return undef;
1366             }
1367             }
1368              
1369             =head2 xte_captcha_max_lines()
1370              
1371             Returns the maximum number of lines to draw on a captcha.
1372              
1373             =cut
1374              
1375             sub xte_captcha_max_lines {
1376             my $self = shift;
1377             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1378             return $self->{xte_captcha_max_lines};
1379             }
1380             else {
1381             return undef;
1382             }
1383             }
1384              
1385             =head2 xte_captcha_min_line_thickness()
1386              
1387             Returns the minimum line thickness to use in captchas.
1388              
1389             =cut
1390              
1391             sub xte_captcha_min_line_thickness {
1392             my $self = shift;
1393             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1394             return $self->{xte_captcha_min_line_thickness};
1395             }
1396             else {
1397             return undef;
1398             }
1399             }
1400              
1401             =head2 xte_captcha_min_lines()
1402              
1403             Returns the minimum number of lines to draw on a captcha.
1404              
1405             =cut
1406              
1407             sub xte_captcha_min_lines {
1408             my $self = shift;
1409             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1410             return $self->{xte_captcha_min_lines};
1411             }
1412             else {
1413             return undef;
1414             }
1415             }
1416              
1417             =head2 xte_captcha_particle_count()
1418              
1419             Returns the number of particles to add to a captcha.
1420              
1421             =cut
1422              
1423             sub xte_captcha_particle_count {
1424             my $self = shift;
1425             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1426             return $self->{xte_captcha_particle_count};
1427             }
1428             else {
1429             return undef;
1430             }
1431             }
1432              
1433             =head2 xte_captcha_particle_size()
1434              
1435             Returns the size of particles added to a captcha.
1436              
1437             =cut
1438              
1439             sub xte_captcha_particle_size {
1440             my $self = shift;
1441             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1442             return $self->{xte_captcha_particle_size};
1443             }
1444             else {
1445             return undef;
1446             }
1447             }
1448              
1449             =head2 xte_captcha_styles()
1450              
1451             Returns a list of GD:SecurityImage captcha styles.
1452              
1453             =cut
1454              
1455             sub xte_captcha_styles {
1456             my $self = shift;
1457             if ( ( lc( $self->{start_xte} ) eq 'yes' ) and $self->{xte_captcha_styles} )
1458             {
1459             return @{ $self->{xte_captcha_styles} };
1460             }
1461             else {
1462             return ();
1463             }
1464             }
1465              
1466             =head2 xte_captcha_ttfont_size()
1467              
1468             Returns the point size for TrueType captcha text.
1469              
1470             =cut
1471              
1472             sub xte_captcha_ttfont_size {
1473             my $self = shift;
1474             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1475             return $self->{xte_captcha_ttfont_size};
1476             }
1477             else {
1478             return undef;
1479             }
1480             }
1481              
1482             =head2 xte_captcha_ttfonts()
1483              
1484             Returns a list of TrueType fonts for captchas.
1485              
1486             =cut
1487              
1488             sub xte_captcha_ttfonts {
1489             my $self = shift;
1490             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1491             and $self->{xte_captcha_ttfonts} )
1492             {
1493             return @{ $self->{xte_captcha_ttfonts} };
1494             }
1495             else {
1496             return ();
1497             }
1498             }
1499              
1500             =head2 xte_captcha_width()
1501              
1502             Returns the pixel width of captchas.
1503              
1504             =cut
1505              
1506             sub xte_captcha_width {
1507             my $self = shift;
1508             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1509             return $self->{xte_captcha_width};
1510             }
1511             else {
1512             return undef;
1513             }
1514             }
1515              
1516             =head2 xte_check_for_waiting()
1517              
1518             Returns the xte_check_for_waiting value (time to wait before revising number of child processes).
1519              
1520             =cut
1521              
1522             sub xte_check_for_waiting {
1523             my $self = shift;
1524             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1525             return $self->{xte_check_for_waiting};
1526             }
1527             else {
1528             return undef;
1529             }
1530             }
1531              
1532             =head2 xte_cidr_allow()
1533              
1534             Returns a list of allowed ip ranges for xteriorize
1535              
1536             =cut
1537              
1538             sub xte_cidr_allow {
1539             my $self = shift;
1540             if ( ( lc( $self->{start_xte} ) eq 'yes' ) and $self->{xte_cidr_allow} ) {
1541             return @{ $self->{xte_cidr_allow} };
1542             }
1543             else {
1544             return ();
1545             }
1546             }
1547              
1548             =head2 xte_cidr_deny()
1549              
1550             Returns a list of denied ip ranges for xteriorize
1551              
1552             =cut
1553              
1554             sub xte_cidr_deny {
1555             my $self = shift;
1556             if ( ( lc( $self->{start_xte} ) eq 'yes' ) and $self->{xte_cidr_deny} ) {
1557             return @{ $self->{xte_cidr_deny} };
1558             }
1559             else {
1560             return ();
1561             }
1562             }
1563              
1564             =head2 xte_docroot()
1565              
1566             Returns the docroot used by xteriorize.
1567              
1568             =cut
1569              
1570             sub xte_docroot {
1571             my $self = shift;
1572             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1573             return $self->{xte_docroot};
1574             }
1575             else {
1576             return undef;
1577             }
1578             }
1579              
1580             =head2 xte_enable_captcha()
1581              
1582             Returns true if captcha serving is enabled.
1583              
1584             =cut
1585              
1586             sub xte_enable_captcha {
1587             my $self = shift;
1588             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1589             and $self->{xte_enable_captcha}
1590             and ( lc( $self->{xte_enable_captcha} ) eq 'yes' ) )
1591             {
1592             return 1;
1593             }
1594             else {
1595             return 0;
1596             }
1597             }
1598              
1599             =head2 xte_enable_email()
1600              
1601             Returns true if is email sending is enabled.
1602              
1603             =cut
1604              
1605             sub xte_enable_email {
1606             my $self = shift;
1607             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1608             and $self->{xte_enable_email}
1609             and ( lc( $self->{xte_enable_email} ) eq 'yes' ) )
1610             {
1611             return 1;
1612             }
1613             else {
1614             return 0;
1615             }
1616             }
1617              
1618             =head2 xte_enable_file_writing()
1619              
1620             Returns true if is writing and deleting files is enabled.
1621              
1622             =cut
1623              
1624             sub xte_enable_file_writing {
1625             my $self = shift;
1626             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1627             and $self->{xte_enable_file_writing}
1628             and ( lc( $self->{xte_enable_file_writing} ) eq 'yes' ) )
1629             {
1630             return 1;
1631             }
1632             else {
1633             return 0;
1634             }
1635             }
1636              
1637             =head2 xte_enable_fop()
1638              
1639             Returns true if PDF output via Apache FOP is enabled.
1640              
1641             =cut
1642              
1643             sub xte_enable_fop {
1644             my $self = shift;
1645             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1646             and $self->{xte_enable_fop}
1647             and ( lc( $self->{xte_enable_fop} ) eq 'yes' ) )
1648             {
1649             return 1;
1650             }
1651             else {
1652             return 0;
1653             }
1654             }
1655              
1656             =head2 xte_enable_json()
1657              
1658             Returns true if output via XML::GenericJSON is enabled.
1659              
1660             =cut
1661              
1662             sub xte_enable_json {
1663             my $self = shift;
1664             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1665             and $self->{xte_enable_json}
1666             and ( lc( $self->{xte_enable_json} ) eq 'yes' ) )
1667             {
1668             return 1;
1669             }
1670             else {
1671             return 0;
1672             }
1673             }
1674              
1675             =head2 xte_enable_mxmlc()
1676              
1677             Returns true if output via the Flex 3 compiler mxmlc is enabled.
1678              
1679             =cut
1680              
1681             sub xte_enable_mxmlc {
1682             my $self = shift;
1683             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1684             and $self->{xte_enable_mxmlc}
1685             and ( lc( $self->{xte_enable_mxmlc} ) eq 'yes' ) )
1686             {
1687             return 1;
1688             }
1689             else {
1690             return 0;
1691             }
1692             }
1693              
1694             =head2 xte_enable_static_serving()
1695              
1696             Returns true if direct static file serving (ie without xacerbate) is enabled.
1697              
1698             =cut
1699              
1700             sub xte_enable_static_serving {
1701             my $self = shift;
1702             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1703             and $self->{xte_enable_static_serving}
1704             and ( lc( $self->{xte_enable_static_serving} ) eq 'yes' ) )
1705             {
1706             return 1;
1707             }
1708             else {
1709             return 0;
1710             }
1711             }
1712              
1713             =head2 xte_enable_uploads()
1714              
1715             Returns true if HTTP file uploading is enabled.
1716              
1717             =cut
1718              
1719             sub xte_enable_uploads {
1720             my $self = shift;
1721             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1722             and $self->{xte_enable_uploads}
1723             and ( lc( $self->{xte_enable_uploads} ) eq 'yes' ) )
1724             {
1725             return 1;
1726             }
1727             else {
1728             return 0;
1729             }
1730             }
1731              
1732             =head2 xte_enable_xmlroff()
1733              
1734             Returns true if PDF output via xmlroff is enabled.
1735              
1736             =cut
1737              
1738             sub xte_enable_xmlroff {
1739             my $self = shift;
1740             if ( ( lc( $self->{start_xte} ) eq 'yes' )
1741             and $self->{xte_enable_xmlroff}
1742             and ( lc( $self->{xte_enable_xmlroff} ) eq 'yes' ) )
1743             {
1744             return 1;
1745             }
1746             else {
1747             return 0;
1748             }
1749             }
1750              
1751             =head2 xte_from_address()
1752              
1753             Returns the from address for emails sent by xteriorize
1754              
1755             =cut
1756              
1757             sub xte_from_address {
1758             my $self = shift;
1759             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1760             return $self->{xte_from_address};
1761             }
1762             else {
1763             return undef;
1764             }
1765             }
1766              
1767             =head2 xte_gateway_auth()
1768              
1769             Returns the from code expected by xacerbate to authorize gateway connections.
1770              
1771             =cut
1772              
1773             sub xte_gateway_auth {
1774             my $self = shift;
1775             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1776             return $self->{xte_gateway_auth};
1777             }
1778             else {
1779             return undef;
1780             }
1781             }
1782              
1783             =head2 xte_group()
1784              
1785             Returns the un*x group to use for xteriorize child processes. May be undefined.
1786              
1787             =cut
1788              
1789             sub xte_group {
1790             my $self = shift;
1791             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1792             return $self->{xte_group};
1793             }
1794             else {
1795             return undef;
1796             }
1797             }
1798              
1799             =head2 xte_i18n_list()
1800              
1801             Returns a list of i18n files.
1802              
1803             =cut
1804              
1805             sub xte_i18n_list {
1806             my $self = shift;
1807             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1808             return @{ $self->{xte_i18n_list} || [] };
1809             }
1810             else {
1811             return undef;
1812             }
1813             }
1814              
1815             =head2 xte_image_sizes()
1816              
1817             Returns a list of sizes (eg 123x456) to which images will be scaled/cropped.
1818              
1819             =cut
1820              
1821             sub xte_image_sizes {
1822             my $self = shift;
1823             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1824             return @{ $self->{xte_image_sizes} || [] };
1825             }
1826             else {
1827             return undef;
1828             }
1829             }
1830              
1831             =head2 xte_log_file()
1832              
1833             Returns the path to the xte log file.
1834              
1835             =cut
1836              
1837             sub xte_log_file {
1838             my $self = shift;
1839             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1840             return $self->{xte_log_file};
1841             }
1842             else {
1843             return undef;
1844             }
1845             }
1846              
1847             =head2 xte_log_level()
1848              
1849             Returns the xteriorize log level.
1850              
1851             =cut
1852              
1853             sub xte_log_level {
1854             my $self = shift;
1855             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1856             return $self->{xte_log_level};
1857             }
1858             else {
1859             return undef;
1860             }
1861             }
1862              
1863             =head2 xte_max_image_size()
1864              
1865             Returns the maximum dimensions (eg 123x456) beyond which an uploaded image will be cropped.
1866              
1867             =cut
1868              
1869             sub xte_max_image_size {
1870             my $self = shift;
1871             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1872             return $self->{xte_max_image_size};
1873             }
1874             else {
1875             return undef;
1876             }
1877             }
1878              
1879             =head2 xte_max_servers()
1880              
1881             Returns the Net::Prefork max_servers value for xteriorize.
1882              
1883             =cut
1884              
1885             sub xte_max_servers {
1886             my $self = shift;
1887             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1888             return $self->{xte_max_servers};
1889             }
1890             else {
1891             return undef;
1892             }
1893             }
1894              
1895             =head2 xte_max_requests()
1896              
1897             Returns the Net::Prefork max_requests value for xteriorize.
1898              
1899             =cut
1900              
1901             sub xte_max_requests {
1902             my $self = shift;
1903             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1904             return $self->{xte_max_requests};
1905             }
1906             else {
1907             return undef;
1908             }
1909             }
1910              
1911             =head2 xte_max_spare_servers()
1912              
1913             Returns the Net::Prefork max_spare_servers value for xteriorize.
1914              
1915             =cut
1916              
1917             sub xte_max_spare_servers {
1918             my $self = shift;
1919             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1920             return $self->{xte_max_spare_servers};
1921             }
1922             else {
1923             return undef;
1924             }
1925             }
1926              
1927             =head2 xte_max_upload_size()
1928              
1929             Returns the maximum permitted size in kb of file uploads.
1930              
1931             =cut
1932              
1933             sub xte_max_upload_size {
1934             my $self = shift;
1935             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1936             return $self->{xte_max_upload_size};
1937             }
1938             else {
1939             return undef;
1940             }
1941             }
1942              
1943             =head2 xte_mimetype_path()
1944              
1945             Returns the path to the mimetype lookup table for direct static file serving.
1946              
1947             =cut
1948              
1949             sub xte_mimetype_path {
1950             my $self = shift;
1951             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1952             return $self->{xte_mimetype_path};
1953             }
1954             else {
1955             return undef;
1956             }
1957             }
1958              
1959             =head2 xte_min_servers()
1960              
1961             Returns the Net::Prefork min_servers value for xteriorize.
1962              
1963             =cut
1964              
1965             sub xte_min_servers {
1966             my $self = shift;
1967             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1968             return $self->{xte_min_servers};
1969             }
1970             else {
1971             return undef;
1972             }
1973             }
1974              
1975             =head2 xte_min_spare_servers()
1976              
1977             Returns the Net::Prefork min_spare_servers value for xteriorize.
1978              
1979             =cut
1980              
1981             sub xte_min_spare_servers {
1982             my $self = shift;
1983             if ( lc( $self->{start_xte} ) eq 'yes' ) {
1984             return $self->{xte_min_spare_servers};
1985             }
1986             else {
1987             return undef;
1988             }
1989             }
1990              
1991             =head2 xte_port()
1992              
1993             Returns the port used by xteriorize.
1994              
1995             =cut
1996              
1997             sub xte_port {
1998             my $self = shift;
1999             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2000             return $self->{xte_port};
2001             }
2002             else {
2003             return undef;
2004             }
2005             }
2006              
2007             =head2 xte_post_max()
2008              
2009             Returns the maximum character size of an http request received by xteriorize.
2010              
2011             =cut
2012              
2013             sub xte_post_max {
2014             my $self = shift;
2015             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2016             return $self->{xte_post_max};
2017             }
2018             else {
2019             return undef;
2020             }
2021             }
2022              
2023             =head2 xte_report_benchmarks()
2024              
2025             Returns true if timings for various aspects of Xcruciate processing are being output.
2026              
2027             =cut
2028              
2029             sub xte_report_benchmarks {
2030             my $self = shift;
2031             if ( not( lc( $self->{start_xte} ) eq 'yes' ) ) {
2032             return undef;
2033             }
2034             elsif ( lc( $self->{xte_report_benchmarks} ) eq 'yes' ) {
2035             return 1;
2036             }
2037             else { return 0 }
2038             }
2039              
2040             =head2 xte_server_ip()
2041              
2042             Returns the ip on which xteriorize will listen.
2043              
2044             =cut
2045              
2046             sub xte_server_ip {
2047             my $self = shift;
2048             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2049             return $self->{xte_server_ip};
2050             }
2051             else {
2052             return undef;
2053             }
2054             }
2055              
2056             =head2 xte_site_language()
2057              
2058             Returns the site language in 2-character format.
2059              
2060             =cut
2061              
2062             sub xte_site_language {
2063             my $self = shift;
2064             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2065             return $self->{xte_site_language};
2066             }
2067             else {
2068             return undef;
2069             }
2070             }
2071              
2072             =head2 xte_smtp_charset()
2073              
2074             Returns the charset used for smtp by xteriorize.
2075              
2076             =cut
2077              
2078             sub xte_smtp_charset {
2079             my $self = shift;
2080             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2081             return $self->{xte_smtp_charset};
2082             }
2083             else {
2084             return undef;
2085             }
2086             }
2087              
2088             =head2 xte_smtp_encoding()
2089              
2090             Returns the encoding used for smtp by xteriorize.
2091              
2092             =cut
2093              
2094             sub xte_smtp_encoding {
2095             my $self = shift;
2096             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2097             return $self->{xte_smtp_encoding};
2098             }
2099             else {
2100             return undef;
2101             }
2102             }
2103              
2104             =head2 xte_smtp_host()
2105              
2106             Returns the host used for smtp by xteriorize.
2107              
2108             =cut
2109              
2110             sub xte_smtp_host {
2111             my $self = shift;
2112             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2113             return $self->{xte_smtp_host};
2114             }
2115             else {
2116             return undef;
2117             }
2118             }
2119              
2120             =head2 xte_smtp_port()
2121              
2122             Returns the port used for smtp by xteriorize.
2123              
2124             =cut
2125              
2126             sub xte_smtp_port {
2127             my $self = shift;
2128             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2129             return $self->{xte_smtp_port};
2130             }
2131             else {
2132             return undef;
2133             }
2134             }
2135              
2136             =head2 xte_splurge_input()
2137              
2138             Returns true if xte_splurge_input is enabled (copies XML sent from xteriorize to xacerbate to STDERR).
2139              
2140             =cut
2141              
2142             sub xte_splurge_input {
2143             my $self = shift;
2144             if ( not( lc( $self->{start_xte} ) eq 'yes' ) ) {
2145             return undef;
2146             }
2147             elsif ( lc( $self->{xte_splurge_input} ) eq 'yes' ) {
2148             return 1;
2149             }
2150             else { return 0 }
2151             }
2152              
2153             =head2 xte_splurge_output()
2154              
2155             Returns true if xte_splurge_output is enabled (copies XML sent from xacerbate to xteriorize to STDERR).
2156              
2157             =cut
2158              
2159             sub xte_splurge_output {
2160             my $self = shift;
2161             if ( not( lc( $self->{start_xte} ) eq 'yes' ) ) {
2162             return undef;
2163             }
2164             elsif ( lc( $self->{xte_splurge_output} ) eq 'yes' ) {
2165             return 1;
2166             }
2167             else { return 0 }
2168             }
2169              
2170             =head2 xte_static_directories()
2171              
2172             Returns a list of directories under docroot from which files will be served directly by Xteriorized.
2173              
2174             =cut
2175              
2176             sub xte_static_directories {
2177             my $self = shift;
2178             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2179             return @{ $self->{xte_static_directories} || [] };
2180             }
2181             else {
2182             return undef;
2183             }
2184             }
2185              
2186             =head2 xte_temporary_file_path()
2187              
2188             Returns a directory to be used for temporary files, eg for output filters
2189              
2190             =cut
2191              
2192             sub xte_temporary_file_path {
2193             my $self = shift;
2194             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2195             return $self->{xte_temporary_file_path};
2196             }
2197             else {
2198             return undef;
2199             }
2200             }
2201              
2202             =head2 xte_user()
2203              
2204             Returns the un*x user to use for xteriorize child processes. May be undefined.
2205              
2206             =cut
2207              
2208             sub xte_user {
2209             my $self = shift;
2210             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2211             return $self->{xte_user};
2212             }
2213             else {
2214             return undef;
2215             }
2216             }
2217              
2218             =head2 xte_use_xca()
2219              
2220             Returns a flag according to whether or not xcathedra is used.
2221              
2222             =cut
2223              
2224             sub xte_use_xca {
2225             my $self = shift;
2226             if ( ( lc( $self->{start_xte} ) eq 'yes' )
2227             and ( lc( $self->{xte_use_xca} ) eq 'yes' ) )
2228             {
2229             return 1;
2230             }
2231             elsif ( $self->{start_xte} eq 'yes' ) {
2232             return 0;
2233             }
2234             else {
2235             return undef;
2236             }
2237             }
2238              
2239             =head2 xte_xac_timeout()
2240              
2241             Returns the delay for a response to xteriorize by xacerbate, after which xteriorize will issue a 504 ('gateway time-out') error.
2242              
2243             =cut
2244              
2245             sub xte_xac_timeout {
2246             my $self = shift;
2247             if ( lc( $self->{start_xte} ) eq 'yes' ) {
2248             return $self->{xte_xac_timeout};
2249             }
2250             else {
2251             return undef;
2252             }
2253             }
2254              
2255             =head2 local_croak()
2256              
2257             Function for croaking
2258              
2259             =cut
2260              
2261             sub local_croak {
2262             my $message = shift;
2263             croak $message if $message;
2264             }
2265              
2266             =head1 BUGS
2267              
2268             The best way to report bugs is via the Xcruciate bugzilla site (F).
2269              
2270             =head1 PREVIOUS VERSIONS
2271              
2272             =over
2273              
2274             B<0.01>: First upload
2275              
2276             B<0.03>: First upload including module
2277              
2278             B<0.04>: Changed minimum perl version to 5.8.8
2279              
2280             B<0.05>: Added debug_list data type. Warn about unknown entries
2281              
2282             B<0.06>: Added stop_only option to new(), added some comments
2283              
2284             B<0.07>: Revised config file entry names. Check server_ip as well as port on start/stop. Attempt to put all Xcruciate modules in one PAUSE tarball.
2285              
2286             B<0.08>: Added xte_temporary_file_path. Added lax option to proceed despite config errors.
2287              
2288             B<0.09>: Use Carp for errors.
2289              
2290             B<0.10>: Prepend path entry to relative paths
2291              
2292             B<0.11>: Remove transform_xsl_path
2293              
2294             B<0.12>: Resolve modifiable file paths, attempt to parse XML and XSLT files
2295              
2296             B<0.14>: Global update
2297              
2298             B<0.15>: Added xte_splurge_output
2299              
2300             B<0.16>: Added support for xca entries. Added very_persistent_modifiable_files and xte_i18n_files. Distinquish warnings and errors in output.
2301              
2302             B<0.17>: use warnings.
2303              
2304             B<0.18>: Removed xca_time_display_function. Made v0.16 additions optional. Added nine new xca entries. Added new types to file format reporting.
2305              
2306             B<0.19>: Use duration type for durations. Added xca_gateway_authenticate_timeout (previously a global in Xcathedra code). Got name of xte_use_xca right. Got missing xca entry testing in right loop.
2307              
2308             B<0.20>: Added backup_path, xte_site_language, xte captcha entries and xte_enable entries, xca_image_sizes entries.
2309              
2310             =back
2311              
2312             =head1 COPYRIGHT AND LICENSE
2313              
2314             Copyright (C) 2007 - 2009 by SARL Cyberporte/Menteith Consulting
2315              
2316             This library is distributed under the BSD licence (F).
2317              
2318             =cut
2319              
2320             1;