File Coverage

blib/lib/CASCM/Wrapper.pm
Criterion Covered Total %
statement 125 273 45.7
branch 29 112 25.8
condition 7 17 41.1
subroutine 17 80 21.2
pod 4 67 5.9
total 182 549 33.1


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