File Coverage

blib/lib/EMDIS/ECS/Config.pm
Criterion Covered Total %
statement 223 238 93.7
branch 92 118 77.9
condition 28 36 77.7
subroutine 15 16 93.7
pod 0 2 0.0
total 358 410 87.3


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2             #
3             # Copyright (C) 2002-2020 National Marrow Donor Program. All rights reserved.
4             #
5             # For a description of this module, please refer to the POD documentation
6             # embedded at the bottom of the file (e.g. perldoc EMDIS::ECS::Config).
7              
8             package EMDIS::ECS::Config;
9              
10 2     2   13105 use Carp;
  2         4  
  2         101  
11 2     2   10 use Cwd;
  2         2  
  2         87  
12 2     2   516 use EMDIS::ECS qw($VERSION is_yes is_no);
  2         5  
  2         243  
13 2     2   11 use File::Basename;
  2         5  
  2         122  
14 2     2   12 use File::Spec::Functions qw(catdir catfile file_name_is_absolute rel2abs);
  2         5  
  2         92  
15 2     2   10 use strict;
  2         2  
  2         56  
16 2     2   973 use Text::ParseWords;
  2         2459  
  2         118  
17 2     2   14 use vars qw($AUTOLOAD %ok_attr);
  2         2  
  2         219  
