1 package logHandling;
4 use strict;
5 use warnings;
7 use Data::Dumper;
8 use File::Spec;
9 use MIME::Base64;
10 use GOsaSI::GosaSupportDaemon;
12 use Exporter;
14 our @ISA = qw(Exporter);
16 my @events = (
17 "get_events",
18 "show_log_by_mac",
19 "show_log_by_date",
20 "show_log_by_date_and_mac",
21 "show_log_files_by_date_and_mac",
22 "get_log_file_by_date_and_mac",
23 "get_recent_log_by_mac",
24 "delete_log_by_date_and_mac",
25 );
27 our @EXPORT = @events;
29 BEGIN {}
31 END {}
33 ### Start ######################################################################
36 #=== FUNCTION ================================================================
37 # NAME: get_events
38 # PARAMETERS: none
39 # RETURNS: reference of exported events
40 # DESCRIPTION: tells the caller which functions are available
41 #===============================================================================
42 sub get_events {
43 return \@events
44 }
47 #=== FUNCTION ================================================================
48 # NAME: show_log_by_date
49 # DESCRIPTION: reporting installed hosts matching to regex of date
50 # PARAMETERS: [$msg] original incoming message
51 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
52 # [$session_id] POE session id
53 # RETURNS: gosa-si valid answer string
54 #===============================================================================
55 sub show_log_by_date {
56 my ($msg, $msg_hash, $session_id) = @_;
57 my $header = @{$msg_hash->{header}}[0];
58 my $target = @{$msg_hash->{target}}[0];
59 my $source = @{$msg_hash->{source}}[0];
60 my $date_l = $msg_hash->{date};
61 my $out_msg;
62 $header =~ s/gosa_//;
64 if (not -d $main::client_fai_log_dir) {
65 my $error_string = "client fai log directory '$main::client_fai_log_dir' do not exist";
66 &main::daemon_log("$session_id ERROR: $error_string", 1);
67 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
68 }
70 # build out_msg
71 my $out_hash = &create_xml_hash($header, $target, $source);
73 # read mac directory
74 opendir(DIR, $main::client_fai_log_dir);
75 my @avail_macs = readdir(DIR);
76 closedir(DIR);
77 foreach my $avail_mac (@avail_macs) {
78 # check mac address
79 if ($avail_mac eq ".." || $avail_mac eq ".") { next; }
81 # read install dates directory
82 my $mac_dir = File::Spec->catdir($main::client_fai_log_dir, $avail_mac);
83 opendir(DIR, $mac_dir);
84 my @avail_dates = readdir(DIR);
85 closedir(DIR);
86 foreach my $date ( @{$date_l} ) { # multiple date selection is allowed
87 foreach my $avail_date (@avail_dates) {
88 # check install date
89 if ($avail_date eq ".." || $avail_date eq ".") { next; }
90 if (not $avail_date =~ /$date/i) { next; }
92 # add content to out_msg
93 &add_content2xml_hash($out_hash, $avail_date, $avail_mac);
94 }
95 }
96 }
98 $out_msg = &create_xml_string($out_hash);
99 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
100 if (defined $forward_to_gosa) {
101 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
102 }
104 return ($out_msg);
105 }
108 #=== FUNCTION ================================================================
109 # NAME: show_log_by_mac
110 # DESCRIPTION: reporting installation dates matching to regex of mac address
111 # PARAMETERS: [$msg] original incoming message
112 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
113 # [$session_id] POE session id
114 # RETURNS: gosa-si valid answer string
115 #===============================================================================
116 sub show_log_by_mac {
117 my ($msg, $msg_hash, $session_id) = @_;
118 my $header = @{$msg_hash->{header}}[0];
119 my $target = @{$msg_hash->{target}}[0];
120 my $source = @{$msg_hash->{source}}[0];
121 my $mac_l = $msg_hash->{mac};
123 $header =~ s/gosa_//;
125 if (not -d $main::client_fai_log_dir) {
126 my $error_string = "client fai log directory '$main::client_fai_log_dir' do not exist";
127 &main::daemon_log("$session_id ERROR: $error_string", 1);
128 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
129 }
131 # build out_msg
132 my $out_hash = &create_xml_hash($header, $target, $source);
134 # read mac directory
135 opendir(DIR, $main::client_fai_log_dir);
136 my @avail_macs = readdir(DIR);
137 closedir(DIR);
138 foreach my $mac (@{$mac_l}) { # multiple mac selection is allowed
139 foreach my $avail_mac ( @avail_macs ) {
140 # check mac address
141 if ($avail_mac eq ".." || $avail_mac eq ".") { next; }
142 if (not $avail_mac =~ /$mac/i) { next; }
144 # read install dates directory
145 my $act_log_dir = File::Spec->catdir($main::client_fai_log_dir, $avail_mac);
146 if (not -d $act_log_dir) { next; }
147 opendir(DIR, $act_log_dir);
148 my @avail_dates = readdir(DIR);
149 closedir(DIR);
150 $avail_mac =~ s/:/_/g; # make mac address XML::Simple valid
151 foreach my $avail_date (@avail_dates) {
152 # check install date
153 if ($avail_date eq ".." || $avail_date eq ".") { next; }
155 # add content to out_msg
156 &add_content2xml_hash($out_hash, "mac_$avail_mac", $avail_date);
157 }
158 }
159 }
161 my $out_msg = &create_xml_string($out_hash);
162 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
163 if (defined $forward_to_gosa) {
164 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
165 }
167 return ($out_msg);
168 }
171 #=== FUNCTION ================================================================
172 # NAME: show_log_by_date_and_mac
173 # DESCRIPTION: reporting host and installation dates matching to regex of date and regex of mac address
174 # PARAMETERS: [$msg] original incoming message
175 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
176 # [$session_id] POE session id
177 # RETURNS: gosa-si valid answer string
178 #===============================================================================
179 sub show_log_by_date_and_mac {
180 my ($msg, $msg_hash, $session_id) = @_ ;
181 my $header = @{$msg_hash->{header}}[0];
182 my $target = @{$msg_hash->{target}}[0];
183 my $source = @{$msg_hash->{source}}[0];
184 my $date = @{$msg_hash->{date}}[0];
185 my $mac = @{$msg_hash->{mac}}[0];
186 $header =~ s/gosa_//;
188 if (not -d $main::client_fai_log_dir) {
189 my $error_string = "client fai log directory '$main::client_fai_log_dir' do not exist";
190 &main::daemon_log("$session_id ERROR: $error_string", 1);
191 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
192 }
194 # build out_msg
195 my $out_hash = &create_xml_hash($header, $target, $source);
197 # read mac directory
198 opendir(DIR, $main::client_fai_log_dir);
199 my @avail_macs = readdir(DIR);
200 closedir(DIR);
201 foreach my $avail_mac ( @avail_macs ) {
202 # check mac address
203 if ($avail_mac eq ".." || $avail_mac eq ".") { next; }
204 if (not $avail_mac =~ /$mac/i) { next; }
205 my $act_log_dir = File::Spec->catdir($main::client_fai_log_dir, $avail_mac);
207 # read install date directory
208 opendir(DIR, $act_log_dir);
209 my @install_dates = readdir(DIR);
210 closedir(DIR);
211 foreach my $avail_date (@install_dates) {
212 # check install date
213 if ($avail_date eq ".." || $avail_date eq ".") { next; }
214 if (not $avail_date =~ /$date/i) { next; }
216 # add content to out_msg
217 &add_content2xml_hash($out_hash, $avail_date, $avail_mac);
218 }
219 }
221 my $out_msg = &create_xml_string($out_hash);
222 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
223 if (defined $forward_to_gosa) {
224 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
225 }
227 return $out_msg;
228 }
231 #=== FUNCTION ================================================================
232 # NAME: show_log_files_by_date_and_mac
233 # DESCRIPTION: reporting installation log files matching exatly to date and mac address
234 # PARAMETERS: [$msg] original incoming message
235 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
236 # [$session_id] POE session id
237 # RETURNS: gosa-si valid answer string
238 #===============================================================================
239 sub show_log_files_by_date_and_mac {
240 my ($msg, $msg_hash, $session_id) = @_ ;
241 my $header = @{$msg_hash->{header}}[0];
242 my $target = @{$msg_hash->{target}}[0];
243 my $source = @{$msg_hash->{source}}[0];
244 my $date = @{$msg_hash->{date}}[0];
245 my $mac = @{$msg_hash->{mac}}[0];
246 $header =~ s/gosa_//;
248 my $act_log_dir = File::Spec->catdir($main::client_fai_log_dir, $mac, $date);
249 if (not -d $act_log_dir) {
250 my $error_string = "client fai log directory '$act_log_dir' do not exist";
251 &main::daemon_log("$session_id ERROR: $error_string", 1);
252 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
253 }
255 # build out_msg
256 my $out_hash = &create_xml_hash($header, $target, $source);
258 # read mac / install date directory
259 opendir(DIR, $act_log_dir);
260 my @log_files = readdir(DIR);
261 closedir(DIR);
263 foreach my $log_file (@log_files) {
264 if ($log_file eq ".." || $log_file eq ".") { next; }
266 # add content to out_msg
267 &add_content2xml_hash($out_hash, $header, $log_file);
268 }
270 my $out_msg = &create_xml_string($out_hash);
271 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
272 if (defined $forward_to_gosa) {
273 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
274 }
276 return $out_msg;
277 }
280 #=== FUNCTION ================================================================
281 # NAME: get_log_file_by_date_and_mac
282 # DESCRIPTION: returning the given log file, base64 coded, matching exactly to date and mac address
283 # PARAMETERS: [$msg] original incoming message
284 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
285 # [$session_id] POE session id
286 # RETURNS: gosa-si valid answer string
287 #===============================================================================
288 sub get_log_file_by_date_and_mac {
289 my ($msg, $msg_hash, $session_id) = @_ ;
290 my $header = @{$msg_hash->{header}}[0];
291 my $target = @{$msg_hash->{target}}[0];
292 my $source = @{$msg_hash->{source}}[0];
293 my $date = @{$msg_hash->{date}}[0];
294 my $mac = @{$msg_hash->{mac}}[0];
295 my $log_file = @{$msg_hash->{log_file}}[0];
296 $header =~ s/gosa_//;
298 # sanity check
299 my $act_log_file = File::Spec->catfile($main::client_fai_log_dir, $mac, $date, $log_file);
300 if (not -f $act_log_file) {
301 my $error_string = "client fai log file '$act_log_file' do not exist or could not be read";
302 &main::daemon_log("$session_id ERROR: $error_string", 1);
303 &main::daemon_log("$session_id ERROR: mac='$mac', date='$date', log_file='$log_file'", 1);
304 &main::daemon_log("$session_id ERROR: could not process message: $msg", 1);
305 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
306 }
308 # read log file
309 my $log_content;
310 open(my $FILE, "<", "$act_log_file");
311 my @log_lines = <$FILE>;
312 close($FILE);
314 # prepare content for xml sending
315 $log_content = join("", @log_lines);
316 $log_content = &encode_base64($log_content);
318 # build out_msg and send
319 my $out_hash = &create_xml_hash($header, $target, $source);
320 &add_content2xml_hash($out_hash, $log_file, $log_content);
321 my $out_msg = &create_xml_string($out_hash);
322 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
323 if (defined $forward_to_gosa) {
324 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
325 }
327 return $out_msg;
328 }
331 # sorting function for fai log directory names
332 # used by get_recent_log_by_mac
333 sub transform {
334 my $a = shift;
335 $a =~ /_(\d{8}?)_(\d{6}?)$/ || return 0;
336 return int("$1$2");
337 }
338 sub by_log_date {
339 &transform($a) <=> &transform($b);
340 }
341 #=== FUNCTION ================================================================
342 # NAME: get_recent_log_by_mac
343 # DESCRIPTION: reporting the latest installation date matching to regex of mac address
344 # PARAMETERS: [$msg] original incoming message
345 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
346 # [$session_id] POE session id
347 # RETURNS: gosa-si valid answer string
348 #===============================================================================
349 sub get_recent_log_by_mac {
350 my ($msg, $msg_hash, $session_id) = @_ ;
351 my $header = @{$msg_hash->{header}}[0];
352 my $target = @{$msg_hash->{target}}[0];
353 my $source = @{$msg_hash->{source}}[0];
354 my $mac = @{$msg_hash->{mac}}[0];
355 $header =~ s/gosa_//;
357 # sanity check
358 if (not -d $main::client_fai_log_dir) {
359 my $error_string = "client fai log directory '$main::client_fai_log_dir' do not exist";
360 &main::daemon_log("$session_id ERROR: $error_string", 1);
361 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
362 }
364 opendir (DIR, $main::client_fai_log_dir);
365 my @avail_macs = readdir(DIR);
366 closedir(DIR);
367 my $act_log_dir;
368 my $act_mac;
369 foreach my $avail_mac (@avail_macs) {
370 if ($avail_mac eq ".." || $avail_mac eq ".") { next; }
371 if (not $avail_mac =~ /$mac/i) { next; }
372 $act_log_dir = File::Spec->catdir($main::client_fai_log_dir, $avail_mac);
373 $act_mac = $avail_mac;
374 }
375 if (not defined $act_log_dir) {
376 my $error_string = "do not find mac '$mac' in directory '$main::client_fai_log_dir'";
377 &main::daemon_log("$session_id ERROR: $error_string", 1);
378 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
379 }
381 # read mac directory
382 opendir(DIR, $act_log_dir);
383 my @avail_dates = readdir(DIR);
384 closedir(DIR);
386 # search for the latest log
387 my @sorted_dates = sort by_log_date @avail_dates;
388 my $latest_log = pop(@sorted_dates);
390 # build out_msg
391 my $out_hash = &create_xml_hash($header, $target, $source);
393 # read latest log directory
394 my $latest_log_dir = File::Spec->catdir($main::client_fai_log_dir, $act_mac, $latest_log);
395 opendir(DIR, $latest_log_dir);
396 my @log_files = readdir(DIR);
397 closedir(DIR);
399 # add all log_files to out_msg
400 foreach my $log_file (@log_files) {
401 if ($log_file eq ".." || $log_file eq ".") { next; }
402 &add_content2xml_hash($out_hash, $latest_log, $log_file);
403 }
405 my $out_msg = &create_xml_string($out_hash);
406 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
407 if (defined $forward_to_gosa) {
408 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
409 }
411 return $out_msg;
412 }
415 #=== FUNCTION ================================================================
416 # NAME: delete_log_by_date_and_mac
417 # DESCRIPTION: delete installation date directory matching to regex of date and regex of mac address
418 # missing date or mac is substitutet with regex '.'; if both is missing, deleting is rejected
419 # PARAMETERS: [$msg] original incoming message
420 # [$msg_hash] incoming message transformed to hash concerning XML::Simple
421 # [$session_id] POE session id
422 # RETURNS: gosa-si valid answer string
423 #===============================================================================
424 sub delete_log_by_date_and_mac {
425 my ($msg, $msg_hash, $session_id) = @_ ;
426 my $header = @{$msg_hash->{header}}[0];
427 my $target = @{$msg_hash->{target}}[0];
428 my $source = @{$msg_hash->{source}}[0];
429 my $date = @{$msg_hash->{date}}[0];
430 my $mac = @{$msg_hash->{mac}}[0];
431 $header =~ s/gosa_//;
433 # sanity check
434 if (not -d $main::client_fai_log_dir) {
435 my $error_string = "client fai log directory '$main::client_fai_log_dir' do not exist";
436 &main::daemon_log("$session_id ERROR: $session_id", 1);
437 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
438 }
439 if ((not defined $date) && (not defined $mac)) {
440 my $error_string = "deleting all log files from gosa-si-server by an empty delete message is not permitted";
441 &main::daemon_log("$session_id INFO: $error_string", 5);
442 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
443 }
444 if (not defined $date) { $date = "."; } # set date to a regular expression matching to everything
445 if (not defined $mac) { $mac = "."; } # set mac to a regular expression matching to everything
447 # build out_msg
448 my $out_hash = &create_xml_hash($header, $target, $source);
450 # read mac directory
451 opendir(DIR, $main::client_fai_log_dir);
452 my @avail_macs = readdir(DIR);
453 closedir(DIR);
454 foreach my $avail_mac ( @avail_macs ) {
455 # check mac address
456 if ($avail_mac eq ".." || $avail_mac eq ".") { next; }
457 if (not $avail_mac =~ /$mac/i) { next; }
458 my $act_log_dir = File::Spec->catdir($main::client_fai_log_dir, $avail_mac);
460 # read install date directory
461 opendir(DIR, $act_log_dir);
462 my @install_dates = readdir(DIR);
463 closedir(DIR);
464 foreach my $avail_date (@install_dates) {
465 # check install date
466 if ($avail_date eq ".." || $avail_date eq ".") { next; }
467 if (not $avail_date =~ /$date/i) { next; }
469 # delete directory and reptorting
470 my $dir_to_delete = File::Spec->catdir($main::client_fai_log_dir, $avail_mac, $avail_date);
471 #my $error = rmdir($dir_to_delete);
472 my $error = 0;
473 if ($error == 1) {
474 &main::daemon_log("$session_id ERROR: log directory '$dir_to_delete' cannot be deleted: $!", 1);
475 } else {
476 &main::daemon_log("$session_id INFO: log directory '$dir_to_delete' deleted", 5);
477 &add_content2xml_hash($out_hash, $avail_date, $avail_mac);
478 }
479 }
480 }
482 my $out_msg = &create_xml_string($out_hash);
483 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
484 if (defined $forward_to_gosa) {
485 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
486 }
488 return $out_msg;
489 }
491 1;