diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server
index 520ba5e0003086dd3b38dc7766e4e5b375de78d6..1dd69157831df62552ae5277a4f56412f38b6b34 100755 (executable)
--- a/gosa-si/gosa-si-server
+++ b/gosa-si/gosa-si-server
#
# OPTIONS: ---
# REQUIREMENTS: libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl
#
# OPTIONS: ---
# REQUIREMENTS: libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl
-# libipc-shareable-perl libdata-dumper-simple-perl
-# libdbd-sqlite3-perl libnet-ldap-perl
+# libdata-dumper-simple-perl libdbd-sqlite3-perl libnet-ldap-perl
# BUGS: ---
# NOTES:
# AUTHOR: (Andreas Rettenberger), <rettenberger@gonicus.de>
# BUGS: ---
# NOTES:
# AUTHOR: (Andreas Rettenberger), <rettenberger@gonicus.de>
use Fcntl;
use IO::Socket::INET;
use Fcntl;
use IO::Socket::INET;
+use IO::Handle;
+use IO::Select;
+use Symbol qw(qualify_to_ref);
use Crypt::Rijndael;
use MIME::Base64;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use Crypt::Rijndael;
use MIME::Base64;
use Digest::MD5 qw(md5 md5_hex md5_base64);
use Sys::Syslog qw( :DEFAULT setlogsock);
use Cwd;
use File::Spec;
use Sys::Syslog qw( :DEFAULT setlogsock);
use Cwd;
use File::Spec;
-use IPC::Shareable qw( :lock);
-IPC::Shareable->clean_up_all;
use GOSA::GosaSupportDaemon;
use GOSA::DBsqlite;
use GOSA::GosaSupportDaemon;
use GOSA::DBsqlite;
+use threads;
my $modules_path = "/usr/lib/gosa-si/modules";
use lib "/usr/lib/gosa-si/modules";
my $modules_path = "/usr/lib/gosa-si/modules";
use lib "/usr/lib/gosa-si/modules";
"bus" =>
{"bus_activ" => [\$bus_activ, "on"],
"bus_passwd" => [\$bus_passwd, ""],
"bus" =>
{"bus_activ" => [\$bus_activ, "on"],
"bus_passwd" => [\$bus_passwd, ""],
- "bus_ip" => [\$bus_ip, ""],
+ "bus_ip" => [\$bus_ip, "0.0.0.0"],
"bus_port" => [\$bus_port, "20080"],
},
"server" =>
{"server_activ" => [\$server_activ, "on"],
"bus_port" => [\$bus_port, "20080"],
},
"server" =>
{"server_activ" => [\$server_activ, "on"],
- "server_ip" => [\$server_ip, ""],
+ "server_ip" => [\$server_ip, "0.0.0.0"],
"server_port" => [\$server_port, "20081"],
"server_passwd" => [\$server_passwd, ""],
"max_clients" => [\$max_clients, 100],
"server_port" => [\$server_port, "20081"],
"server_passwd" => [\$server_passwd, ""],
"max_clients" => [\$max_clients, 100],
},
"gosa" =>
{"gosa_activ" => [\$gosa_activ, "on"],
},
"gosa" =>
{"gosa_activ" => [\$gosa_activ, "on"],
- "gosa_ip" => [\$gosa_ip, ""],
+ "gosa_ip" => [\$gosa_ip, "0.0.0.0"],
"gosa_port" => [\$gosa_port, "20082"],
"gosa_passwd" => [\$gosa_passwd, "none"],
},
"gosa_port" => [\$gosa_port, "20082"],
"gosa_passwd" => [\$gosa_passwd, "none"],
},
if( -r $cfg_file ) {
$cfg = Config::IniFiles->new( -file => $cfg_file );
} else {
if( -r $cfg_file ) {
$cfg = Config::IniFiles->new( -file => $cfg_file );
} else {
- print STDERR "Couldn't read config file!";
+ print STDERR "Couldn't read config file!\n";
}
} else {
$cfg = Config::IniFiles->new() ;
}
} else {
$cfg = Config::IniFiles->new() ;
# RETURNS: nothing
# DESCRIPTION: function for logging
#===============================================================================
# RETURNS: nothing
# DESCRIPTION: function for logging
#===============================================================================
-sub daemon_log {
+sub daemon_log : locked {
# log into log_file
my( $msg, $level ) = @_;
if(not defined $msg) { return }
# log into log_file
my( $msg, $level ) = @_;
if(not defined $msg) { return }
return }
chomp($msg);
if($level <= $verbose){
return }
chomp($msg);
if($level <= $verbose){
- print LOG_HANDLE "$level $msg\n";
- if($foreground) { print $msg."\n" }
+ my ($seconds, $minutes, $hours, $monthday, $month,
+ $year, $weekday, $yearday, $sommertime) = localtime(time);
+ $hours = $hours < 10 ? $hours = "0".$hours : $hours;
+ $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
+ $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
+ my @monthnames = ("Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+ $month = $monthnames[$month];
+ $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
+ $year+=1900;
+ my $name = $0;
+ $name =~ s/\.\///;
+
+ my $log_msg = "$month $monthday $hours:$minutes:$seconds $name $msg\n";
+ print LOG_HANDLE $log_msg;
+ if( $foreground ) {
+ print STDERR $log_msg;
+ }
}
}
+ close( LOG_HANDLE );
}
}
-# close( LOG_HANDLE );
#log into syslog
# my ($msg, $level, $facility) = @_;
# if(not defined $msg) {return}
#log into syslog
# my ($msg, $level, $facility) = @_;
# if(not defined $msg) {return}
}
}
}
}
-
-#=== FUNCTION ================================================================
-# NAME: get_ip_and_mac
-# PARAMETERS: nothing
-# RETURNS: (ip, mac)
-# DESCRIPTION: executes /sbin/ifconfig and parses the output, the first occurence
-# of a inet address is returned as well as the mac address in the line
-# above the inet address
-#===============================================================================
-sub get_ip_and_mac {
- my $ip = "0.0.0.0.0"; # Defualt-IP
- my $mac = "00:00:00:00:00:00"; # Default-MAC
- my @ifconfig = qx(/sbin/ifconfig);
- foreach(@ifconfig) {
- if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) {
- $mac = "$1:$2:$3:$4:$5:$6";
- next;
- }
- if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) {
- $ip = "$1.$2.$3.$4";
- last;
- }
- }
- return ($ip, $mac);
-}
-
-
-
#=== FUNCTION ================================================================
# NAME: import_modules
# PARAMETERS: module_path - string - abs. path to the directory the modules
#=== FUNCTION ================================================================
# NAME: import_modules
# PARAMETERS: module_path - string - abs. path to the directory the modules
}
eval { require $file; };
if ($@) {
}
eval { require $file; };
if ($@) {
- daemon_log("ERROR: gosa-sd could not load module $file", 1);
+ daemon_log("ERROR: gosa-si-server could not load module $file", 1);
daemon_log("$@", 5);
daemon_log("$@", 5);
- next;
- }
- my $mod_name = $1;
- #my $module_tag_hash = eval( $mod_name.'::get_module_tags()' );
-
- my $info = eval($mod_name.'::get_module_info()');
- my ($input_address, $input_key, $input, $input_active, $input_type) = @{$info};
- $known_modules->{$mod_name} = $info;
+ } else {
+ my $mod_name = $1;
+ my $info = eval($mod_name.'::get_module_info()');
+ my ($input_address, $input_key, $input, $input_active, $input_type) = @{$info};
+ $known_modules->{$mod_name} = $info;
- daemon_log("module $mod_name loaded", 1);
+ daemon_log("module $mod_name loaded", 1);
+ }
}
# for debugging
}
# for debugging
#===============================================================================
sub sig_int_handler {
my ($signal) = @_;
#===============================================================================
sub sig_int_handler {
my ($signal) = @_;
- if($server){
- close($server);
- daemon_log("daemon server closed", 1);
- }
- if( -p $arp_fifo_path ) {
- close $arp_fifo ;
- unlink($arp_fifo_path) ;
- daemon_log("ARP_FIFO closed", 1) ;
- }
- if($gosa_server){
- close($gosa_server);
- daemon_log("gosa server closed", 1);
- }
-
- print STDERR "$signal\n";
-
+ daemon_log("shutting down gosa-si-server", 1);
exit(1);
}
$SIG{INT} = \&sig_int_handler;
exit(1);
}
$SIG{INT} = \&sig_int_handler;
my $answer;
my %act_modules = %$known_modules;
while( my ($module, $info) = each(%act_modules)) {
my $answer;
my %act_modules = %$known_modules;
while( my ($module, $info) = each(%act_modules)) {
- &daemon_log("##########", 5);
my $tmp = &{ $module."::process_incoming_msg" }($msg);
if (defined $tmp) {
$answer = $tmp;
}
my $tmp = &{ $module."::process_incoming_msg" }($msg);
if (defined $tmp) {
$answer = $tmp;
}
- &daemon_log("##########", 5);
}
}
-
- #&print_known_daemons();
- #&print_known_clients();
-
daemon_log("processing of msg finished", 5);
if (defined $answer) {
print $PARENT_wr $answer."\n";
daemon_log("processing of msg finished", 5);
if (defined $answer) {
print $PARENT_wr $answer."\n";
- daemon_log("with answer: $answer", 5);
- daemon_log(" ", 5);
+ print $PARENT_wr "ENDMESSAGE\n";
+ my $len_answer = length $answer;
+ daemon_log("with answer: length of answer: $len_answer", 7);
+ daemon_log("\n$answer", 7);
} else {
print $PARENT_wr "done"."\n";
} else {
print $PARENT_wr "done"."\n";
- daemon_log(" ", 5);
+ print $PARENT_wr "ENDMESSAGE\n";
}
redo;
}
}
redo;
}
return;
}
return;
}
-
-#=== FUNCTION ================================================================
-# NAME: add_content2known_clients
-# PARAMETERS: hostname - string - ip address and port of host (required)
-# status - string - (optional)
-# passwd - string - (optional)
-# mac_address - string - (optional)
-# events - string - event of client, executable skripts
-# under /etc/gosac/events
-# RETURNS: nothing
-# DESCRIPTION: nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-#sub update_known_clients {
-# my $arg = {
-# hostname => undef, status => undef, hostkey => undef,
-# macaddress => undef, events => undef, timestamp=>undef,
-# @_ };
-# my $hostname = $arg->{hostname};
-# my $status = $arg->{status};
-# my $hostkey = $arg->{hostkey};
-# my $macaddress = $arg->{macaddress};
-# my $events = $arg->{events};
-# my $timestamp = $arg->{timestamp};
+#sub sysreadline(*;$) {
+# my ($hd, $timeout) = @_;
#
#
-# if (not defined $hostname) {
-# daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1);
-# return;
-# }
+# $hd = qualify_to_ref($hd, caller());
+# my $infinitely_patient = (@_ == 1 || $timeout < 0);
+# my $start_time = time();
+# my $selector = IO::Select->new();
+# $selector->add($hd);
+# my $line = "";
#
#
-# my $change_entry = { table=>'known_clients',
-# where=>'hostname',
-# timestamp=>&get_time,
-# };
-#
-#
-# if (defined $status) {
-# $change_entry->{status} = $status;
-# }
-# if (defined $hostkey) {
-# $change_entry->{hostkey} = $hostkey;
-# }
-# if (defined $macaddress) {
-# $change_entry->{macaddress} = $macaddress;
-# }
-# if (defined $events) {
-# $change_entry->{events} = $events;
-# }
-#
-# $known_clients->change_dbentry($change_entry);
-# return;
-#}
-
-
-#=== FUNCTION ================================================================
-# NAME:
-# PARAMETERS:
-# RETURNS:
-# DESCRIPTION:
-#===============================================================================
-#sub clean_up_known_clients {
-# my ($address) = @_ ;
-#
-# if (not exists $known_clients->{$address}) {
-# daemon_log("cannot prune known_clients from $address, client not known", 5);
-# return;
-# }
-#
-# delete $known_clients->{$address};
-#
-# # send bus a msg that address was deleted from known_clients
-# my $out_hash = &create_xml_hash('delete_client', $server_address, $bus_address, $address);
-# &send_msg_hash2bus($out_hash);
-#
-# daemon_log("client $address deleted from known_clients because of multiple down time", 3);
-# return;
-#}
-
-
-#=== FUNCTION ================================================================
-# NAME: update_known_clients
-# PARAMETERS: hostname - string - ip address and port of host (required)
-# status - string - (optional)
-# passwd - string - (optional)
-# client - string - ip address and port of client (optional)
-# RETURNS: nothing
-# DESCRIPTION: nome est omen and updates each time the timestamp of hostname
-#===============================================================================
-#sub update_known_clients {
-# my $arg = {
-# hostname => undef, status => undef, passwd => undef,
-# mac_address => undef, events => undef,
-# @_ };
-# my $hostname = $arg->{hostname};
-# my $status = $arg->{status};
-# my $passwd = $arg->{passwd};
-# my $mac_address = $arg->{mac_address};
-# my $events = $arg->{events};
+#SLEEP:
+# until( at_eol($line)) {
+# if (not $infinitely_patient) {
+# return $line if time() > ($start_time + $timeout);
+# }
+# next SLEEP unless $selector->can_read(1.0);
+#INPUT_READY:
+# while( $selector->can_read(0.0)) {
+# my $was_blocking = $hd->blocking(0);
+#CHAR: while (sysread($hd, my $nextbyte, 1)) {
+# $line .= $nextbyte;
+# last CHAR if $nextbyte eq "\n";
#
#
-# if (not defined $hostname) {
-# daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1);
-# return;
+# }
+# $hd->blocking($was_blocking);
+# next SLEEP unless at_eol($line);
+# last INPUT_READY;
+# }
# }
# }
+# return $line;
+#}
#
#
-# my ($seconds, $minutes, $hours, $monthday, $month,
-# $year, $weekday, $yearday, $sommertime) = localtime(time);
-# $hours = $hours < 10 ? $hours = "0".$hours : $hours;
-# $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
-# $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
-# $month+=1;
-# $month = $month < 10 ? $month = "0".$month : $month;
-# $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
-# $year+=1900;
-# my $t = "$year$month$monthday$hours$minutes$seconds";
-#
-# if (defined $status) {
-# $known_clients->{$hostname}->{status} = $status;
-# }
-# if (defined $passwd) {
-# $known_clients->{$hostname}->{passwd} = $passwd;
-# }
-# if (defined $mac_address) {
-# $known_clients->{$hostname}->{mac_address} = $mac_address;
-# }
-# if (defined $events) {
-# $known_clients->{$hostname}->{events} = $events;
-# }
-# $known_clients_db->{$hostname}->{timestamp} = $t;
-# return;
+#sub at_eol($) {
+# $_[0] =~ /\n\z/ ;
#}
#}
-
-
-
-
-
-
#==== MAIN = main ==============================================================
# parse commandline options
#==== MAIN = main ==============================================================
# parse commandline options
$SIG{CHLD} = 'IGNORE';
$SIG{CHLD} = 'IGNORE';
-# restart daemon log file
-if(-e $log_file ) { unlink $log_file }
-daemon_log(" ", 1);
-daemon_log("$0 started!", 1);
+# forward error messages to logfile
+if( ! $foreground ) {
+ open(STDERR, '>>', $log_file);
+ open(STDOUT, '>>', $log_file);
+}
-# Just fork, if we"re not in foreground mode
+# Just fork, if we are not in foreground mode
if( ! $foreground ) {
if( ! $foreground ) {
- $pid = fork();
+ chdir '/' or die "Can't chdir to /: $!";
+ $pid = fork;
+ setsid or die "Can't start a new session: $!";
+ umask 0;
} else {
$pid = $$;
}
} else {
$pid = $$;
}
};
}
};
}
+daemon_log(" ", 1);
+daemon_log("$0 started!", 1);
+
+# delete old DBsqlite lock files
+system('rm -f /tmp/gosa_si_lock*');
+
# connect to gosa-si job queue
# connect to gosa-si job queue
-my @job_col_names = ("timestamp", "status", "result", "headertag", "targettag", "xmlmessage", "macaddress");
+my @job_col_names = ("id", "timestamp", "status", "result", "headertag", "targettag", "xmlmessage", "macaddress");
$job_db = GOSA::DBsqlite->new($job_queue_file_name);
$job_db->create_table('jobs', \@job_col_names);
$job_db = GOSA::DBsqlite->new($job_queue_file_name);
$job_db->create_table('jobs', \@job_col_names);
#}
#
#}
#
-
##################################
#everything ready, okay, lets start
##################################
##################################
#everything ready, okay, lets start
##################################
if (vec($rout, fileno $fhd, 1) ) {
daemon_log("process child $pid is ready to read", 5);
if (vec($rout, fileno $fhd, 1) ) {
daemon_log("process child $pid is ready to read", 5);
-
- $fhd->blocking(1);
- my $in_msg = <$fhd>;
- $fhd->blocking(0);
- my $part_in_msg;
- while ($part_in_msg = <$fhd>) {
- if (not defined $part_in_msg) {
+
+ my $in_msg;
+ while (1) {
+ my $part_in_msg = <$fhd>;
+ if( $part_in_msg eq "ENDMESSAGE\n") {
last;
}
$in_msg .= $part_in_msg;
}
chomp($in_msg);
last;
}
$in_msg .= $part_in_msg;
}
chomp($in_msg);
-
- daemon_log("process child read: $in_msg", 5);
+
if (not defined $in_msg) {
next;
} elsif ($in_msg =~ "done") {
if (not defined $in_msg) {
next;
} elsif ($in_msg =~ "done") {
+ daemon_log("process child read: $in_msg", 7);
delete $busy_child{$pid};
$free_child{$pid} = $child_hash;
delete $busy_child{$pid};
$free_child{$pid} = $child_hash;
-
+
} else {
} else {
+ daemon_log("process child read:", 7);
+ daemon_log("\n$in_msg", 8);
# send computed answer back to connected client
my $act_client = $busy_child{$pid}{client_ref};
print $act_client $in_msg."\n";
# send computed answer back to connected client
my $act_client = $busy_child{$pid}{client_ref};
print $act_client $in_msg."\n";
-
- #my $act_pipe = $busy_child{$pid}{pipe_rd};
delete $busy_child{$pid};
$free_child{$pid} = $child_hash;
delete $busy_child{$pid};
$free_child{$pid} = $child_hash;
- # give the client a chance to read
- sleep(2);
- close ($act_client);
}
}
}
}
}
}
while( my ($id, $hit) = each %{$res} ) {
while( my ($id, $hit) = each %{$res} ) {
- my $jobdb_id = $hit->{ROWID};
+ my $jobdb_id = $hit->{id};
my $macaddress = $hit->{macaddress};
my $job_msg_hash = &transform_msg2hash($hit->{xmlmessage});
my $out_msg_hash = $job_msg_hash;
my $macaddress = $hit->{macaddress};
my $job_msg_hash = &transform_msg2hash($hit->{xmlmessage});
my $out_msg_hash = $job_msg_hash;
&daemon_log("xml message: $hit->{xmlmessage}", 5);
my $update_hash = { table=>$job_queue_table_name,
update=> [ { status=>['error'], result=>["no host found for mac address"] } ],
&daemon_log("xml message: $hit->{xmlmessage}", 5);
my $update_hash = { table=>$job_queue_table_name,
update=> [ { status=>['error'], result=>["no host found for mac address"] } ],
- where=> [ { ROWID=>[$jobdb_id] } ],
+ where=> [ { id=>[$jobdb_id] } ],
};
my $res = $job_db->update_dbentry($update_hash);
};
my $res = $job_db->update_dbentry($update_hash);
my $error = &send_msg_hash2address($out_msg_hash, "$gosa_ip:$gosa_port", $gosa_passwd);
my $error = &send_msg_hash2address($out_msg_hash, "$gosa_ip:$gosa_port", $gosa_passwd);
-#######################
-# TODO exchange ROWID with jobid, insert column jobid in table jobs befor
-
if ($error == 0) {
if ($error == 0) {
- my $sql = "UPDATE '$job_queue_table_name' SET status='processing', targettag='$target' WHERE ROWID='$jobdb_id'";
+ my $sql = "UPDATE '$job_queue_table_name' SET status='processing', targettag='$target' WHERE id='$jobdb_id'";
my $res = $job_db->exec_statement($sql);
} else {
my $update_hash = { table=>$job_queue_table_name,
update=> [ { status=>'error' } ],
my $res = $job_db->exec_statement($sql);
} else {
my $update_hash = { table=>$job_queue_table_name,
update=> [ { status=>'error' } ],
- where=> [ { ROWID=>$jobdb_id } ],
+ where=> [ { id=>$jobdb_id } ],
};
my $res = $job_db->update_dbentry($update_hash);
}
};
my $res = $job_db->update_dbentry($update_hash);
}