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