Code

update: ownership of installing jobs can be switch among si-server
[gosa.git] / gosa-si / server / events / clMessages.pm
1 ## @file
2 # @brief Implementation of a GOsa-SI event module. 
3 # @details A GOsa-SI event module containing all functions to handle incoming messages from clients.
5 package clMessages;
6 use Exporter;
7 @ISA = qw(Exporter);
8 my @events = (
9     "confirm_usr_msg",
10     "PROGRESS",
11     "FAIREBOOT",
12     "TASKSKIP",
13     "TASKBEGIN",
14     "TASKEND",
15     "TASKERROR",
16     "HOOK",
17     "GOTOACTIVATION",
18     "LOGIN",
19     "LOGOUT",
20     "CURRENTLY_LOGGED_IN",
21     "save_fai_log",
22     );
23 @EXPORT = @events;
25 use strict;
26 use warnings;
27 use Data::Dumper;
28 use GOSA::GosaSupportDaemon;
29 use MIME::Base64;
32 BEGIN {}
34 END {}
37 ## @method get_events()
38 # @details A brief function returning a list of functions which are exported by importing the module.
39 # @return List of all provided functions
40 sub get_events {
41     return \@events;
42 }
44 ## @method confirm_usr_msg()
45 # @details Confirmed messages are set in the messaging_db from d (deliverd) to s(seen). 
46 # @param msg - STRING - xml message with tags 'message', 'subject' and 'usr'
47 # @param msg_hash - HASHREF - message information parsed into a hash
48 # @param session_id - INTEGER - POE session id of the processing of this message
49 sub confirm_usr_msg {
50     my ($msg, $msg_hash, $session_id) = @_;
51     my $message = @{$msg_hash->{'message'}}[0];
52     my $subject = @{$msg_hash->{'subject'}}[0];
53     my $usr = @{$msg_hash->{'usr'}}[0];
55     # set update for this message
56     my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')"; 
57     &main::daemon_log("$session_id DEBUG: $sql", 7);
58     my $res = $main::messaging_db->exec_statement($sql); 
61     return;
62 }
65 ## @method save_fai_log()
66 # @details Creates under /var/log/fai/ the directory '$macaddress' and stores within all FAI log files from client.
67 # @param msg - STRING - xml message with tags 'macaddress' and 'save_fai_log'
68 # @param msg_hash - HASHREF - message information parsed into a hash
69 # @param session_id - INTEGER - POE session id of the processing of this message
70 sub save_fai_log {
71     my ($msg, $msg_hash, $session_id) = @_;
72     my $header = @{$msg_hash->{'header'}}[0];
73     my $source = @{$msg_hash->{'source'}}[0];
74     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
75     my $all_logs = @{$msg_hash->{$header}}[0];
77     # if there is nothing to log
78     if( ref($all_logs) eq "HASH" ) { return; }
79         
80     my $client_fai_log_dir = $main::client_fai_log_dir;
81     if (not -d $client_fai_log_dir) {
82         mkdir($client_fai_log_dir, 0755)
83     }
85     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
86     if (not -d $client_fai_log_dir) {
87         mkdir($client_fai_log_dir, 0755)
88     }
90     my $time = &get_time;
91     $time = substr($time, 0, 8)."_".substr($time, 8, 6);
92     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
93     mkdir($client_fai_log_dir, 0755);
95     my @all_logs = split(/log_file:/, $all_logs); 
96     foreach my $log (@all_logs) {
97         if (length $log == 0) { next; };
98         my ($log_file, $log_string) = split(":", $log);
99         my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
101         open(my $LOG_FILE, ">$client_fai_log_file"); 
102         print $LOG_FILE &decode_base64($log_string);
103         close($LOG_FILE);
105     }
106     return;
109 ## @method LOGIN()
110 # @details Reported user from client is added to login_users_db.
111 # @param msg - STRING - xml message with tag 'LOGIN'
112 # @param msg_hash - HASHREF - message information parsed into a hash
113 # @param session_id - INTEGER - POE session id of the processing of this message
114 sub LOGIN {
115     my ($msg, $msg_hash, $session_id) = @_;
116     my $header = @{$msg_hash->{'header'}}[0];
117     my $source = @{$msg_hash->{'source'}}[0];
118     my $login = @{$msg_hash->{$header}}[0];
120     my %add_hash = ( table=>$main::login_users_tn, 
121         primkey=> ['client', 'user'],
122         client=>$source,
123         user=>$login,
124         timestamp=>&get_time,
125         ); 
126     my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
127     if ($res != 0)  {
128         &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
129         return;
130     }
132     return;   
136 ## @method LOGOUT()
137 # @details Reported user from client is deleted from login_users_db.
138 # @param msg - STRING - xml message with tag 'LOGOUT'
139 # @param msg_hash - HASHREF - message information parsed into a hash
140 # @param session_id - INTEGER - POE session id of the processing of this message
141 sub LOGOUT {
142     my ($msg, $msg_hash, $session_id) = @_;
143     my $header = @{$msg_hash->{'header'}}[0];
144     my $source = @{$msg_hash->{'source'}}[0];
145     my $login = @{$msg_hash->{$header}}[0];
146     
147     my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')"; 
148     my $res =  $main::login_users_db->del_dbentry($sql_statement);
149     &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5); 
150     
151     return;
155 ## @method CURRENTLY_LOGGED_IN()
156 # @details Reported users from client are updated in login_users_db. Users which are no longer logged in are deleted from DB. 
157 # @param msg - STRING - xml message
158 # @param msg_hash - HASHREF - message information parsed into a hash
159 # @param session_id - INTEGER - POE session id of the processing of this message
160 sub CURRENTLY_LOGGED_IN {
161     my ($msg, $msg_hash, $session_id) = @_;
162     my ($sql_statement, $db_res);
163     my $header = @{$msg_hash->{'header'}}[0];
164     my $source = @{$msg_hash->{'source'}}[0];
165     my $login = @{$msg_hash->{$header}}[0];
167     if(ref $login eq "HASH") { 
168         &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5); 
169         return;     
170     }
171     
172     # fetch all user currently assigned to the client at login_users_db
173     my %currently_logged_in_user = (); 
174     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'"; 
175     $db_res = $main::login_users_db->select_dbentry($sql_statement);
176     while( my($hit_id, $hit) = each(%{$db_res}) ) {
177         $currently_logged_in_user{$hit->{'user'}} = 1;
178     }
179     &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7); 
181     # update all reported users in login_user_db
182     my @logged_in_user = split(/\s+/, $login);
183     &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7); 
184     foreach my $user (@logged_in_user) {
185         my %add_hash = ( table=>$main::login_users_tn, 
186                 primkey=> ['client', 'user'],
187                 client=>$source,
188                 user=>$user,
189                 timestamp=>&get_time,
190                 ); 
191         my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
192         if ($res != 0)  {
193             &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
194             return;
195         }
197         delete $currently_logged_in_user{$user};
198     }
200     # if there is still a user in %currently_logged_in_user 
201     # although he is not reported by client 
202     # then delete it from $login_user_db
203     foreach my $obsolete_user (keys(%currently_logged_in_user)) {
204         &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
205                 "in at client '$source' but still found at login_user_db", 3); 
206         my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'"; 
207         my $res =  $main::login_users_db->del_dbentry($sql_statement);
208         &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3); 
209     }
211     return;
215 ## @method GOTOACTIVATION()
216 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
217 # @param msg - STRING - xml message with tag 'macaddress'
218 # @param msg_hash - HASHREF - message information parsed into a hash
219 # @param session_id - INTEGER - POE session id of the processing of this message
220 sub GOTOACTIVATION {
221     my ($msg, $msg_hash, $session_id) = @_;
222     my $header = @{$msg_hash->{'header'}}[0];
223     my $source = @{$msg_hash->{'source'}}[0];
224     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
226     # test whether content is an empty hash or a string which is required
227     my $content = @{$msg_hash->{$header}}[0];
228     if(ref($content) eq "HASH") { $content = ""; }
230     # clean up header
231     $header =~ s/CLMSG_//g;
233     my $sql_statement = "UPDATE $main::job_queue_tn ".
234             "SET status='processing', progress='goto-activation', modified='1' ".
235             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
236     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
237     my $res = $main::job_db->update_dbentry($sql_statement);
238     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
239     return; 
243 ## @method PROGRESS()
244 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
245 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
246 # @param msg_hash - HASHREF - message information parsed into a hash
247 # @param session_id - INTEGER - POE session id of the processing of this message
248 sub PROGRESS {
249     my ($msg, $msg_hash, $session_id) = @_;
250     my $header = @{$msg_hash->{'header'}}[0];
251     my $source = @{$msg_hash->{'source'}}[0];
252     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
254     # test whether content is an empty hash or a string which is required
255     my $content = @{$msg_hash->{$header}}[0];
256     if(ref($content) eq "HASH") { $content = ""; }
258     # clean up header
259     $header =~ s/CLMSG_//g;
261     my $sql_statement = "UPDATE $main::job_queue_tn ".
262         "SET progress='$content', modified='1' ".
263         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
264     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
265     my $res = $main::job_db->update_dbentry($sql_statement);
266     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
268     return;
272 ## @method FAIREBOOT()
273 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
274 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
275 # @param msg_hash - HASHREF - message information parsed into a hash
276 # @param session_id - INTEGER - POE session id of the processing of this message
277 sub FAIREBOOT {
278     my ($msg, $msg_hash, $session_id) = @_;
279     my $header = @{$msg_hash->{'header'}}[0];
280     my $source = @{$msg_hash->{'source'}}[0];
281     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
283     # test whether content is an empty hash or a string which is required
284         my $content = @{$msg_hash->{$header}}[0];
285     if(ref($content) eq "HASH") { $content = ""; }
287     # clean up header
288     $header =~ s/CLMSG_//g;
290     my $sql_statement = "UPDATE $main::job_queue_tn ".
291             "SET status='processing', result='$header "."$content', modified='1' ".
292             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
293     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
294     my $res = $main::job_db->update_dbentry($sql_statement);
295     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
297     return; 
301 ## @method TASKSKIP()
302 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated. 
303 # @param msg - STRING - xml message with tag 'macaddress'.
304 # @param msg_hash - HASHREF - message information parsed into a hash
305 # @param session_id - INTEGER - POE session id of the processing of this message
306 sub TASKSKIP {
307     my ($msg, $msg_hash, $session_id) = @_;
308     my $header = @{$msg_hash->{'header'}}[0];
309     my $source = @{$msg_hash->{'source'}}[0];
310     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
312     # test whether content is an empty hash or a string which is required
313         my $content = @{$msg_hash->{$header}}[0];
314     if(ref($content) eq "HASH") { $content = ""; }
316     # clean up header
317     $header =~ s/CLMSG_//g;
319     my $sql_statement = "UPDATE $main::job_queue_tn ".
320             "SET status='processing', result='$header "."$content', modified='1' ".
321             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
322     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
323     my $res = $main::job_db->update_dbentry($sql_statement);
324     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
326     return; 
330 ## @method TASKBEGIN()
331 # @details Message reports a starting FAI task. If the task is equal to 'finish', 'faiend' or 'savelog', job at job_queue_db is being set to status 'done' and FAI state is being set to 'localboot'. If task is equal to 'chboot', 'test' or 'confdir', just do nothing. In all other cases, job at job_queue_db is going to be updated or created if not exists. 
332 # @param msg - STRING - xml message with tag 'macaddress'.
333 # @param msg_hash - HASHREF - message information parsed into a hash
334 # @param session_id - INTEGER - POE session id of the processing of this message
335 sub TASKBEGIN {
336     my ($msg, $msg_hash, $session_id) = @_;
337     my $header = @{$msg_hash->{'header'}}[0];
338     my $source = @{$msg_hash->{'source'}}[0];
339     my $target = @{$msg_hash->{'target'}}[0];
340     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
342     # test whether content is an empty hash or a string which is required
343         my $content = @{$msg_hash->{$header}}[0];
344     if(ref($content) eq "HASH") { $content = ""; }
346     # clean up header
347     $header =~ s/CLMSG_//g;
349     # TASKBEGIN eq finish or faiend 
350     if (($content eq 'finish') 
351                         || ($content eq 'faiend')
352                         || ($content eq 'savelog')
353                         ) {
354         my $sql_statement = "UPDATE $main::job_queue_tn ".
355             "SET status='done', result='$header "."$content', modified='1' ".
356             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
357         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
358         my $res = $main::job_db->update_dbentry($sql_statement);
359         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
360         
361         # set fai_state to localboot
362         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
364         # TASKBEGIN eq chboot
365         } elsif (($content eq 'chboot')
366                 || ($content eq 'test')
367                 || ($content eq 'confdir')
368                 ) {
369                 # just ignor this client message
370                 # do nothing
372         # other TASKBEGIN msgs
373     } else {
374                 # select processing jobs for host
375                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
376                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
377                 my $res = $main::job_db->select_dbentry($sql_statement);
379                 # there is exactly one job entry in queue for this host
380                 if (keys(%$res) == 1) {
381                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
382                         my $sql_statement = "UPDATE $main::job_queue_tn ".
383                 "SET result='$header $content', modified='1', siserver='localhost' ".
384                 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
385                         my $err = $main::job_db->update_dbentry($sql_statement);
386                         if (not defined  $err) {
387                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
388                         }
389                         
390                 # there is no entry or more than one enties
391                 } else {
392                         # in case of more than one running jobs in queue, delete all jobs
393                         if (keys(%$res) > 1) {
394                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
395                                                                 "delete entries", 7); 
397                 # set job to status 'done', job will be deleted automatically
398                 my $sql_statement = "UPDATE $main::job_queue_tn ".
399                     "SET status='done', modified='1'".
400                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
401                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
402                 my $res = $main::job_db->update_dbentry( $sql_statement );
404                         }
405                 
406                         # in case of no and more than one running jobs in queue, add one single job
407                         # resolve plain name for host $macaddress
408                         my $plain_name;
409                         my $ldap_handle = &main::get_ldap_handle($session_id);
410                         if( not defined $ldap_handle ) {
411                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
412                                 $plain_name = "none";
414                         # try to fetch a 'real name'
415                         } else {
416                                 my $mesg = $ldap_handle->search(
417                                                 base => $main::ldap_base,
418                                                 scope => 'sub',
419                                                 attrs => ['cn'],
420                                                 filter => "(macAddress=$macaddress)");
421                                 if($mesg->code) {
422                                         &main::daemon_log($mesg->error, 1);
423                                         $plain_name = "none";
424                                 } else {
425                                         my $entry= $mesg->entry(0);
426                                         $plain_name = $entry->get_value("cn");
427                                 }
428                         }
430             # In any case add a new job to job queue
431                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
432                         my $func_dic = {table=>$main::job_queue_tn,
433                                         primkey=>['macaddress', 'headertag'],
434                                         timestamp=>&get_time,
435                                         status=>'processing',
436                                         result=>"$header $content",
437                                         progress=>'none',
438                                         headertag=>'trigger_action_reinstall',
439                                         targettag=>$target,
440                                         xmlmessage=>'none',
441                                         macaddress=>$macaddress,
442                                         plainname=>$plain_name,
443                     modified=>'1',
444                     siserver=>'localhost',
445                         };
446                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
447                         if ($err != 0)  {
448                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
449                         }
450                 }
451     }
453     return; 
457 ## @method TASKEND()
458 # @details Message reports a finished FAI task. If task is equal to 'savelog', job at job_queue_db is going to be set to status 'done'. Otherwise, job is going to be updated. 
459 # @param msg - STRING - xml message with tag 'macaddress'.
460 # @param msg_hash - HASHREF - message information parsed into a hash
461 # @param session_id - INTEGER - POE session id of the processing of this message
462 sub TASKEND {
463     my ($msg, $msg_hash, $session_id) = @_;
464     my $header = @{$msg_hash->{'header'}}[0];
465     my $target = @{$msg_hash->{'target'}}[0];
466     my $source = @{$msg_hash->{'source'}}[0];
467     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
469     # test whether content is an empty hash or a string which is required
470     my $content = @{$msg_hash->{$header}}[0];
471     if(ref($content) eq "HASH") { $content = ""; }
473     # clean up header
474     $header =~ s/CLMSG_//g;
476         if ($content eq "savelog 0") {
477                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
478         
479         # set job to status 'done', job will be deleted automatically
480         my $sql_statement = "UPDATE $main::job_queue_tn ".
481                                         "SET status='done', modified='1'".
482                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
483         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
484         my $res = $main::job_db->update_dbentry( $sql_statement );
486         } else {
487         my $sql_statement = "UPDATE $main::job_queue_tn ".
488             "SET status='processing', result='$header "."$content', modified='1' ".
489             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
490         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
491         my $res = $main::job_db->update_dbentry($sql_statement);
492         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
493         }
495     return; 
499 ## @method TASKERROR()
500 # @details Message reports a FAI error. Job at job_queue_db is going to be updated. 
501 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
502 # @param msg_hash - HASHREF - message information parsed into a hash
503 # @param session_id - INTEGER - POE session id of the processing of this message
504 sub TASKERROR {
505     my ($msg, $msg_hash, $session_id) = @_;
506     my $header = @{$msg_hash->{'header'}}[0];
507     my $source = @{$msg_hash->{'source'}}[0];
508     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
510     # clean up header
511     $header =~ s/CLMSG_//g;
513     # test whether content is an empty hash or a string which is required
514     my $content = @{$msg_hash->{$header}}[0];
515     if(ref($content) eq "HASH") { $content = ""; } 
517         # set fai_state to localboot
518         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
519                 
520     my $sql_statement = "UPDATE $main::job_queue_tn ".
521             "SET status='processing', result='$header "."$content', modified='1' ".
522             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
523     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
524     my $res = $main::job_db->update_dbentry($sql_statement);
525     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
527     return; 
531 ## @method HOOK()
532 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated. 
533 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
534 # @param msg_hash - HASHREF - message information parsed into a hash
535 # @param session_id - INTEGER - POE session id of the processing of this message
536 sub HOOK {
537     my ($msg, $msg_hash, $session_id) = @_;
538     my $header = @{$msg_hash->{'header'}}[0];
539     my $source = @{$msg_hash->{'source'}}[0];
540     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
542     # clean up header
543     $header =~ s/CLMSG_//g;
545     # test whether content is an empty hash or a string which is required
546         my $content = @{$msg_hash->{$header}}[0];
547     if(not ref($content) eq "STRING") { $content = ""; }
549     my $sql_statement = "UPDATE $main::job_queue_tn ".
550             "SET status='processing', result='$header "."$content', modified='1' ".
551             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
552     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
553     my $res = $main::job_db->update_dbentry($sql_statement);
554     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
556     return;
559 =pod
561 =head1 NAME
563 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
565 =head1 SYNOPSIS
567  use GOSA::GosaSupportDaemon;
568  use MIME::Base64;
570 =head1 DESCRIPTION
572 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients. 
574 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
576 =head1 METHODS
578 =over 4
580 =item get_events ( )
582 =item confirm_usr_msg ( )
584 =item PROGRESS ( )
586 =item FAIREBOOT ( )
588 =item TASKSKIP ( )
590 =item TASKBEGIN ( )
592 =item TASKEND ( )
594 =item TASKERROR ( )
596 =item HOOK ( )
598 =item GOTOACTIVATION ( )
600 =item LOGIN ( )
602 =item LOGOUT ( )
604 =item CURRENTLY_LOGGED_IN ( )
606 =item save_fai_log ( )
608 =back
610 =head1 BUGS
612 Please report any bugs, or post any suggestions, to the GOsa mailing list E<lt>gosa-devel@oss.gonicus.deE<gt> or to L<https://oss.gonicus.de/labs/gosa>
614 =head1 COPYRIGHT
616 This code is part of GOsa (L<http://www.gosa-project.org>)
618 Copyright (C) 2003-2008 GONICUS GmbH
620 This program is distributed in the hope that it will be useful,
621 but WITHOUT ANY WARRANTY; without even the implied warranty of
622 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
623 GNU General Public License for more details.
625 =cut
628 1;