File Coverage

blib/lib/CASCM/Wrapper.pm
Criterion Covered Total %
statement 144 307 46.9
branch 32 124 25.8
condition 7 15 46.6
subroutine 19 83 22.8
pod 4 69 5.8
total 206 598 34.4


line stmt bran cond sub pod time code
1             package CASCM::Wrapper;
2              
3             #######################
4             # LOAD MODULES
5             #######################
6 5     5   6212 use 5.006001;
  5         19  
  5         242  
7              
8 5     5   31 use strict;
  5         10  
  5         229  
9 5     5   44 use warnings FATAL => 'all';
  5         10  
  5         277  
10              
11 5     5   4750 use File::Temp qw();
  5         107140  
  5         182  
12 5     5   39 use Carp qw(croak carp);
  5         7  
  5         24757  
13              
14             #######################
15             # VERSION
16             #######################
17             our $VERSION = '1.0.1';
18              
19             #######################
20             # MODULE METHODS
21             #######################
22              
23             # Constructor
24             sub new {
25 5     5 0 3221 my $class = shift;
26 5   100     37 my $options_ref = shift || {};
27              
28 5         11 my $self = {};
29 5         15 bless $self, $class;
30 5         19 return $self->_init($options_ref);
31             } ## end sub new
32              
33             # Set Context
34             sub set_context {
35 4     4 1 743 my $self = shift;
36 4   50     16 my $context = shift || {};
37              
38 4 50       14 if ( ref $context ne 'HASH' ) {
39 0         0 $self->_err("Context must be a hash reference");
40 0         0 return;
41             } ## end if ( ref $context ne 'HASH')
42              
43 4         8 $self->{_context} = $context;
44 4         29 return 1;
45             } ## end sub set_context
46              
47             # load context
48             sub load_context {
49 1     1 1 2 my $self = shift;
50 1   33     6 my $file
51             = shift || ( $self->_err("File required but missing") and return );
52              
53 1 50       25 if ( not -f $file ) { $self->_err("File $file does not exist"); return; }
  0         0  
  0         0  
54              
55             eval {
56 1         10 require Config::Tiny;
57 1         8 Config::Tiny->import();
58 1         4 return 1;
59 1 50       4 } or do {
60 0         0 $self->_err(
61             "Please install Config::Tiny if you'd like to load context files"
62             );
63 0         0 return;
64             };
65              
66             my $config = Config::Tiny->read($file)
67 1 0       17 or do { $self->_err("Error reading $file") and return; };
  0 50       0  
68              
69 1         262 my $context = {};
70 1         3 foreach ( keys %{$config} ) {
  1         6  
71 3 100       7 if ( $_ eq '_' ) { $context->{global} = $config->{$_}; }
  1         5  
72 2         6 else { $context->{$_} = $config->{$_}; }
73             } ## end foreach ( keys %{$config} )
74              
75 1         6 return $self->set_context($context);
76             } ## end sub load_context
77              
78             # Update Context
79             sub update_context {
80 1     1 1 2 my $self = shift;
81 1   50     4 my $new = shift || {};
82              
83 1 50       3 if ( ref $new ne 'HASH' ) {
84 0         0 $self->_err("Context must be a hash reference");
85 0         0 return;
86             } ## end if ( ref $new ne 'HASH')
87              
88 1         2 my $context = $self->get_context();
89              
90 1         1 foreach my $type ( keys %{$new} ) {
  1         7  
91 2         17 foreach my $key ( keys %{ $new->{$type} } ) {
  2         5  
92 2         5 $context->{$type}->{$key} = $new->{$type}->{$key};
93             }
94             } ## end foreach my $type ( keys %{$new...})
95              
96 1         2 return $self->set_context($context);
97             } ## end sub update_context
98              
99             # Parse logs
100             sub parse_logs {
101 0     0 0 0 my $self = shift;
102 0 0       0 if (@_) {
103 0         0 $self->{_options}->{parse_logs} = shift;
104 0 0       0 if ( $self->{_options}->{parse_logs} ) {
105 0 0       0 eval {
106 0         0 require Log::Any;
107 0         0 return 1;
108             }
109             or croak
110             "Error loading Log::Any. Please install it if you'd like to parse logs";
111             } ## end if ( $self->{_options}...)
112             } ## end if (@_)
113 0         0 return $self->{_options}->{parse_logs};
114             } ## end sub parse_logs
115              
116             # Dry Run
117             sub dry_run {
118 0     0 0 0 my $self = shift;
119 0 0       0 if (@_) { $self->{_options}->{dry_run} = shift; }
  0         0  
120 0         0 return $self->{_options}->{dry_run};
121             } ## end sub dry_run
122              
123             # Get context
124             sub get_context {
125 8     8 1 594 my ( $self, $cmd ) = @_;
126 8         12 my $context = {};
127 8 100       19 if ($cmd) {
128 4         16 $context = {
129              
130             # Global
131             $self->{_context}->{global}
132 4         21 ? %{ $self->{_context}->{global} }
133             : (),
134              
135             # Command specific
136 4 50       10 $self->{_context}->{$cmd} ? %{ $self->{_context}->{$cmd} } : (),
    50          
137             };
138             } ## end if ($cmd)
139             else {
140 4         7 $context = $self->{_context};
141             }
142              
143 8         31 return $context;
144             } ## end sub get_context
145              
146             # Get error message
147 0     0 0 0 sub errstr { return shift->{_errstr}; }
148              
149             # Get return code
150 0     0 0 0 sub exitval { return shift->{_exitval}; }
151              
152             # Make argument string
153             sub make_arg_str {
154 3     3 0 5 my ( $self, @args ) = @_;
155 3         4 my @quoted;
156 3         6 foreach my $arg (@args) {
157 2 50       4 next unless defined $arg;
158 2         5 $arg =~ s{^\"(.*)\"$}{$1}xi;
159 2         3 $arg =~ s{^\'(.*)\'$}{$1}xi;
160 2         5 $arg = '"' . $arg . '"';
161 2         5 push( @quoted, $arg );
162             } ## end foreach my $arg (@args)
163              
164 3         6 my $arg_str = '';
165 3 100       8 $arg_str = join( ' ', map { "-arg=$_" } @quoted ) if (@quoted);
  2         8  
166 3         7 return $arg_str;
167             } ## end sub make_arg_str
168              
169             #######################
170             # CASCM METHODS
171             #######################
172              
173 0     0 0 0 sub haccess { return shift->_run( 'haccess', @_ ); }
174 0     0 0 0 sub hap { return shift->_run( 'hap', @_ ); }
175 0     0 0 0 sub har { return shift->_run( 'har', @_ ); }
176 0     0 0 0 sub hauthsync { return shift->_run( 'hauthsync', @_ ); }
177 0     0 0 0 sub hcbl { return shift->_run( 'hcbl', @_ ); }
178 0     0 0 0 sub hccmrg { return shift->_run( 'hccmrg', @_ ); }
179 0     0 0 0 sub hcrrlte { return shift->_run( 'hcrrlte', @_ ); }
180 0     0 0 0 sub hchgtype { return shift->_run( 'hchgtype', @_ ); }
181 0     0 0 0 sub hchu { return shift->_run( 'hchu', @_ ); }
182 0     0 0 0 sub hci { return shift->_run( 'hci', @_ ); }
183 0     0 0 0 sub hcmpview { return shift->_run( 'hcmpview', @_ ); }
184 3     3 0 11 sub hco { return shift->_run( 'hco', @_ ); }
185 0     0 0 0 sub hcp { return shift->_run( 'hcp', @_ ); }
186 0     0 0 0 sub hcpj { return shift->_run( 'hcpj', @_ ); }
187 0     0 0 0 sub hcropmrg { return shift->_run( 'hcropmrg', @_ ); }
188 0     0 0 0 sub hcrtpath { return shift->_run( 'hcrtpath', @_ ); }
189 0     0 0 0 sub hdbgctrl { return shift->_run( 'hdbgctrl', @_ ); }
190 0     0 0 0 sub hdelss { return shift->_run( 'hdelss', @_ ); }
191 0     0 0 0 sub hdlp { return shift->_run( 'hdlp', @_ ); }
192 0     0 0 0 sub hdp { return shift->_run( 'hdp', @_ ); }
193 0     0 0 0 sub hdv { return shift->_run( 'hdv', @_ ); }
194 0     0 0 0 sub hexecp { return shift->_run( 'hexecp', @_ ); }
195 0     0 0 0 sub hexpenv { return shift->_run( 'hexpenv', @_ ); }
196 0     0 0 0 sub hfatt { return shift->_run( 'hfatt', @_ ); }
197 0     0 0 0 sub hformsync { return shift->_run( 'hformsync', @_ ); }
198 0     0 0 0 sub hft { return shift->_run( 'hft', @_ ); }
199 0     0 0 0 sub hgetusg { return shift->_run( 'hgetusg', @_ ); }
200 0     0 0 0 sub himpenv { return shift->_run( 'himpenv', @_ ); }
201 0     0 0 0 sub hlr { return shift->_run( 'hlr', @_ ); }
202 0     0 0 0 sub hlv { return shift->_run( 'hlv', @_ ); }
203 0     0 0 0 sub hmvitm { return shift->_run( 'hmvitm', @_ ); }
204 0     0 0 0 sub hmvpkg { return shift->_run( 'hmvpkg', @_ ); }
205 0     0 0 0 sub hmvpth { return shift->_run( 'hmvpth', @_ ); }
206 0     0 0 0 sub hpg { return shift->_run( 'hpg', @_ ); }
207 0     0 0 0 sub hpkgunlk { return shift->_run( 'hpkgunlk', @_ ); }
208 0     0 0 0 sub hpp { return shift->_run( 'hpp', @_ ); }
209 0     0 0 0 sub hppolget { return shift->_run( 'hppolget', @_ ); }
210 0     0 0 0 sub hppolset { return shift->_run( 'hppolset', @_ ); }
211 0     0 0 0 sub hrefresh { return shift->_run( 'hrefresh', @_ ); }
212 0     0 0 0 sub hrepedit { return shift->_run( 'hrepedit', @_ ); }
213 0     0 0 0 sub hrepmngr { return shift->_run( 'hrepmngr', @_ ); }
214 0     0 0 0 sub hri { return shift->_run( 'hri', @_ ); }
215 0     0 0 0 sub hrmvpth { return shift->_run( 'hrmvpth', @_ ); }
216 0     0 0 0 sub hrnitm { return shift->_run( 'hrnitm', @_ ); }
217 0     0 0 0 sub hrnpth { return shift->_run( 'hrnpth', @_ ); }
218 0     0 0 0 sub hrt { return shift->_run( 'hrt', @_ ); }
219 0     0 0 0 sub hsigget { return shift->_run( 'hsigget', @_ ); }
220 0     0 0 0 sub hsigset { return shift->_run( 'hsigset', @_ ); }
221 0     0 0 0 sub hsmtp { return shift->_run( 'hsmtp', @_ ); }
222 0     0 0 0 sub hspp { return shift->_run( 'hspp', @_ ); }
223 0     0 0 0 sub hsql { return shift->_run( 'hsql', @_ ); }
224 0     0 0 0 sub hsv { return shift->_run( 'hsv', @_ ); }
225 0     0 0 0 sub hsync { return shift->_run( 'hsync', @_ ); }
226 0     0 0 0 sub htakess { return shift->_run( 'htakess', @_ ); }
227 0     0 0 0 sub hucache { return shift->_run( 'hucache', @_ ); }
228 0     0 0 0 sub hudp { return shift->_run( 'hudp', @_ ); }
229 0     0 0 0 sub hup { return shift->_run( 'hup', @_ ); }
230 0     0 0 0 sub husrmgr { return shift->_run( 'husrmgr', @_ ); }
231 0     0 0 0 sub husrunlk { return shift->_run( 'husrunlk', @_ ); }
232              
233             #######################
234             # INTERNAL METHODS
235             #######################
236              
237             # Object initialization
238             sub _init {
239 5     5   9 my $self = shift;
240 5         7 my $options_ref = shift;
241              
242             # Basic initliazation
243 5         29 $self->{_options} = {};
244 5         15 $self->{_context} = {};
245 5         11 $self->{_errstr} = q();
246 5         10 $self->{_exitval} = 0;
247              
248             # Make sure we have a option hash ref
249 5 50       22 if ( ref $options_ref ne 'HASH' ) { croak "Hash reference expected"; }
  0         0  
250              
251             # Set default options
252 5         15 my %default_options = (
253             'context_file' => 0,
254             'dry_run' => 0,
255             'parse_logs' => 0,
256             );
257              
258             # Valid options
259 5         14 my %valid_options = (
260             'context_file' => 1,
261             'dry_run' => 1,
262             'parse_logs' => 1,
263             );
264              
265             # Read options
266 5         16 my %options = ( %default_options, %{$options_ref} );
  5         19  
267 5         18 foreach ( keys %options ) {
268 15 50       49 croak "Invalid option $_" unless $valid_options{$_};
269             }
270 5         14 $self->{_options} = \%options;
271              
272             # Set context
273 5 100       21 if ( $options{'context_file'} ) {
274 1 50       4 $self->load_context( $options{'context_file'} )
275             or croak "Error Loading Context file : " . $self->errstr();
276             } ## end if ( $options{'context_file'...})
277              
278             # Check if we're parsing logs
279 5 50       38 $self->parse_logs( $options{'parse_logs'} ) if $options{'parse_logs'};
280              
281             # Done initliazing
282 5         26 return $self;
283             } ## end sub _init
284              
285             # Set error
286             sub _err {
287 3     3   4 my $self = shift;
288 3         3 my $msg = shift;
289 3         9 $self->{_errstr} = $msg;
290 3         4 return 1;
291             } ## end sub _err
292              
293             # Set exitval
294             sub _exitval {
295 3     3   4 my ( $self, $rc ) = @_;
296 3 50       7 $rc = 0 if not defined $rc;
297 3         4 $self->{_exitval} = $rc;
298 3         3 return 1;
299             } ## end sub _exitval
300              
301             # Execute command
302             sub _run {
303 3     3   5 my ( $self, $cmd, @args ) = @_;
304              
305             # Reset error
306 3         7 $self->_err(q());
307 3         7 $self->_exitval(0);
308              
309             # Get Context & Options
310 3         4 my $context = {};
311 3         29 ( $context, @args ) = $self->_get_run_context( $cmd, @args );
312              
313             # Get options
314 3         6 my $dry_run = delete $context->{dry_run};
315 3         4 my $parse_log = delete $context->{parse_logs};
316              
317             # Check if we're parsing logs
318 3         3 my $default_log;
319 3 50       6 if ($parse_log) {
320              
321             # Init Log
322 0         0 my $tmpfile = File::Temp->new(
323             UNLINK => 1,
324             );
325 0         0 $default_log = $tmpfile->filename();
326              
327             # Remove existing 'o' & 'oa' from context
328 0 0       0 delete $context->{'o'} if exists $context->{'o'};
329 0 0       0 delete $context->{'oa'} if exists $context->{'oa'};
330              
331             # Set default log
332 0         0 $context->{'o'} = $default_log;
333             } ## end if ($parse_log)
334              
335             # Build argument string
336 3         8 my $arg_str = $self->make_arg_str(@args);
337              
338             # Get option string for $cmd
339 3         8 my $opt_str = $self->_get_option_str( $cmd, $context );
340              
341             # Dry run
342 3 50       8 if ($dry_run) { return "$cmd $arg_str $opt_str"; }
  3         31  
343              
344             # Prepare DI file
345 0         0 my $DIF = File::Temp->new( UNLINK => 0 );
346 0         0 my $di_file = $DIF->filename;
347             print( $DIF "$arg_str $opt_str" )
348 0 0       0 or do { $self->_err("Unable to write to $di_file") and return; };
  0 0       0  
349 0         0 close($DIF);
350              
351             # Run command
352 0         0 my $cmd_str = "$cmd -di \"${di_file}\"";
353 0         0 my $out = qx($cmd_str 2>&1);
354 0         0 my $rc = $?;
355              
356             # Cleanup DI file if command didn't remove it
357 0 0       0 if ( -f $di_file ) { unlink $di_file; }
  0         0  
358              
359             # Handle command error and return codes
360 0         0 my $method_return_value = $self->_handle_error( $cmd, $rc, $out );
361              
362             # Parse log
363 0 0       0 $self->_parse_log( $default_log, $parse_log ) if $parse_log;
364              
365             # Return
366 0         0 return $method_return_value;
367             } ## end sub _run
368              
369             # Get run context
370             sub _get_run_context {
371 3     3   4 my ( $self, $cmd, @args ) = @_;
372              
373 3         4 my $run_context = {};
374 3 100       13 if ( ref( $args[0] ) eq 'HASH' ) { $run_context = shift @args; }
  1         2  
375              
376 3   50     7 my $cmd_context = $self->get_context($cmd) || {};
377 3         3 my $context = { %{$cmd_context}, %{$run_context} };
  3         8  
  3         9  
378              
379 3 50       11 $context->{dry_run} = $self->{_options}->{dry_run}
380             if not exists $context->{dry_run};
381 3 50       9 $context->{parse_logs} = $self->{_options}->{parse_logs}
382             if not exists $context->{parse_logs};
383              
384 3         14 return ( $context, @args );
385             } ## end sub _get_run_context
386              
387             # Get option string
388             sub _get_option_str {
389 3     3   3 my $self = shift;
390 3         4 my $cmd = shift;
391 3   50     8 my $context = shift || {};
392              
393 3         6 my @cmd_options = _get_cmd_options($cmd);
394              
395 3         9 my @opt_args = qw();
396 3         6 foreach my $option (@cmd_options) {
397 126 100       222 next unless $context->{$option};
398 16         17 my $val = $context->{$option};
399 16 100       29 if ( $val eq '1' ) {
400 6         15 push @opt_args, "-${option}";
401             }
402             else {
403 10 50       22 if ( $val =~ m{^\s*\-arg} ) {
404 0         0 push @opt_args, "-${option}", $val;
405             }
406             else {
407 10         12 $val =~ s{^\"(.*)\"$}{$1}xi;
408 10         12 $val =~ s{^\'(.*)\'$}{$1}xi;
409 10         46 $val = '"' . $val . '"';
410 10         27 push @opt_args, "-${option}", $val;
411             } ## end else [ if ( $val =~ m{^\s*\-arg})]
412             } ## end else [ if ( $val eq '1' ) ]
413             } ## end foreach my $option (@cmd_options)
414              
415 3         22 return join( ' ', @opt_args );
416             } ## end sub _get_option_str
417              
418             # Command options
419             sub _get_cmd_options {
420 62     62   2523 my $cmd = shift;
421              
422             #<<< Don't touch this ...
423              
424 62         7616 my $options = {
425             'common' => [qw(o v oa wts)],
426             'haccess' => [qw(b eh en ft ha pw rn ug usr)],
427             'hap' => [qw(b c eh en pn pw st rej usr)],
428             'har' => [qw(b f m eh er pw mpw usr musr rport)],
429             'hauthsync' => [qw(b eh pw usr)],
430             'hcbl' => [qw(b eh en pw rp rw ss st add rdp rmr usr)],
431             'hccmrg' => [qw(b p eh en ma mc pn pw st tb tt usr)],
432             'hchgtype' => [qw(b q eh pw rp bin ext txt usr)],
433             'hchu' => [qw(b eh pw npw usr ousr)],
434             'hci' => [qw(b d p s bo cp de eh en er if nd ob op ot pn pw rm ro st tr uk ur vp dcp dvp rpw usr rusr rport)],
435             'hcmpview' => [qw(b s eh pw en1 en2 st1 usr uv1 uv2 vn1 vn2 vp1 vp2 cidc ciic)],
436             'hco' => [qw(b p r s bo br cp cu eh en er nt op pf pn po pw rm ro ss st sy tb to tr up vn vp ced dcp dvp nvf nvs rpw usr rusr rport replace)],
437             'hcp' => [qw(b at eh en pn pw st usr)],
438             'hcpj' => [qw(b eh pw act cpj cug dac ina npj tem usr)],
439             'hcropmrg' => [qw(b eh mo p1 p2 pn pw en1 en2 plo st1 st2 usr vfs)],
440             'hcrrlte' => [qw(b d eh en pw usr epid epname)],
441             'hcrtpath' => [qw(b p de eh en ob ot pw rp st usr cipn)],
442             'hdbgctrl' => [qw(b eh pw rm usr rport)],
443             'hdelss' => [qw(b eh en pw usr)],
444             'hdlp' => [qw(b eh en pn pw st usr pkgs)],
445             'hdp' => [qw(b eh en pb pd pn pw st adp pdr usr vdr)],
446             'hdv' => [qw(b s eh en pn pw st vp usr)],
447             'hexecp' => [qw(m er ma pw prg syn usr args asyn rport)],
448             'hexpenv' => [qw(b f eh en pw cug eac eug usr)],
449             'hfatt' => [qw(b at cp eh er fn ft pw rm add fid get rem rpw usr comp rusr rport)],
450             'hformsync' => [qw(b d f eh pw all hfd usr)],
451             'hft' => [qw(a b fo fs)],
452             'hgetusg' => [qw(b cu pu pw usr)],
453             'himpenv' => [qw(b f eh pw iug usr)],
454             'hlr' => [qw(b c f cp eh er pw rm rp rpw usr rcep rusr rport)],
455             'hlv' => [qw(b s ac cd eh en pn pw ss st vn vp usr)],
456             'hmvitm' => [qw(b p de eh en np ob ot pn pw st uk ur vp usr)],
457             'hmvpkg' => [qw(b eh en ph pn pw st ten tst usr)],
458             'hmvpth' => [qw(b p de eh en np ob ot pn pw st uk ur vp usr)],
459             'hpg' => [qw(b bp eh en pg pw st app cpg dpg dpp usr)],
460             'hpkgunlk' => [qw(b eh en pw usr)],
461             'hpp' => [qw(b eh en pb pd pm pn pw st adp pdr usr vdr)],
462             'hppolget' => [qw(b f eh gl pw usr)],
463             'hppolset' => [qw(b f eh fc pw usr)],
464             'hrefresh' => [qw(b iv pl pr ps pv st nst debug nolock)],
465             'hrepedit' => [qw(b eh fo pw rp all usr ismv isren ppath tpath rnpath newname oldname)],
466             'hrepmngr' => [qw(b c r co cp cr eh er fc ld mv nc nc pw rm rp all cep coe del drn drp dup isv mvs ren rpw srn srp upd usr appc gext ndac nmvs rext rusr noext rport addext appext remext addsgrp addugrp addvgrp newname oldname remsgrp remugrp remvgrp)],
467             'hri' => [qw(b p de eh en ob ot pn pw st vp usr)],
468             'hrmvpth' => [qw(b p de eh en ob ot pn pw st vp usr)],
469             'hrnitm' => [qw(b p de eh en nn ob on ot pn pw st uk ur vp usr)],
470             'hrnpth' => [qw(b p de eh en nn ob ot pn pw st uk ur vp usr)],
471             'hrt' => [qw(b f m eh er pw mpw usr musr rport)],
472             'hsigget' => [qw(a t v gl purge)],
473             'hsigset' => [qw(purge context)],
474             'hsmtp' => [qw(d f m p s cc bcc)],
475             'hspp' => [qw(b s eh en fp pn pw st tp usr)],
476             'hsql' => [qw(b f s t eh eh gl nh pw usr)],
477             'hsv' => [qw(b p s eh en gl ib id io it iu iv pw st vp usr)],
478             'hsync' => [qw(b av bo br cp eh en er fv il iv pl pn ps pv pw rm ss st sy tb to vp ced iol rpw usr excl rusr excls purge rport complete)],
479             'htakess' => [qw(b p eh en pb pg pn po pw rs ss st ts ve vp abv usr)],
480             'hucache' => [qw(b eh en er pw ss st vp rpw usr rusr purge rport cacheagent)],
481             'hudp' => [qw(b ap eh en ip pn pw st usr)],
482             'hup' => [qw(b p af at cf eh en ft nt pr pw rf afo apg del des npn rfo rpg usr)],
483             'husrmgr' => [qw(b ad ae cf du eh nn ow pw cpw dlm swl usr)],
484             'husrunlk' => [qw(b eh pw usr)],
485             };
486              
487             #>>>
488              
489 3053         5896 my @cmd_options = sort { lc $a cmp lc $b }
  62         142  
490 62         233 ( @{ $options->{common} }, @{ $options->{$cmd} } );
  62         246  
491 62         2612 return @cmd_options;
492             } ## end sub _get_cmd_options
493              
494             # Handle error/return
495             sub _handle_error {
496 0     0     my ( $self, $cmd, $rc, $out ) = @_;
497              
498             # Fix return code
499 0 0         if ( $rc > 255 ) { $rc = $rc >> 8; }
  0            
500              
501             # Save exitval
502 0           $self->_exitval($rc);
503              
504             # Standard cases
505 0           my %error = (
506             '1' => "Command syntax for $cmd is incorrect."
507             . ' Please check your context setting',
508             '2' => 'Broker not connected',
509             '3' => "$cmd failed",
510             '4' => 'Unexpected error',
511             '5' => 'Invalid login',
512             '6' => 'Server or database down',
513             '7' => 'Incorrect service pack level',
514             '8' => 'Incompatible server version',
515             '9' => 'Exposed password',
516             '10' => 'Ambiguous arguments',
517             '11' => 'Access denied',
518             '12' => 'Pre-link failed',
519             '13' => 'Post-link failed',
520             );
521              
522             # Special cases
523 0 0         if ( $cmd eq 'hchu' ) {
    0          
    0          
524 0           %error = (
525             %error,
526             '94' =>
527             'Password changes executed from the command line using hchu are disabled when external authentication is enabled',
528             );
529             } ## end if ( $cmd eq 'hchu' )
530             elsif ( $cmd eq 'hco' ) {
531 0           %error = (
532             %error,
533             '14' => 'No version was found for the file name or pattern',
534             );
535             } ## end elsif ( $cmd eq 'hco' )
536             elsif ( $cmd eq 'hexecp' ) {
537 0           %error = (
538             %error,
539             '2' =>
540             'Broker not connected OR the invoked program did not return a value of its own',
541             );
542             } ## end elsif ( $cmd eq 'hexecp' )
543              
544             # Cleanup command output
545 0 0         if ($out) {
546 0           my @lines;
547 0           foreach my $line ( split( /\r\n|\r|\n/, $out ) ) {
548 0           chomp $line;
549 0           $line =~ s{^\s+}{}gxi;
550 0           $line =~ s{\s+$}{}gxi;
551 0 0         next unless $line;
552 0 0         next if $line =~ /^[[:blank:]]$/;
553 0           push @lines, $line;
554             } ## end foreach my $line ( split( /\r\n|\r|\n/...))
555              
556             # Reset
557 0           $out = join( '. ', @lines );
558             } ## end if ($out)
559              
560             # Get error message
561 0           my $msg;
562 0 0         if ( $rc == -1 ) {
    0          
563 0           $msg = "Failed to execute $cmd";
564 0 0         $msg .= " : $out" if $out;
565 0           $self->_err($msg);
566 0           return;
567             } ## end if ( $rc == -1 )
568             elsif ( $rc > 0 ) {
569 0 0         if ( $error{$rc} ) {
570 0           $msg = $error{$rc};
571 0 0         $msg .= " : $out" if $out;
572             } ## end if ( $error{$rc} )
573             else {
574 0 0         if ($out) { $msg = $out; }
  0            
575 0           else { $msg = 'Unknown error'; }
576             } ## end else [ if ( $error{$rc} ) ]
577 0           $self->_err($msg);
578 0           return;
579             } ## end elsif ( $rc > 0 )
580              
581             # Return true
582 0           return 1;
583             } ## end sub _handle_error
584              
585             # Parse Log
586             sub _parse_log {
587 0     0     my ( $self, $logfile, $category ) = @_;
588              
589 0   0       $category ||= 0;
590 0 0         $category = __PACKAGE__ if ( $category eq '1' );
591              
592 0 0         my $log
593             = Log::Any->get_logger( $category ? ( category => $category ) : () );
594              
595 0 0         if ( not -f $logfile ) {
596              
597             # The log file was probably not created
598             # if the command didn't even execute
599 0 0         $log->error( $self->errstr() ) if ( $self->errstr() );
600 0           return 1;
601             } ## end if ( not -f $logfile )
602              
603 0 0         open( my $LOG, '<', $logfile ) or do {
604 0           $log->warn("Unable to read $logfile");
605 0 0         $log->error( $self->errstr() ) if ( $self->errstr() );
606 0           return 1;
607             };
608              
609 0           while (<$LOG>) {
610 0           my $line = $_;
611 0 0         next unless defined $line;
612 0           chomp $line;
613 0           $line =~ s{^\s+}{}gxi;
614 0           $line =~ s{\s+$}{}gxi;
615 0 0         next unless $line;
616 0 0         next if $line =~ /^[[:blank:]]*$/;
617              
618 0 0         if ( $line =~ s/^\s*E0\w{7}\:\s*//x ) { $log->error($line); }
  0 0          
    0          
619 0           elsif ( $line =~ s/^\s*W0\w{7}\:\s*//x ) { $log->warn($line); }
620 0           elsif ( $line =~ s/^\s*I0\w{7}\:\s*//x ) { $log->info($line); }
621 0           else { $log->info($line); }
622             } ## end while (<$LOG>)
623 0           close $LOG;
624 0           unlink($logfile);
625              
626 0 0         $log->error( $self->errstr() ) if ( $self->errstr() );
627              
628 0           return 1;
629             } ## end sub _parse_log
630              
631             #######################
632             1;
633              
634             __END__