From: rettenbe Date: Thu, 24 Jan 2008 17:18:54 +0000 (+0000) Subject: add 'order by' xml-tag to GosaPackages X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=9228851e746377193a19563a1b296aeda55fd927;p=gosa.git add 'order by' xml-tag to GosaPackages and some other small bugfixes git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@8599 594d385d-05f5-0310-b6e9-bd551577e9d8 --- diff --git a/gosa-si/gosa-si-bus b/gosa-si/gosa-si-bus index a5d50f1d2..dd848c182 100755 --- a/gosa-si/gosa-si-bus +++ b/gosa-si/gosa-si-bus @@ -292,34 +292,34 @@ sub get_interfaces { # DESCRIPTION: Uses ioctl to get mac address directly from system. #=============================================================================== sub get_mac { - my $ifreq= shift; - my $result; - if ($ifreq && length($ifreq) > 0) { - if($ifreq eq "all") { - $result = "00:00:00:00:00:00"; - } else { - my $SIOCGIFHWADDR= 0x8927; # man 2 ioctl_list + my $ifreq= shift; + my $result; + if ($ifreq && length($ifreq) > 0) { + if($ifreq eq "all") { + $result = "00:00:00:00:00:00"; + } else { + my $SIOCGIFHWADDR= 0x8927; # man 2 ioctl_list - # A configured MAC Address should always override a guessed value - if ($bus_mac_address and length($bus_mac_address) > 0) { - return $bus_mac_address; - } + # A configured MAC Address should always override a guessed value + if ($bus_mac_address and length($bus_mac_address) > 0) { + return $bus_mac_address; + } - socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip') - or die "socket: $!"; + socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip') + or die "socket: $!"; - if(ioctl SOCKET, $SIOCGIFHWADDR, $ifreq) { - my ($if, $mac)= unpack 'h36 H12', $ifreq; + if(ioctl SOCKET, $SIOCGIFHWADDR, $ifreq) { + my ($if, $mac)= unpack 'h36 H12', $ifreq; - if (length($mac) > 0) { - $mac=~ m/^([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/; - $mac= sprintf("%s:%s:%s:%s:%s:%s", $1, $2, $3, $4, $5, $6); - $result = $mac; - } - } + if (length($mac) > 0) { + $mac=~ m/^([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/; + $mac= sprintf("%s:%s:%s:%s:%s:%s", $1, $2, $3, $4, $5, $6); + $result = $mac; } + } } - return $result; + } + return $result; } #=== FUNCTION ================================================================ @@ -550,7 +550,8 @@ sub process_incoming_msg { # check wether incoming msg is from a bus_known_server if( not defined $msg ) { - my $query_res = $bus_known_server_db->select_dbentry( {table=>'bus_known_server'} ); + my $sql_statement= "SELECT * FROM bus_known_server"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); while( my ($hit_num, $hit) = each %{ $query_res } ) { $host_name = $hit->{hostname}; if( not $host_name =~ "^$host") { @@ -613,7 +614,8 @@ sub process_incoming_msg { } elsif ($target eq "*"){ # msg is for all server - my $query_res = $bus_known_server_db->select_dbentry( {table=>'known_server'} ); + my $sql_statement= "SELECT * FROM known_server"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); while( my ($hit_num, $hit) = each %{ $query_res } ) { $host_name = $hit->{hostname}; $host_key = $hit->{hostkey}; @@ -628,14 +630,16 @@ sub process_incoming_msg { my $target_address; foreach $target_address (@targets) { - my $query_res = $bus_known_server_db->select_dbentry( {table=>'known_server', hostname=>$target_address} ); + my $sql_statement= "SELECT * FROM known_server WHERE hostname='$target_address'"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); if( 1 == keys %{$query_res} ) { $host_key = $query_res->{1}->{hostkey}; &send_msg_hash2address($msg_hash, $target_address, $host_key); next; } else { - $query_res = $bus_known_server_db->select_dbentry( {table=>'known_server'} ); + my $sql_statement= "SELECT * FROM known_server"; + $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); while( my ($hit_num, $hit) = each %{$query_res} ) { my $host_name = $hit->{hostname}; my $host_key = $hit->{hostkey}; @@ -659,17 +663,6 @@ sub process_incoming_msg { } -#=== FUNCTION ================================================================ -# NAME: get_content_of_known_daemons -# PARAMETERS: -# RETURNS: -# DESCRIPTION: -#=============================================================================== -#sub get_content_of_known_daemons { -# my ($host, $content) = @_; -# return; -#} - #=== FUNCTION ================================================================ # NAME: create_passwd @@ -686,162 +679,6 @@ sub create_passwd { } -#=== FUNCTION ================================================================ -# NAME: create_ciphering -# PARAMETERS: passwd - string - used to create ciphering -# RETURNS: cipher - object -# DESCRIPTION: creates a Crypt::Rijndael::MODE_CBC object with passwd as key -#=============================================================================== -#sub create_ciphering { -# my ($passwd) = @_; -# $passwd = substr(md5_hex("$passwd") x 32, 0, 32); -# my $iv = substr(md5_hex('GONICUS GmbH'),0, 16); -# -# my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC()); -# $my_cipher->set_iv($iv); -# return $my_cipher; -#} - - -#=== FUNCTION ================================================================ -# NAME: encrypt_msg -# PARAMETERS: msg - string - message to encrypt -# my_cipher - ref - reference to a Crypt::Rijndael object -# RETURNS: crypted_msg - string - crypted message -# DESCRIPTION: crypts the incoming message with the Crypt::Rijndael module -#=============================================================================== -#sub encrypt_msg { -# my ($msg, $my_cipher) = @_; -# if(not defined $my_cipher) { print "no cipher object\n"; } -# $msg = "\0"x(16-length($msg)%16).$msg; -# my $crypted_msg = $my_cipher->encrypt($msg); -# chomp($crypted_msg = &encode_base64($crypted_msg)); -# return $crypted_msg; -#} - - -#=== FUNCTION ================================================================ -# NAME: decrypt_msg -# PARAMETERS: crypted_msg - string - message to decrypt -# my_cipher - ref - reference to a Crypt::Rijndael object -# RETURNS: msg - string - decrypted message -# DESCRIPTION: decrypts the incoming message with the Crypt::Rijndael module -#=============================================================================== -#sub decrypt_msg { -# my ($crypted_msg, $my_cipher) = @_ ; -# $crypted_msg = &decode_base64($crypted_msg); -# my $msg = $my_cipher->decrypt($crypted_msg); -# $msg =~ s/^\0*//g; -# return $msg; -#} - - -#=== FUNCTION ================================================================ -# NAME: create_xml_hash -# PARAMETERS: header - string - message header (required) -# source - string - where the message come from (required) -# target - string - where the message should go to (required) -# [header_value] - string - something usefull (optional) -# RETURNS: hash - hash - nomen est omen -# DESCRIPTION: creates a key-value hash, all values are stored in a array -#=============================================================================== -#sub create_xml_hash { -# my ($header, $source, $target, $header_value) = @_ ; -# -# if (not defined $header || not defined $source || not defined $target) { -# daemon_log("ERROR: create_xml_hash function is invoked with uncompleted parameters", 7); -# } -# -# my $hash = { -# header => [$header], -# source => [$source], -# target => [$target], -# $header => [$header_value], -# }; -# #daemon_log("create_xml_hash:", 7), -# #chomp(my $tmp = Dumper $hash); -# #daemon_log("\t$tmp\n", 7); -# return $hash -#} - - -#=== FUNCTION ================================================================ -# NAME: create_xml_string -# PARAMETERS: xml_hash - hash - hash from function create_xml_hash -# RETURNS: xml_string - string - xml string representation of the hash -# DESCRIPTION: transform the hash to a string using XML::Simple module -#=============================================================================== -#sub create_xml_string { -# my ($xml_hash) = @_ ; -# my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml'); -# #$xml_string =~ s/[\n]+//g; -# return $xml_string; -#} - - -#=== FUNCTION ================================================================ -# NAME: add_content2xml_hash -# PARAMETERS: xml_ref - ref - reference to a hash from function create_xml_hash -# element - string - key for the hash -# content - string - value for the hash -# RETURNS: nothing -# DESCRIPTION: add key-value pair to xml_ref, if key alread exists, then append value to list -#=============================================================================== -#sub add_content2xml_hash { -# my ($xml_ref, $element, $content) = @_; -# if(not exists $$xml_ref{$element} ) { -# $$xml_ref{$element} = []; -# } -# my $tmp = $$xml_ref{$element}; -# push(@$tmp, $content); -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: get_content_from_xml_hash -# PARAMETERS: xml_ref - ref - reference of the xml hash -# element - string - key of the value you want -# RETURNS: value - string - if key is either header, target or source -# value - list - for all other keys in xml hash -# DESCRIPTION: -#=============================================================================== -#sub get_content_from_xml_hash { -# my ($xml_ref, $element) = @_; -# my $result = $xml_ref->{$element}; -# if( $element eq "header" || $element eq "target" || $element eq "source") { -# return @$result[0]; -# } -# return @$result; -#} - - -#=== FUNCTION ================================================================ -# NAME: open_socket -# PARAMETERS: PeerAddr - string - something like 192.168.1.1 or 192.168.1.1:10000 -# [PeerPort] - string - necessary if port not appended by PeerAddr -# RETURNS: socket - IO::Socket::INET -# DESCRIPTION: open a socket to PeerAddr -#=============================================================================== -#sub open_socket { -# my ($PeerAddr, $PeerPort) = @_ ; -# if(defined($PeerPort)){ -# $PeerAddr = $PeerAddr.":".$PeerPort; -# } -# my $socket; -# $socket = new IO::Socket::INET(PeerAddr => $PeerAddr , -# Porto => "tcp" , -# Type => SOCK_STREAM, -# Reuse => 1, -# Timeout => 5, -# ); -# if(not defined $socket) { -# return; -# } -# return $socket; -#} - - #=== FUNCTION ================================================================ # NAME: read_from_socket # PARAMETERS: socket - fh - filehandel to read from @@ -873,99 +710,6 @@ sub read_from_socket { } -#=== FUNCTION ================================================================ -# NAME: send_msg_hash2address -# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash -# PeerAddr string - socket address to send msg -# PeerPort string - socket port, if not included in socket address -# RETURNS: nothing -# DESCRIPTION: ???? -#=============================================================================== -#sub send_msg_hash2address { -# my ($msg_hash, $address) = @_ ; -# -# # fetch header for logging -# my $header = &get_content_from_xml_hash($msg_hash, "header"); -# -# # generate xml string -# my $msg_xml = &create_xml_string($msg_hash); -# -# # fetch the appropriated passwd from hash -# my $passwd = $known_daemons->{$address}->{passwd}; -# -# # create a ciphering object -# my $act_cipher = &create_ciphering($passwd); -# -# # encrypt xml msg -# my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); -# -# # open socket -# my $socket = &open_socket($address); -# if(not defined $socket){ -# daemon_log("ERROR: cannot send '$header'-msg to $address , server not reachable", 1); -# return; -# } -# -# # send xml msg -# print $socket $crypted_msg."\n"; -# -# close $socket; -# daemon_log("send '$header'-msg to $address", 5); -# daemon_log("crypted_msg:\n\t$crypted_msg", 7); -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: send_msg_hash2all -# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash -# RETURNS: nothing -# DESCRIPTION: send msg_hash to all registered daemons -#=============================================================================== -#sub send_msg_hash2all { -# my ($msg_hash) = @_; -# -# # fetch header for logging -# my $header = &get_content_from_xml_hash($msg_hash, "header"); -# -# # generate xml string -# my $msg_xml = &create_xml_string($msg_hash); -# -# # fetch a list of all target addresses -# my @targets = keys(%$known_daemons); -# -# # itterates through the list an send each the msg -# foreach my $target (@targets) { -# if($target eq $bus_address) {next}; # do not send msg to bus -# -# # fetch the appropriated passwd -# my $passwd = $known_daemons->{$target}->{passwd}; -# -# # create ciphering object -# my $act_cipher = &create_ciphering($passwd); -# -# # encrypt xml msg -# my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); -# -# # open socket -# my $socket = &open_socket($target); -# if(not defined $socket){ -# daemon_log("ERROR: cannot open socket to $target , server not reachable", 1); -# &update_known_daemons_entry(hostname=>$target, status=>"down"); -# next; -# } -# -# # send xml msg -# print $socket $crypted_msg."\n"; -# -# close $socket; -# daemon_log("send '$header'-msg to $target", 5); -# daemon_log("crypted_msg:\n\t$crypted_msg", 7); -# } -# return; -#} - - #=== FUNCTION ================================================================ # NAME: here_i_am # PARAMETERS: msg_hash - hash - hash from function create_xml_hash @@ -994,10 +738,10 @@ sub here_i_am { &send_msg_hash2address($out_hash, $source, $bus_passwd); # change hostkey, reason - my $update_hash = { table=>'bus_known_server' }; - $update_hash->{where} = [ { hostname=>[$source] } ]; - $update_hash->{update} = [ { hostkey=>[$new_key] } ]; - $bus_known_server_db->update_dbentry($update_hash); + my $where_str= " WHERE hostname='$source'"; + my $update_str= " SET hostkey='$new_key'"; + my $sql_statement= "UPDATE bus_known_server $update_str $where_str"; + $bus_known_server_db->update_dbentry($sql_statement); return; } @@ -1012,11 +756,11 @@ sub here_i_am { sub confirm_new_passwd { my ($msg_hash) = @_ ; my $source = @{$msg_hash->{source}}[0]; + my $sql_statement= "UPDATE bus_known_server ". + "SET status='key_confirmed' ". + "WHERE hostname='$source' "; - my $update_hash = { table=>'bus_known_server' }; - $update_hash->{where} = [ { hostname=>[$source] } ]; - $update_hash->{update} = [ { status=>['key_confirmed'] } ]; - $bus_known_server_db->update_dbentry($update_hash); + $bus_known_server_db->update_dbentry($sql_statement); return; } @@ -1033,15 +777,13 @@ sub ping { my $header = @{$msg_hash->{header}}[0]; my $source = @{$msg_hash->{source}}[0]; - my $update_hash = { table=>'bus_known_server', - where=> [ { hostname=>[$source] } ], - update=> [ { status=>$header } ], - }; - $bus_known_server_db->update_dbentry($update_hash); + my $sql_statement= "UPDATE bus_known_server SET status='$header' WHERE hostname='$source'"; + $bus_known_server_db->update_dbentry($sql_statement); my $out_hash = &create_xml_hash("got_ping", $bus_address, $source); - my $res = $bus_known_server_db->select_dbentry( { table=>'bus_known_server', hostname=>$source } ); + $sql_statement= "SELECT * FROM bus_known_server WHERE hostname='$source'"; + my $res = $bus_known_server_db->select_dbentry( $sql_statement ); my $hostkey = $res->{1}->{hostkey}; &send_msg_hash2address($out_hash, $source, $hostkey); @@ -1049,21 +791,6 @@ sub ping { } -#=== FUNCTION ================================================================ -# NAME: make ping -# PARAMETERS: address - string - address which should be pinged -# RETURNS: nothing -# DESCRIPTION: send ping message to address -#=============================================================================== -#sub make_ping { -# my ($address) = @_; -# daemon_log("ping:$address\n", 1); -# my $out_hash = &create_xml_hash("ping", "$bus_ip:$bus_port", $address); -# &send_msg_hash2address($out_hash, $address); -# return; -#} - - #=== FUNCTION ================================================================ # NAME: got_ping # PARAMETERS: msg_hash - hash - hash from function create_xml_hash @@ -1073,12 +800,9 @@ sub ping { sub got_ping { my ($msg_hash) = @_; my $source = @{$msg_hash->{source}}[0]; - - my $update_hash = { table=>'bus_known_server', - where=> [ { hostname=>[$source] } ], - update=> [ { status=>'got_ping' } ], - }; - $bus_known_server_db->update_dbentry($update_hash); + + my $sql_statement= "UPDATE bus_known_server SET status='got_ping' WHERE hostname='$source'"; + $bus_known_server_db->update_dbentry($sql_statement); return; } @@ -1095,8 +819,9 @@ sub new_client { my $source = @{$msg_hash->{source}}[0]; my $header = @{$msg_hash->{header}}[0]; my $new_client = @{$msg_hash->{$header}}[0]; - - my $res = $bus_known_server_db->select_dbentry( { table=>'bus_known_server', hostname=>$source } ); + + my $sql_statement= "SELECT * FROM bus_known_server WHERE hostname='$source'"; + my $res = $bus_known_server_db->select_dbentry( $sql_statement ); my $clients = $res->{1}->{clients}; # if host has alread more clients, than just append @@ -1106,140 +831,12 @@ sub new_client { $clients = $new_client; } - my $update_hash = { table=>'bus_known_server', - where=>[ {hostname=>[$source] } ], - update=>[ {clients=>[$clients] } ], - }; - - $bus_known_server_db->update_dbentry( $update_hash ); + $sql_statement= "UPDATE bus_known_server SET clients='$clients' WHERE hostname='$source'"; + $bus_known_server_db->update_dbentry( $sql_statement ); return; } -#=== FUNCTION ================================================================ -# NAME: delete_client -# PARAMETERS: msg_hash - hash - hash from function create_xml_hash -# RETURNS: nothing -# DESCRIPTION: process this incoming message -#=============================================================================== -#sub delete_client { -# my ($msg_hash) = @_ ; -# my $source = &get_content_from_xml_hash($msg_hash, "source"); -# my $header = &get_content_from_xml_hash($msg_hash, "header"); -# my $del_client = (&get_content_from_xml_hash($msg_hash, $header))[0]; -# -# if (not exists $known_daemons->{$source}->{$del_client}) { -# daemon_log -# } -# delete $known_daemons->{$source}->{$del_client}; -# -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: print_known_daemons_hash -# PARAMETERS: nothing -# RETURNS: nothing -# DESCRIPTION: nome est omen -#=============================================================================== -#sub print_known_daemons_hash { -# my ($tmp) = @_; -# print "####################################\n"; -# print "# status of known_daemons\n"; -# my $hosts; -# my $host_hash; -# $shmkh->shlock(LOCK_EX); -# my @hosts = keys %$known_daemons; -# foreach my $host (@hosts) { -# my $status = $known_daemons->{$host}->{status} ; -# my $passwd = $known_daemons->{$host}->{passwd}; -# my $timestamp = $known_daemons->{$host}->{timestamp}; -# my @clients = keys %{$known_daemons->{$host}->{clients}}; -# my $client_string = join(", ", @clients); -# print "$host\n"; -# print "\tstatus: $status\n"; -# print "\tpasswd: $passwd\n"; -# print "\ttimestamp: $timestamp\n"; -# print "\tclients: $client_string\n"; -# -# } -# $shmkh->shunlock(LOCK_EX); -# print "####################################\n\n"; -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: create_known_daemons_entry -# PARAMETERS: hostname - string - ip address and port of host -# RETURNS: nothing -# DESCRIPTION: nome est omen -#=============================================================================== -#sub create_known_daemons_entry { -# my ($hostname) = @_; -# $shmkh->shlock(LOCK_EX); -# $known_daemons->{$hostname} = {}; -# $known_daemons->{$hostname}->{status} = "none"; -# $known_daemons->{$hostname}->{passwd} = "none"; -# $known_daemons->{$hostname}->{timestamp} = "none"; -# $known_daemons->{$hostname}->{clients} = {}; -# $shmkh->shunlock(LOCK_EX); -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: update_known_daemons_entry -# 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_daemons_entry { -# my $arg = { -# hostname => undef, status => undef, passwd => undef, -# client => undef, -# @_ }; -# my $hostname = $arg->{hostname}; -# my $status = $arg->{status}; -# my $passwd = $arg->{passwd}; -# my $client = $arg->{client}; -# -# if (not defined $hostname) { -# daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); -# return; -# } -# -# 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"; -# -# $shmkh->shlock(LOCK_EX); -# if (defined $status) { -# $known_daemons->{$hostname}->{status} = $status; -# } -# if (defined $passwd) { -# $known_daemons->{$hostname}->{passwd} = $passwd; -# } -# if (defined $client) { -# $known_daemons->{$hostname}->{clients}->{$client} = ""; -# } -# $known_daemons->{$hostname}->{timestamp} = $t; -# $shmkh->shunlock(LOCK_EX); -# return; -#} - - #==== MAIN = main ============================================================== # parse commandline options @@ -1262,6 +859,9 @@ if(-e $log_file ) { unlink $log_file } daemon_log(" ", 1); daemon_log("$0 started!", 1); +# delete old DBsqlite lock files +system('rm -f /tmp/gosa_si_lock*'); + # forward error messages to logfile if( ! $foreground ) { open(STDERR, '>>', $log_file); @@ -1274,16 +874,16 @@ if( ! $foreground ) { $pid = fork; setsid or die "Can't start a new session: $!"; umask 0; +} else { + $pid = $$; } -else { $pid = $$; } - # Do something useful - put our PID into the pid_file if( 0 != $pid ) { open( LOCK_FILE, ">$pid_file" ); print LOCK_FILE "$pid\n"; close( LOCK_FILE ); - if( !$foreground ) { exit( 0 ) }; + if( ! $foreground ) { exit( 0 ) }; } # connect to bus_known_server_db @@ -1295,7 +895,6 @@ $bus_known_server_db->create_table('bus_known_server', \@server_col_names); # detect own ip and mac address $network_interface= &get_interface_for_ip($bus_ip); $bus_mac_address= &get_mac($network_interface); - daemon_log("bus ip address detected: $bus_ip", 1); daemon_log("bus mac address detected: $bus_mac_address", 1); diff --git a/gosa-si/gosa-si-client b/gosa-si/gosa-si-client index 54884536a..016646c0e 100755 --- a/gosa-si/gosa-si-client +++ b/gosa-si/gosa-si-client @@ -487,8 +487,6 @@ sub register_at_server { &add_content2xml_hash($register_hash, "mac_address", $client_mac_address); &add_content2xml_hash($register_hash, "events", $events); - my $tmp = print Dumper $register_hash; - # send xml hash to server with general server passwd my $answer = &send_msg_hash2address($register_hash, $server, $server_passwd); diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server index a34e5c97c..11e24b459 100755 --- a/gosa-si/gosa-si-server +++ b/gosa-si/gosa-si-server @@ -396,6 +396,9 @@ sub create_known_client { sub client_input { my ($heap,$input,$wheel) = @_[HEAP, ARG0, ARG1]; + + daemon_log("Incoming msg:\n$input\n", 8); + ###################################### # forward msg to all imported modules no strict "refs"; diff --git a/gosa-si/modules/DBsqlite.pm b/gosa-si/modules/DBsqlite.pm index 2e838333f..65d896bb4 100644 --- a/gosa-si/modules/DBsqlite.pm +++ b/gosa-si/modules/DBsqlite.pm @@ -8,6 +8,8 @@ use Data::Dumper; use threads; use Time::HiRes qw(usleep); + + my $col_names = {}; sub new { @@ -62,6 +64,7 @@ sub remove_lock : locked { unlink($self->{db_lock}); } + sub create_table { my $self = shift; my $table_name = shift; @@ -74,7 +77,6 @@ sub create_table { &remove_lock($self,'create_table'); return 0; } - sub add_dbentry { @@ -99,7 +101,7 @@ sub add_dbentry { my $sql_statement = "SELECT MAX(CAST(id AS INTEGER)) FROM $table"; &create_lock($self,'add_dbentry'); my $max_id = @{ @{ $self->{dbh}->selectall_arrayref($sql_statement) }[0] }[0]; - &remove_lock($self,'add_dbentry'); + &remove_lock($self,'add_dbentry'); if( defined $max_id) { $id = $max_id + 1; } else { @@ -108,11 +110,6 @@ sub add_dbentry { $arg->{id} = $id; } - # check wether value to primary key is specified - if ( not exists $arg->{ $primkey } ) { - return 3; - } - # if timestamp is not provided, add timestamp if( not exists $arg->{timestamp} ) { $arg->{timestamp} = &get_time; @@ -124,6 +121,8 @@ sub add_dbentry { my $res = @{ $self->{dbh}->selectall_arrayref($sql_statement) }; &remove_lock($self,'add_dbentry'); if ($res == 0) { + # primekey is unique + # fetch column names of table my $col_names = &get_table_columns("",$table); @@ -137,33 +136,35 @@ sub add_dbentry { } my $sql_statement = "INSERT INTO $table VALUES ('".join("', '", @add_list)."')"; - print STDERR $sql_statement; + + print STDERR $sql_statement."\n"; + &create_lock($self,'add_dbentry'); my $db_res = $self->{dbh}->do($sql_statement); &remove_lock($self,'add_dbentry'); if( $db_res != 1 ) { return 4; - } else { - return 0; - } + } } else { - my $update_hash = { table=>$table }; - $update_hash->{where} = [ { $primkey=>[ $arg->{$primkey} ] } ]; - $update_hash->{update} = [ {} ]; + # entry already exists, so update it + my $where_str= " WHERE $primkey='".$arg->{$primkey}."'"; + + my @update_l; while( my ($pram, $val) = each %{$arg} ) { if( $pram eq 'table' ) { next; } if( $pram eq 'primkey' ) { next; } - $update_hash->{update}[0]->{$pram} = [$val]; - } - my $db_res = &update_dbentry( $self, $update_hash ); - if( $db_res != 1 ) { - return 5; - } else { - return 0; + push(@update_l, "$pram='$val'"); } + my $update_str= join(", ", @update_l); + $update_str= " SET $update_str"; + + my $sql_statement= "UPDATE $table $update_str $where_str"; + my $db_res = &update_dbentry($self, $sql_statement ); } + + return 0; } sub update_dbentry { @@ -208,7 +209,7 @@ sub select_dbentry { my $db_answer= &exec_statement($self, $sql); # fetch column list of db and create a hash with column_name->column_value of the select query - $sql =~ /FROM ([\S]*?) /g; + $sql =~ /FROM ([\S]*?)( |$)/g; my $table = $1; my $column_list = &get_table_columns($self, $table); my $list_len = @{ $column_list } ; @@ -227,11 +228,16 @@ sub select_dbentry { sub show_table { my $self = shift; my $table_name = shift; - &create_lock($self,'show_table'); - my @res = @{$self->{dbh}->selectall_arrayref( "SELECT * FROM $table_name")}; - &remove_lock($self,'show_table'); + #&create_lock($self,'show_table'); + #my @res = @{$self->{dbh}->selectall_arrayref( "SELECT * FROM $table_name ORDER BY timestamp")}; + #&remove_lock($self,'show_table'); + + my $sql_statement= "SELECT * FROM $table_name ORDER BY timestamp"; + print STDERR $sql_statement."\n"; + my $res= &exec_statement($self, $sql_statement); + my @answer; - foreach my $hit (@res) { + foreach my $hit (@{$res}) { push(@answer, "hit: ".join(', ', @{$hit})); } return join("\n", @answer); @@ -250,6 +256,18 @@ sub exec_statement { } +sub count_dbentries { + my ($self, $table)= @_; + my $error= 0; + my $answer= -1; + + my $sql_statement= "SELECT * FROM $table"; + my $db_answer= &select_dbentry($self, $sql_statement); + + my $count = keys(%{$db_answer}); + return $count; +} + sub get_time { my ($seconds, $minutes, $hours, $monthday, $month, $year, $weekday, $yearday, $sommertime) = localtime(time); diff --git a/gosa-si/modules/GosaPackages.pm b/gosa-si/modules/GosaPackages.pm index 04a1f29c5..0094ebccb 100644 --- a/gosa-si/modules/GosaPackages.pm +++ b/gosa-si/modules/GosaPackages.pm @@ -13,14 +13,6 @@ use Data::Dumper; use GOSA::DBsqlite; use MIME::Base64; -my $op_hash = { - 'eq' => '=', - 'ne' => '!=', - 'ge' => '>=', - 'gt' => '>', - 'le' => '<=', - 'lt' => '<', -}; BEGIN{} END{} @@ -269,7 +261,6 @@ sub open_socket { #=============================================================================== sub process_incoming_msg { my ($crypted_msg) = @_ ; - &main::daemon_log("Got message $crypted_msg", 8); if( (not(defined($crypted_msg))) || (length($crypted_msg) <= 0)) { &main::daemon_log("function 'process_incoming_msg': got no msg", 7); return; @@ -418,9 +409,11 @@ sub db_res_2_xml { my $xml = ""; - while ( my ($hit, $hash) = each %{ $db_res } ) { - $xml .= "\n"; + my $len_db_res= keys %{$db_res}; + for( my $i= 1; $i<= $len_db_res; $i++ ) { + $xml .= "\n"; + my $hash= $db_res->{$i}; while ( my ($column_name, $column_value) = each %{$hash} ) { $xml .= "<$column_name>"; my $xml_content; @@ -432,8 +425,8 @@ sub db_res_2_xml { $xml .= $xml_content; $xml .= ""; } + $xml .= ""; - $xml .= ""; } $xml .= ""; @@ -443,117 +436,6 @@ sub db_res_2_xml { ## CORE FUNCTIONS ############################################################ -sub get_where_statement { - my ($msg, $msg_hash)= @_; - my $error= 0; - - my $clause_str= ""; - if( not exists @{$msg_hash->{'where'}}[0]->{'clause'} ) { $error++; }; - if( $error == 0 ) { - my @clause_l; - my @where = @{@{$msg_hash->{'where'}}[0]->{'clause'}}; - foreach my $clause (@where) { - my $connector = $clause->{'connector'}[0]; - if( not defined $connector ) { $connector = "AND"; } - $connector = uc($connector); - delete($clause->{'connector'}); - - my @phrase_l ; - foreach my $phrase (@{$clause->{'phrase'}}) { - my $operator = "="; - if( exists $phrase->{'operator'} ) { - my $op = $op_hash->{$phrase->{'operator'}[0]}; - if( not defined $op ) { - &main::daemon_log("Can not translate operator '$operator' in where ". - "statement to sql valid syntax. Please use 'eq', ". - "'ne', 'ge', 'gt', 'le', 'lt' in xml message\n", 1); - &main::daemon_log($msg, 8); - $op = "="; - } - $operator = $op; - delete($phrase->{'operator'}); - } - - my @xml_tags = keys %{$phrase}; - my $tag = $xml_tags[0]; - my $val = $phrase->{$tag}[0]; - push(@phrase_l, "$tag$operator'$val'"); - } - my $clause_str .= join(" $connector ", @phrase_l); - push(@clause_l, $clause_str); - } - - if( not 0 == @clause_l ) { - $clause_str = join(" AND ", @clause_l); - $clause_str = "WHERE $clause_str "; - } - } - - return $clause_str; -} - -sub get_select_statement { - my ($msg, $msg_hash)= @_; - my $select = "*"; - if( exists $msg_hash->{'select'} ) { - my $select_l = \@{$msg_hash->{'select'}}; - $select = join(' AND ', @{$select_l}); - } - return $select; -} - - -sub get_update_statement { - my ($msg, $msg_hash) = @_; - my $error= 0; - my $update_str= ""; - my @update_l; - - if( not exists $msg_hash->{'update'} ) { $error++; }; - - if( $error == 0 ) { - my $update= @{$msg_hash->{'update'}}[0]; - while( my ($tag, $val) = each %{$update} ) { - my $val= @{$update->{$tag}}[0]; - push(@update_l, "$tag='$val'"); - } - if( 0 == @update_l ) { $error++; }; - } - - if( $error == 0 ) { - $update_str= join(', ', @update_l); - $update_str= "SET $update_str "; - } - - return $update_str; -} - -sub get_limit_statement { - my ($msg, $msg_hash)= @_; - my $error= 0; - my $limit_str = ""; - my ($from, $to); - - if( not exists $msg_hash->{'limit'} ) { $error++; }; - - if( $error == 0 ) { - eval { - my $limit= @{$msg_hash->{'limit'}}[0]; - $from= @{$limit->{'from'}}[0]; - $to= @{$limit->{'to'}}[0]; - }; - if( $@ ) { - $error++; - } - } - - if( $error == 0 ) { - $limit_str= "LIMIT $from, $to"; - } - - return $limit_str; -} - sub query_jobdb { my ($msg) = @_; my $msg_hash = &transform_msg2hash($msg); @@ -563,7 +445,10 @@ sub query_jobdb { my $table= $main::job_queue_table_name; my $where= &get_where_statement($msg, $msg_hash); my $limit= &get_limit_statement($msg, $msg_hash); - my $sql_statement= "SELECT $select FROM $table $where $limit"; + my $orderby= &get_orderby_statement($msg, $msg_hash); + my $sql_statement= "SELECT $select FROM $table $where $orderby $limit"; + +print STDERR "\n\n$sql_statement\n\n"; # execute db query my $res_hash = $main::job_db->select_dbentry($sql_statement); diff --git a/gosa-si/modules/GosaSupportDaemon.pm b/gosa-si/modules/GosaSupportDaemon.pm index 62e2a3caa..182e920bf 100644 --- a/gosa-si/modules/GosaSupportDaemon.pm +++ b/gosa-si/modules/GosaSupportDaemon.pm @@ -2,7 +2,7 @@ package GOSA::GosaSupportDaemon; use Exporter; @ISA = qw(Exporter); -@EXPORT = qw(create_xml_hash send_msg_hash2address get_content_from_xml_hash add_content2xml_hash create_xml_string encrypt_msg decrypt_msg create_ciphering transform_msg2hash get_time send_msg); +@EXPORT = qw(create_xml_hash send_msg_hash2address get_content_from_xml_hash add_content2xml_hash create_xml_string encrypt_msg decrypt_msg create_ciphering transform_msg2hash get_time send_msg get_where_statement get_select_statement get_update_statement get_limit_statement get_orderby_statement); use strict; use warnings; @@ -12,6 +12,14 @@ use Digest::MD5 qw(md5 md5_hex md5_base64); use MIME::Base64; use XML::Simple; +my $op_hash = { + 'eq' => '=', + 'ne' => '!=', + 'ge' => '>=', + 'gt' => '>', + 'le' => '<=', + 'lt' => '<', +}; BEGIN {} @@ -107,7 +115,7 @@ sub send_msg_hash2address ($$$){ # encrypt xml msg my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); - + # opensocket my $socket = &open_socket($address); if(not defined $socket){ @@ -194,6 +202,10 @@ sub encrypt_msg { $msg = "\0"x(16-length($msg)%16).$msg; $msg = $my_cipher->encrypt($msg); chomp($msg = &encode_base64($msg)); + + # there are no newlines allowed inside msg + $msg=~ s/\n//g; + return $msg; } @@ -302,4 +314,140 @@ sub send_msg ($$$$$) { &send_msg_hash2address($out_hash, $to, $hostkey); } + +sub get_where_statement { + my ($msg, $msg_hash)= @_; + my $error= 0; + + my $clause_str= ""; + if( not exists @{$msg_hash->{'where'}}[0]->{'clause'} ) { $error++; }; + if( $error == 0 ) { + my @clause_l; + my @where = @{@{$msg_hash->{'where'}}[0]->{'clause'}}; + foreach my $clause (@where) { + my $connector = $clause->{'connector'}[0]; + if( not defined $connector ) { $connector = "AND"; } + $connector = uc($connector); + delete($clause->{'connector'}); + + my @phrase_l ; + foreach my $phrase (@{$clause->{'phrase'}}) { + my $operator = "="; + if( exists $phrase->{'operator'} ) { + my $op = $op_hash->{$phrase->{'operator'}[0]}; + if( not defined $op ) { + &main::daemon_log("Can not translate operator '$operator' in where ". + "statement to sql valid syntax. Please use 'eq', ". + "'ne', 'ge', 'gt', 'le', 'lt' in xml message\n", 1); + &main::daemon_log($msg, 8); + $op = "="; + } + $operator = $op; + delete($phrase->{'operator'}); + } + + my @xml_tags = keys %{$phrase}; + my $tag = $xml_tags[0]; + my $val = $phrase->{$tag}[0]; + push(@phrase_l, "$tag$operator'$val'"); + } + my $clause_str .= join(" $connector ", @phrase_l); + push(@clause_l, $clause_str); + } + + if( not 0 == @clause_l ) { + $clause_str = join(" AND ", @clause_l); + $clause_str = "WHERE $clause_str "; + } + } + + return $clause_str; +} + +sub get_select_statement { + my ($msg, $msg_hash)= @_; + my $select = "*"; + if( exists $msg_hash->{'select'} ) { + my $select_l = \@{$msg_hash->{'select'}}; + $select = join(' AND ', @{$select_l}); + } + return $select; +} + + +sub get_update_statement { + my ($msg, $msg_hash) = @_; + my $error= 0; + my $update_str= ""; + my @update_l; + + if( not exists $msg_hash->{'update'} ) { $error++; }; + + if( $error == 0 ) { + my $update= @{$msg_hash->{'update'}}[0]; + while( my ($tag, $val) = each %{$update} ) { + my $val= @{$update->{$tag}}[0]; + push(@update_l, "$tag='$val'"); + } + if( 0 == @update_l ) { $error++; }; + } + + if( $error == 0 ) { + $update_str= join(', ', @update_l); + $update_str= "SET $update_str "; + } + + return $update_str; +} + +sub get_limit_statement { + my ($msg, $msg_hash)= @_; + my $error= 0; + my $limit_str = ""; + my ($from, $to); + + if( not exists $msg_hash->{'limit'} ) { $error++; }; + + if( $error == 0 ) { + eval { + my $limit= @{$msg_hash->{'limit'}}[0]; + $from= @{$limit->{'from'}}[0]; + $to= @{$limit->{'to'}}[0]; + }; + if( $@ ) { + $error++; + } + } + + if( $error == 0 ) { + $limit_str= "LIMIT $from, $to"; + } + + return $limit_str; +} + +sub get_orderby_statement { + my ($msg, $msg_hash)= @_; + my $error= 0; + my $order_str= ""; + my $order; + + if( not exists $msg_hash->{'orderby'} ) { $error++; }; + + if( $error == 0) { + eval { + $order= @{$msg_hash->{'orderby'}}[0]; + }; + if( $@ ) { + $error++; + } + } + + if( $error == 0 ) { + $order_str= "ORDER BY $order"; + } + + return $order_str; +} + 1; diff --git a/gosa-si/modules/ServerPackages.pm b/gosa-si/modules/ServerPackages.pm index ceb926825..a13b8701e 100644 --- a/gosa-si/modules/ServerPackages.pm +++ b/gosa-si/modules/ServerPackages.pm @@ -259,30 +259,6 @@ sub get_ip { return $result; } -#=== FUNCTION ================================================================ -# NAME: open_socket -# PARAMETERS: PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000 -# [PeerPort] string necessary if port not appended by PeerAddr -# RETURNS: socket IO::Socket::INET -# DESCRIPTION: open a socket to PeerAddr -#=============================================================================== -#sub open_socket { -# my ($PeerAddr, $PeerPort) = @_ ; -# if(defined($PeerPort)){ -# $PeerAddr = $PeerAddr.":".$PeerPort; -# } -# my $socket; -# $socket = new IO::Socket::INET(PeerAddr => $PeerAddr , -# Porto => "tcp" , -# Type => SOCK_STREAM, -# Timeout => 5, -# ); -# if(not defined $socket) { -# return; -# } -# &main::daemon_log("open_socket to: $PeerAddr", 7); -# return $socket; -#} #=== FUNCTION ================================================================ # NAME: register_at_bus @@ -292,10 +268,6 @@ sub get_ip { #=============================================================================== sub register_at_bus { - - - print STDERR ">>>>>>>>>>>>>>>>>>>>>>>>1\n"; - # add bus to known_server_db my $res = $main::known_server_db->add_dbentry( {table=>'known_server', primkey=>'hostname', @@ -304,7 +276,6 @@ sub register_at_bus { hostkey=>$bus_passwd, timestamp=>&get_time, } ); - print STDERR ">>>>>>>>>>>>>>>>>>>>>>>>2\n"; my $msg_hash = &create_xml_hash("here_i_am", $server_address, $bus_address); my $answer = ""; $answer = &send_msg_hash2address($msg_hash, $bus_address, $bus_passwd); @@ -328,12 +299,10 @@ sub process_incoming_msg { &main::daemon_log("function 'process_incoming_msg': got no msg", 7); } - &main::daemon_log("ServerPackages: incoming msg: \n$crypted_msg", 8); - $crypted_msg =~ /^([\s\S]*?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)\.(\d{1,3}?)$/; $crypted_msg = $1; my $host="0.0.0.0"; - if($1 && $2 && $3 && $4) { + if(defined $2 && defined $3 && defined $4 && defined $5) { $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5); } @@ -363,11 +332,12 @@ sub process_incoming_msg { # check wether incoming msg is from a known_server if( not defined $msg ) { - #my $query_res = $main::known_server_db->select_dbentry( {table=>'known_server'} ); my $sql_statement= "SELECT * FROM known_server"; my $query_res = $main::known_server_db->select_dbentry( $sql_statement ); + while( my ($hit_num, $hit) = each %{ $query_res } ) { $host_name = $hit->{hostname}; + if( not $host_name =~ "^$host") { next; } @@ -546,13 +516,11 @@ sub new_passwd { my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$source_name'"; $query_res = $main::known_clients_db->select_dbentry( $sql_statement ); if( 1 == keys %{$query_res} ) { - my $update_hash = { table=>'known_clients' }; - $update_hash->{where} = [ { hostname=>[$source_name] } ]; - $update_hash->{update} = [ { - hostkey=>[$source_key], - timestamp=>[&get_time], - } ]; - my $res = $main::known_clients_db->update_dbentry( $update_hash ); + my $act_time = &get_time; + my $sql_statement= "UPDATE known_clients ". + "SET hostkey='$source_key', timestamp='$act_time' ". + "WHERE hostname='$source_name'"; + my $res = $main::known_clients_db->update_dbentry( $sql_statement ); my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source_name); &send_msg_hash2address($hash, $source_name, $source_key); @@ -560,15 +528,14 @@ sub new_passwd { } # check known_server_db - $query_res = $main::known_server_db->select_dbentry( {table=>'known_server', hostname=>$source_name } ); + my $sql_statement = "SELECT * FROM known_server WHERE hostname='$source_name'"; + $query_res = $main::known_server_db->select_dbentry( $sql_statement ); if( 1 == keys %{$query_res} ) { - my $update_hash = { table=>'known_server' }; - $update_hash->{where} = [ { hostname=>[$source_name] } ]; - $update_hash->{update} = [ { - hostkey=>[$source_key], - timestamp=>[&get_time], - } ]; - my $res = $main::known_server_db->update_dbentry( $update_hash ); + my $act_time = &get_time; + my $sql_statement= "UPDATE known_server ". + "SET hostkey='$source_key', timestamp='$act_time' ". + "WHERE hostname='$source_name'"; + my $res = $main::known_server_db->update_dbentry( $sql_statement ); my $hash = &create_xml_hash("confirm_new_passwd", $server_address, $source_name); &send_msg_hash2address($hash, $source_name, $source_key); @@ -580,16 +547,6 @@ sub new_passwd { } -sub send_msg_hash { - my ($hash, $host_name, $host_key); - - - my $answer = &send_msg_hash2address($hash, $host_name, $host_key); - - return; -} - - #=== FUNCTION ================================================================ # NAME: here_i_am # PARAMETERS: msg_hash - hash - hash from function create_xml_hash @@ -604,10 +561,13 @@ sub here_i_am { my $out_hash; # number of known clients - my $nu_clients = keys %{ $main::known_clients_db->select_dbentry( {table=>'known_clients'} ) }; + my $nu_clients= $main::known_clients_db->count_dbentries('known_clients'); # check wether client address or mac address is already known - if (exists $main::known_clients->{$source}) { + my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$source'"; + my $db_res= $main::known_clients_db->select_dbentry( $sql_statement ); + + if ( 1 == keys %{$db_res} ) { &main::daemon_log("WARNING: $source is already known as a client", 1); &main::daemon_log("WARNING: values for $source are being overwritten", 1); $nu_clients --; @@ -633,6 +593,7 @@ sub here_i_am { # create entry in known_clients my $events = @{$msg_hash->{events}}[0]; + # add entry to known_clients_db my $res = $main::known_clients_db->add_dbentry( {table=>'known_clients', primkey=>'hostname', @@ -656,9 +617,10 @@ sub here_i_am { # notify registered client to bus if( $bus_activ eq "on") { # fetch actual bus key - my $query_res = $main::known_server_db->select_dbentry( {table=>'known_server'} ); - my $hostkey = $query_res->{1}->{hostkey}; - + my $sql_statement= "SELECT * FROM known_server WHERE status='bus'"; + my $query_res = $main::known_server_db->select_dbentry( $sql_statement ); + my $hostkey = $query_res->{1}->{'hostkey'}; + # send update msg to bus $out_hash = &create_xml_hash("new_client", $server_address, $bus_address, $source); &send_msg_hash2address($out_hash, $bus_address, $hostkey); @@ -729,7 +691,8 @@ sub who_has_i_do { sub new_ldap_config { my ($address) = @_ ; - my $res = $main::known_clients_db->select_dbentry( { table=>'known_clients', hostname=>$address } ); + my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'"; + my $res = $main::known_clients_db->select_dbentry( $sql_statement ); # check hit my $hit_counter = keys %{$res}; diff --git a/gosa-si/tests/client.php b/gosa-si/tests/client.php index bcfef94a1..e3df70614 100755 --- a/gosa-si/tests/client.php +++ b/gosa-si/tests/client.php @@ -12,7 +12,7 @@ if($sock->connected()){ /* Prepare a hunge bunch of data to be send */ # add -#$data = "
job_ping
10.89.1.155:2008300:1B:77:04:8A:6C 19700101000000
"; +#$data = "
job_ping
10.89.1.155:2008300:1B:77:04:8A:6C 19700101000001
"; #$data = "
job_sayHello
10.89.1.155:2008300:1B:77:04:8A:6C 20130102133900
"; #$data = "
job_ping
10.89.1.155:2008300:1B:77:04:8A:6C 20130102133900
"; @@ -24,7 +24,9 @@ if($sock->connected()){ # query #$data = "
gosa_query_jobdb
andgt0le5
"; -$data= "
gosa_query_jobdb
ping03
"; +#$data= "
gosa_query_jobdb
ping03
"; +$data= "
gosa_query_jobdb
ping09timestamp
"; + # count #$data = "
gosa_count_jobdb
";