18              
19             # ----------------------------------------------------------------------
20             # initialize %ok_attr hash with valid attribute names
21             BEGIN
22             {
23 2     2   19 my @attrlist = qw(
24             MSG_PROC MAIL_MRK THIS_NODE T_CHK T_SCN ERR_FILE LOG_FILE ADM_ADDR
25             M_MSG_PROC BCK_DIR ACK_THRES LOG_LEVEL MAIL_LEVEL
26             ECS_BIN_DIR ECS_DAT_DIR ECS_TO_DIR ECS_FROM_DIR ECS_DEBUG
27             NODE_TBL NODE_TBL_LCK T_ADM_DELAY T_ADM_REMIND T_MSG_PROC
28             ADAPTER_CMD ALWAYS_ACK GNU_TAR T_RESEND_DELAY
29             SMTP_HOST SMTP_DOMAIN SMTP_TIMEOUT SMTP_DEBUG SMTP_FROM SMTP_PORT
30             SMTP_USE_SSL SMTP_USE_STARTTLS SMTP_USERNAME SMTP_PASSWORD
31             INBOX_PROTOCOL INBOX_HOST INBOX_PORT INBOX_TIMEOUT INBOX_DEBUG
32             INBOX_FOLDER INBOX_USERNAME INBOX_PASSWORD INBOX_MAX_MSG_SIZE
33             INBOX_DIRECTORY INBOX_USE_SSL INBOX_USE_STARTTLS
34             MSG_PART_SIZE_DFLT
35             GPG_HOMEDIR GPG_KEYID GPG_PASSPHRASE
36             OPENPGP_CMD_ENCRYPT OPENPGP_CMD_DECRYPT
37             PGP_HOMEDIR PGP_KEYID PGP_PASSPHRASE
38             PGP2_CMD_ENCRYPT PGP2_CMD_DECRYPT
39             ENABLE_AMQP
40             AMQP_BROKER_URL AMQP_VHOST AMQP_ADDR_META AMQP_ADDR_MSG AMQP_ADDR_DOC
41             AMQP_TRUSTSTORE AMQP_SSLCERT AMQP_SSLKEY AMQP_SSLPASS
42             AMQP_USERNAME AMQP_PASSWORD
43             AMQP_RECV_TIMEOUT AMQP_RECV_TIMELIMIT AMQP_SEND_TIMELIMIT
44             AMQP_DEBUG_LEVEL AMQP_CMD_SEND AMQP_CMD_RECV
45             EMDIS_MESSAGE_VERSION
46             );
47 2         5 for my $attr (@attrlist)
48             {
49 158         4725 $ok_attr{$attr} = 1;
50             }
51             }
52              
53             # ----------------------------------------------------------------------
54             # use AUTOLOAD method to provide accessor methods
55             # (as described in Perl Cookbook)
56             sub AUTOLOAD
57             {
58 139     139   577 my $this = shift;
59 139         223 my $attr = $AUTOLOAD;
60 139         605 $attr =~ s/.*:://;
61 139 100       551 return unless $attr =~ /[^A-Z]/; # skip DESTROY and all-cap methods
62             # (for EMDIS::ECS::Config, all valid
63             # attribute names contain at least
64             # one underscore)
65 133 50       231 croak "invalid attribute method: ->$attr()" unless $ok_attr{$attr};
66 133         720 return $this->{uc $attr};
67             }
68              
69             # ----------------------------------------------------------------------
70             # Constructor.
71             # Returns EMDIS::ECS::Config reference if successful or error message if
72             # error encountered.
73             sub new
74             {
75 7     7 0 4556 my $class = shift;
76 7         8 my $cfg_file = shift;
77 7         10 my $skip_val = shift;
78 7 50       19 $skip_val = '' unless defined $skip_val;
79 7         12 my $this = {};
80 7         15 bless $this, $class;
81 7 50       15 $cfg_file = 'ecs.cfg' unless defined($cfg_file);
82 7         18 $this->{CFG_FILE} = $cfg_file;
83 7         14252 $this->{CFG_CWD} = cwd(); # remember cwd in case it may be needed
84 7         196 $this->_set_defaults();
85 7 50       27 return $this if $cfg_file eq ''; # default config (used by ecs_setup)
86 7         46 my $err = $this->_read_config();
87 7 100       58 return $err if $err;
88 5 50       12 return $this if $skip_val; # skip validation (used by ecs_setup)
89 5         18 $err = $this->_massage_config();
90 5 50       10 return $err if $err;
91 5         44 $err = $this->_validate_config();
92 5 100       80 return $err if $err;
93 2         14 return $this;
94             }
95              
96             # ----------------------------------------------------------------------
97             # Display configuration data.
98             sub display
99             {
100 0     0 0 0 my $this = shift;
101 0         0 my $fmt = "%-20s %s\n";
102 0         0 print "ECS_CFG\n";
103 0         0 print "---------------------------------------------------------------\n";
104 0         0 for my $attr (sort keys %$this) {
105 0         0 my $value = $this->{$attr};
106 0 0       0 $value = '********' if $attr =~ /PASSWORD|PASSPHRASE/i;
107 0         0 printf $fmt, $attr, $value;
108             }
109             }
110              
111             # ----------------------------------------------------------------------
112             # Parse config file data.
113             # Returns empty string if successful or error message if error encountered.
114             sub _read_config
115             {
116 7     7   19 my $this = shift;
117              
118             # read config file
119 7         23 my $err = '';
120 7 100       273 if(not open CONFIG, "< $this->{CFG_FILE}")
121             {
122 1         24 return "Unable to open config file '$this->{CFG_FILE}': $!";
123             }
124 6         136 while()
125             {
126 151         221 chomp; # trim EOL character(s)
127 151         271 s/^\s+//; # trim leading whitespace
128 151         392 s/\s+$//; # trim trailing whitespace
129 151 100       274 next unless length; # skip blank line
130 145 100       303 next if /^#/; # skip comment line
131 117         143 my @fields = ();
132 117         271 my @tokens = split '\|'; # split on pipe ('|') delimiter
133 117         173 for my $token (@tokens)
134             {
135 351 50 66     860 if($#fields >= 0 and $fields[$#fields] =~ /\\$/)
136             {
137             # rejoin tokens separated by escaped pipe ('\|')
138 0         0 chop($fields[$#fields]);
139 0         0 $fields[$#fields] .= "|$token";
140             }
141             else
142             {
143 351         523 push(@fields, $token);
144             }
145             }
146             # trim leading & trailing whitespace
147 117         152 @fields = map { s/^\s+//; s/\s+$//; $_; } @fields;
  351         645  
  351         767  
  351         619  
148 117         201 my ($attr, $value, $comment) = @fields;
149 117 100       200 if($ok_attr{$attr})
150             {
151             # store value
152 116         534 $this->{$attr} = $value;
153             }
154             else
155             {
156 1         33 $err .=
157             "Unexpected input '$attr' at $this->{CFG_FILE} line $.\n";
158             }
159             }
160 6         54 close CONFIG;
161 6 100       23 if($err)
162             {
163 1         13 return $err .
164             "Error(s) encountered while attempting to process " .
165             "$this->{CFG_FILE}.";
166             }
167              
168 5         15 return '';
169             }
170              
171             # ----------------------------------------------------------------------
172             # Massage config data.
173             # Returns empty string if successful or error message if error encountered.
174             sub _massage_config
175             {
176 5     5   8 my $this = shift;
177              
178             # initialize
179 5         162 my $script_dir = dirname($0);
180 5 50       118 $script_dir = rel2abs($script_dir)
181             unless file_name_is_absolute($script_dir);
182 5         494 my $config_dir = dirname($this->{CFG_FILE});
183 5 50       21 $config_dir = rel2abs($config_dir)
184             unless file_name_is_absolute($config_dir);
185              
186             # parse some special tokens
187 5         304 for my $attr (keys %ok_attr)
188             {
189 431 100       594 if(exists $this->{$attr})
190             {
191 286         368 my $value = $this->{$attr};
192 286         329 $value =~ s/__SCRIPT_DIR__/$script_dir/;
193 286         309 $value =~ s/__CONFIG_DIR__/$config_dir/;
194 286         369 $this->{$attr} = $value;
195             }
196             }
197              
198             # prepend ECS_DAT_DIR to non-absolute file/path names
199 5         21 for my $attr (qw(ERR_FILE GPG_HOMEDIR LOG_FILE NODE_TBL NODE_TBL_LCK
200             PGP_HOMEDIR ECS_TO_DIR ECS_FROM_DIR))
201             {
202             $this->{$attr} = catfile($this->{ECS_DAT_DIR}, $this->{$attr})
203             if exists($this->{$attr})
204             and not ($this->{$attr} eq '')
205 40 100 66     354 and not file_name_is_absolute($this->{$attr});
      100        
206             }
207              
208             # prepend ECS_BIN_DIR to non-absolute executable command names
209 5         9 for my $attr (qw(MSG_PROC M_MSG_PROC))
210             {
211             $this->{$attr} = catfile($this->{ECS_BIN_DIR}, $this->{$attr})
212             if exists($this->{$attr})
213 10 50 33     95 and not file_name_is_absolute($this->{$attr});
214             }
215              
216             # compute derived values
217 5         48 $this->{ECS_TMP_DIR} = catdir($this->{ECS_DAT_DIR}, 'tmp');
218 5 100 66     56 if ( ! defined($this->{ECS_TO_DIR}) || $this->{ECS_TO_DIR} eq '')
219             {
220 4         24 $this->{ECS_DRP_DIR} = catdir($this->{ECS_DAT_DIR}, 'maildrop');
221             }
222             else
223             {
224 1         13 $this->{ECS_DRP_DIR} = $this->{ECS_TMP_DIR};
225             }
226 5         22 $this->{ECS_MBX_DIR} = catdir($this->{ECS_DAT_DIR}, 'mboxes');
227 5         16 $this->{ECS_MBX_AMQP_STAGING_DIR} = catdir($this->{ECS_MBX_DIR}, 'amqp_staging');
228 5         23 $this->{ECS_MBX_IN_DIR} = catdir($this->{ECS_MBX_DIR}, 'in');
229 5         17 $this->{ECS_MBX_IN_FML_DIR} = catdir($this->{ECS_MBX_DIR}, 'in_fml');
230 5         22 $this->{ECS_MBX_OUT_DIR} = catdir($this->{ECS_MBX_DIR}, 'out');
231 5         16 $this->{ECS_MBX_TRASH_DIR} = catdir($this->{ECS_MBX_DIR}, 'trash');
232 5         14 $this->{ECS_MBX_STORE_DIR} = catdir($this->{ECS_MBX_DIR}, 'store');
233 5         9 for my $attr (qw(ECS_TMP_DIR ECS_DRP_DIR ECS_MBX_DIR
234             ECS_MBX_AMQP_STAGING_DIR ECS_MBX_IN_DIR
235             ECS_MBX_IN_FML_DIR ECS_MBX_OUT_DIR ECS_MBX_TRASH_DIR
236             ECS_MBX_STORE_DIR))
237             {
238 45         83 $ok_attr{$attr} = 1;
239             }
240              
241             # parse more special tokens
242 5         42 for my $attr (keys %ok_attr)
243             {
244 440 100       574 if(exists $this->{$attr})
245             {
246 331         370 my $value = $this->{$attr};
247 331         367 $value =~ s/__MAILDROP_DIR__/$this->{ECS_DRP_DIR}/;
248 331         455 $this->{$attr} = $value;
249             }
250             }
251              
252             # if indicated, assign SMTP_PORT default value
253 5 100       37 if(not defined($this->{SMTP_PORT})) {
254 4         8 $this->{SMTP_PORT} = 25;
255 4 100       51 $this->{SMTP_PORT} = 465 if is_yes($this->{SMTP_USE_SSL});
256 4 100       12 $this->{SMTP_PORT} = 587 if is_yes($this->{SMTP_USE_STARTTLS});
257             }
258              
259             # if indicated, assign INBOX_PORT default value
260 5 100       13 if(not defined($this->{INBOX_PORT})) {
261 4         9 for($this->{INBOX_PROTOCOL})
262             {
263 4 100       12 /POP3/ and do {
264 2         4 $this->{INBOX_PORT} = 110;
265 2 50       3 $this->{INBOX_PORT} = 995 if is_yes($this->{INBOX_USE_SSL});
266             };
267 4 100       10 /IMAP/ and do {
268 1         11 $this->{INBOX_PORT} = 143;
269 1 50       14 $this->{INBOX_PORT} = 993 if is_yes($this->{INBOX_USE_SSL});
270             };
271             }
272             }
273              
274 5         11 return '';
275             }
276              
277             # ----------------------------------------------------------------------
278             # Assign default values to configuration settings.
279             # Note: no default value for THIS_NODE, ADM_ADDR, ADAPTER_CMD, SMTP_DOMAIN,
280             # SMTP_FROM, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, INBOX_PORT,
281             # INBOX_FOLDER, INBOX_USERNAME, INBOX_PASSWORD, GPG_HOMEDIR, GPG_KEYID,
282             # GPG_PASSPHRASE, PGP_HOMEDIR, PGP_KEYID, PGP_PASSPHRASE,
283             # AMQP_BROKER_URL, AMQP_VHOST, AMQP_TRUSTSTORE, AMQP_SSLCERT AMQP_SSLKEY,
284             # AMQP_SSLPASS, AMQP_USERNAME, AMQP_PASSWORD
285             sub _set_defaults
286             {
287 7     7   37 my $this = shift;
288 7         68 $this->{MSG_PROC} = "ecs_proc_msg";
289 7         60 $this->{MAIL_MRK} = "EMDIS";
290 7         50 $this->{T_CHK} = "7200";
291 7         46 $this->{T_SCN} = "3600";
292 7         829 my $basename = basename($0); # default; use magic logfile name
293 7         55 $this->{ERR_FILE} = "$basename.err";
294 7         65 $this->{LOG_FILE} = "$basename.log";
295 7         21 $this->{M_MSG_PROC} = "ecs_proc_meta";
296 7         38 $this->{BCK_DIR} = "NONE";
297 7         24 $this->{ACK_THRES} = "100";
298 7         25 $this->{ALWAYS_ACK} = "NO";
299 7         20 $this->{GNU_TAR} = "/usr/bin/tar";
300 7         19 $this->{ECS_BIN_DIR} = "__SCRIPT_DIR__";
301 7         59 $this->{ECS_DAT_DIR} = "__CONFIG_DIR__";
302 7         80 $this->{ECS_DEBUG} = "0";
303 7         62 $this->{NODE_TBL} = "node_tbl.dat";
304 7         25 $this->{NODE_TBL_LCK} = "node_tbl.lock";
305 7         40 $this->{T_ADM_DELAY} = "0";
306 7         17 $this->{T_ADM_REMIND} = "86400";
307 7         35 $this->{T_MSG_PROC} = "3600";
308 7         17 $this->{T_RESEND_DELAY} = "14400";
309 7         41 $this->{LOG_LEVEL} = 1;
310 7         18 $this->{MAIL_LEVEL} = 2;
311 7         37 $this->{MSG_PART_SIZE_DFLT} = "1073741824";
312 7         44 $this->{SMTP_HOST} = "smtp";
313 7         41 $this->{SMTP_TIMEOUT} = "60";
314 7         13 $this->{SMTP_DEBUG} = "0";
315 7         36 $this->{SMTP_USE_SSL} = "NO";
316 7         45 $this->{SMTP_USE_STARTTLS} = "NO";
317 7         17 $this->{INBOX_PROTOCOL} = "POP3";
318 7         32 $this->{INBOX_HOST} = "mail";
319 7         11 $this->{INBOX_FOLDER} = "INBOX";
320 7         14 $this->{INBOX_TIMEOUT} = "60";
321 7         35 $this->{INBOX_DEBUG} = "0";
322 7         14 $this->{INBOX_USE_SSL} = "NO";
323 7         17 $this->{INBOX_USE_STARTTLS} = "NO";
324 7         18 $this->{INBOX_MAX_MSG_SIZE} = "1048576";
325 7         41 $this->{OPENPGP_CMD_ENCRYPT} = '/usr/local/bin/gpg --armor --batch ' .
326             '--charset ISO-8859-1 --force-mdc --logger-fd 1 --openpgp ' .
327             '--output __OUTPUT__ --passphrase-fd 0 --quiet ' .
328             '--recipient __RECIPIENT__ --recipient __SELF__ --yes ' .
329             '--sign --local-user __SELF__ --encrypt __INPUT__';
330 7         43 $this->{OPENPGP_CMD_DECRYPT} = '/usr/local/bin/gpg --batch ' .
331             '--charset ISO-8859-1 --logger-fd 1 --openpgp --output __OUTPUT__ ' .
332             '--passphrase-fd 0 --quiet --yes --decrypt __INPUT__';
333 7         44 $this->{PGP2_CMD_ENCRYPT} = '/usr/local/bin/pgp +batchmode +verbose=0 ' .
334             '+force +CharSet=latin1 +ArmorLines=0 -o __OUTPUT__ ' .
335             '-u __SELF__ -eats __INPUT__ __RECIPIENT__ __SELF__';
336 7         43 $this->{PGP2_CMD_DECRYPT} = '/usr/local/bin/pgp +batchmode +verbose=0 ' .
337             '+force +CharSet=latin1 -o __OUTPUT__ __INPUT__';
338 7         45 $this->{ENABLE_AMQP} = "NO";
339 7         17 $this->{AMQP_RECV_TIMEOUT} = 5;
340 7         10 $this->{AMQP_RECV_TIMELIMIT} = 300;
341 7         37 $this->{AMQP_SEND_TIMELIMIT} = 60;
342 7         44 $this->{AMQP_DEBUG_LEVEL} = 0;
343 7         17 $this->{AMQP_CMD_SEND} = 'ecs_amqp_send.py';
344 7         42 $this->{AMQP_CMD_RECV} = 'ecs_amqp_recv.py';
345             }
346              
347             # ----------------------------------------------------------------------
348             # Do a few sanity checks on the configuration data.
349             # Returns empty string if successful or error message if error encountered.
350             sub _validate_config
351             {
352 5     5   12 my $this = shift;
353 5         7 my @errors = ();
354 5         46 my @required_attrlist = qw(
355             MSG_PROC MAIL_MRK THIS_NODE T_CHK T_SCN ERR_FILE LOG_FILE ADM_ADDR
356             M_MSG_PROC BCK_DIR ACK_THRES
357             ECS_BIN_DIR ECS_DAT_DIR ECS_DEBUG
358             NODE_TBL NODE_TBL_LCK T_ADM_REMIND T_MSG_PROC
359             SMTP_HOST SMTP_DOMAIN SMTP_TIMEOUT SMTP_DEBUG SMTP_FROM
360             INBOX_PROTOCOL INBOX_HOST INBOX_TIMEOUT INBOX_DEBUG
361             INBOX_MAX_MSG_SIZE
362             MSG_PART_SIZE_DFLT
363             );
364              
365             # check for required values that are undefined
366 5         39 for my $attr (@required_attrlist)
367             {
368             push(@errors, "$attr not defined.")
369 145 100       244 unless exists($this->{$attr});
370             }
371              
372             # validate INBOX_PROTOCOL
373            
374             # username/password not needed for DIRECTORY inbox
375 5 50       16 if($this->{INBOX_PROTOCOL} !~ /DIRECTORY/i)
376             {
377 5         7 for my $attr (qw( INBOX_USERNAME INBOX_PASSWORD))
378             {
379             push(@errors, "$attr not defined.")
380 10 100       26 unless exists($this->{$attr});
381             }
382             }
383              
384 5 100       49 if($this->{INBOX_PROTOCOL} =~ /IMAP/i)
    100          
    50          
    50          
385             {
386 2         8 $this->{INBOX_PROTOCOL} = 'IMAP'; # force uppercase
387             push(@errors,
388             "INBOX_FOLDER not defined, but is required for IMAP protocol.")
389 2 50       13 unless defined($this->{INBOX_FOLDER});
390             }
391             elsif($this->{INBOX_PROTOCOL} =~ /POP3/i)
392             {
393 2         5 $this->{INBOX_PROTOCOL} = 'POP3'; # force uppercase
394             }
395             elsif($this->{INBOX_PROTOCOL} =~ /DIRECTORY/i)
396             {
397 0         0 $this->{INBOX_PROTOCOL} = 'DIRECTORY'; # force uppercase
398             push(@errors, "INBOX_DIRECTORY not defined, but is required for " .
399             "DIRECTORY protocol.")
400 0 0       0 unless defined($this->{INBOX_DIRECTORY});
401             }
402             elsif($this->{INBOX_PROTOCOL} =~ /NONE/i)
403             {
404 0         0 $this->{INBOX_PROTOCOL} = 'NONE'; # force uppercase
405             }
406             else
407             {
408 1         11 push(@errors,
409             "Unrecognized INBOX_PROTOCOL: $this->{INBOX_PROTOCOL}");
410             }
411              
412 5 50       26 if(is_yes($this->{ENABLE_AMQP}))
413             {
414             # sanity checks on AMQP configuration
415 0         0 for my $attr (qw(AMQP_ADDR_META AMQP_ADDR_MSG AMQP_BROKER_URL
416             AMQP_CMD_SEND AMQP_CMD_RECV AMQP_DEBUG_LEVEL
417             AMQP_RECV_TIMEOUT AMQP_RECV_TIMELIMIT
418             AMQP_SEND_TIMELIMIT))
419             {
420             push(@errors, "$attr not defined, but is required for AMQP " .
421             "messaging.")
422 0 0       0 unless exists($this->{$attr});
423             }
424             }
425              
426             # check whether an encryption method is configured
427 5 50 66     18 if(!exists($this->{GPG_HOMEDIR}) && !exists($this->{PGP_HOMEDIR}))
428             {
429 1         3 push(@errors, "No encryption method configured. Need to " .
430             "configure either GPG_HOMEDIR or PGP_HOMEDIR, etc.");
431             }
432              
433             # check OpenPGP encryption setup
434 5 100       12 if(exists($this->{GPG_HOMEDIR}))
435             {
436 4         13 for my $attr (qw(GPG_HOMEDIR GPG_KEYID GPG_PASSPHRASE
437             OPENPGP_CMD_ENCRYPT OPENPGP_CMD_DECRYPT))
438             {
439             push(@errors, "$attr not defined, but is required for OpenPGP " .
440             "encryption setup (GPG_HOMEDIR = " .
441             $this->{GPG_HOMEDIR} . ").")
442 20 100       43 unless exists($this->{$attr});
443             }
444             }
445              
446             # check PGP encryption setup
447 5 100       11 if(exists($this->{PGP_HOMEDIR}))
448             {
449 3         9 for my $attr (qw(PGP_HOMEDIR PGP_KEYID PGP_PASSPHRASE
450             PGP2_CMD_ENCRYPT PGP2_CMD_DECRYPT))
451             {
452             push(@errors, "$attr not defined, but is required for PGP2 " .
453             "encryption setup (PGP_HOMEDIR = " .
454             $this->{PGP_HOMEDIR} . ").")
455 15 100       40 unless exists($this->{$attr});
456             }
457             }
458              
459             # validate T_CHK
460 5 100       18 if($this->{T_CHK} <= 0)
461             {
462 1         11 push(@errors,
463             "T_CHK ($this->{T_CHK}) is required to be greater than zero.");
464             }
465              
466             # validate T_SCN
467 5 100       11 if($this->{T_SCN} <= 0)
468             {
469 1         4 push(@errors,
470             "T_SCN ($this->{T_SCN}) is required to be greater than zero.");
471             }
472              
473             # validate T_ADM_REMIND
474 5 100       16 if($this->{T_ADM_REMIND} <= 0)
475             {
476 1         7 push(@errors,
477             "T_ADM_REMIND ($this->{T_ADM_REMIND}) is required " .
478             "to be greater than zero.");
479             }
480              
481             # validate T_MSG_PROC
482 5 100       14 if($this->{T_MSG_PROC} <= 0)
483             {
484 1         7 push(@errors,
485             "T_MSG_PROC ($this->{T_MSG_PROC}) is required " .
486             "to be greater than zero.");
487             }
488              
489             # validate YES/NO values
490 5         24 for my $name (qw(ALWAYS_ACK INBOX_USE_SSL INBOX_USE_STARTTLS SMTP_USE_SSL SMTP_USE_STARTTLS))
491             {
492 25 100 66     90 if(exists $this->{$name} and not is_yes($this->{$name})
      100        
493             and not is_no($this->{$name}))
494             {
495             push(@errors, "Unrecognized $name (YES/NO) value: " .
496 5         21 $this->{$name});
497             }
498             }
499              
500 5 100 100     11 if(is_yes($this->{INBOX_USE_SSL})
501             and is_yes($this->{INBOX_USE_STARTTLS}))
502             {
503 1         7 push(@errors, "INBOX_USE_SSL and INBOX_USE_STARTTLS " .
504             "are both selected, but they are mutually exclusive.");
505             }
506              
507 5 100 100     12 if(is_yes($this->{SMTP_USE_SSL})
508             and is_yes($this->{SMTP_USE_STARTTLS}))
509             {
510 1         3 push(@errors, "SMTP_USE_SSL and SMTP_USE_STARTTLS " .
511             "are both selected, but they are mutually exclusive.");
512             }
513              
514             # check whether directories exist
515 5         17 my @dirs = qw(ECS_BIN_DIR ECS_DAT_DIR ECS_TMP_DIR ECS_MBX_DIR
516             ECS_MBX_IN_DIR ECS_MBX_IN_FML_DIR ECS_MBX_OUT_DIR
517             ECS_MBX_TRASH_DIR ECS_MBX_STORE_DIR GPG_HOMEDIR
518             PGP_HOMEDIR);
519 5 50       11 push(@dirs, 'BCK_DIR') if($this->{BCK_DIR} ne 'NONE');
520             push(@dirs, 'ECS_DRP_DIR')
521             if( ! defined($this->{ECS_TO_DIR})
522 5 100 66     29 || $this->{ECS_TO_DIR} eq '');
523 5 50       14 push(@dirs, 'ECS_MBX_AMQP_STAGING_DIR') if is_yes($this->{ENABLE_AMQP});
524 5         10 for my $dir (@dirs)
525             {
526 59 100 100     723 if(exists $this->{$dir} and not -d $this->{$dir})
527             {
528 8         31 push(@errors,
529             "$dir ($this->{$dir}) directory not found.");
530             }
531             }
532              
533             # return error messages, if any
534 5 100       16 if($#errors >= 0)
535             {
536 3         9 push(@errors,
537             "Error(s) detected in configuration file $this->{CFG_FILE}");
538 3         6 push(@errors, "Fatal configuration error(s) encountered.\n");
539 3         31 return "\n" . join("\n", @errors);
540             }
541 2         12 return '';
542             }
543              
544             1;
545              
546             __DATA__