File Coverage

blib/lib/CASCM/Wrapper.pm
Criterion Covered Total %
statement 131 280 46.7
branch 30 114 26.3
condition 7 17 41.1
subroutine 18 82 21.9
pod 4 68 5.8
total 190 561 33.8


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