Welcome To Our Shell

Mister Spy & Souheyl Bypass Shell

Current Path : /var/www/web-klick.de/dsh/90_akt/DivBasicF/

Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
Upload File :
Current File : /var/www/web-klick.de/dsh/90_akt/DivBasicF/DBComSimple_devel.pm

package DivBasicF::DBComSimple;

#  Kommunikation zwischen Prozessen auf Datenbankebene
#
#  Dieses Modul ermoeglicht eine Kommunikation zwischen Prozessen
#  ueber eine Datenbank.
#
#  Erster Prozess (Server);
#
#  my $com1 = DivBasicF::DBComSimple->new([ <db-string>,<port>,...],
#
#
#  Zweiter Prozess (Client):
#
#  my $com2 = DivBasicF::DBComSimple->new([ <db-string>,<port>,...],
#
#
#  Beide Prozesse koennen nun ueber die Funktionen  $com->msg(<array>)
#  und  $com->get()  Daten in Form von anonymen Arrays per Handshaking
#  austauschen.  Liegt eine Antwort noch nicht vor, dann liefert  get()
#  nichts zurueck, dann muss zu einem spaeteren Zeitpunkt noch mal
#  nachgefragt werden.
#
#
#
#
#  Die Methode  run  bietet die Moeglichkeit, einen Multisession-Server
#  laufen zu lassen. Zu uebergebende Parameter sind:
#
#  1. ein Applikationsobjekt  (z.B. DivBasicF::Beispiel->new());
#  2. Anzahl gleichzeitiger Start-Prozess      (z.B. 3)
#  3. Anzahl gleichzeitiger laufender Prozesse (z.B. 3)
#  4. Standard-Wait-time  (hier immer: -1)
#
#  Der Server lauscht auf dem Standard-Port, der dem Konstruktor mitgegeben
#  wurde. Empfaengt er eine Nachricht der Form [func,<param1>, ...],
#  dann wird aufegrufen:
#
#    $application_object->$func(<param1>,...]
#
#  Rueckgabewert dieser Methode muss wiederum ein anonymes Array sein.
#
#  Hat das Ergebnis-Array die Form: ["___NEXT<n>___",func1,<param1>,...],
#  dann wird <n> Sekunden gewartet, und danach aufgerufen:
#
#    $application_object->$func1(<param1>,...]
#
#  usw.  ___NEXT___  bedeutet   ___NEXT0___
#  Ist die Wartezeit groesser als die Standard-Wartezeit (siehe new),
#  dann wird der Prozess in eine Prozesstabelle gedumpt und erst nach der
#  vereinbarten Sleep-Time wieder aufgeweckt.
#
#  Ansonsten wird das Ergebnis ueber  msg  dem Client zurueckgegeben,
#  der dann das Ergebnis mit  get()  abholen kann, und ggfs. weitere
#  Anfragen stellen kann.
#
#  Soll der Prozess auf der Serverseite tatsaechlich beendet werden, dann
#  muss als Ergebnis das Array  ["___END___"]  gegeben werden, denn ansonsten
#  verbleibt der gestartete Prozess im Server und wird jeweils in der
#  Prozesstabelle gehalten, bis weitere Anfragen kommen. Beendet wird
#  der Prozess auch, wenn der Client ein ["___END___"] schickt. Fuer
#   $com->msg(["___END___"])  kann auch kurz geschrieben werden: $com->stop() .
#
#  Wird in der new-Methode des Servers ein Indices-String angegeben, dann
#  werden die entsprechenden Spalten in der Prozesstabelle zusaetzlich
#  angelegt. Beim Dumpen des Prozesses wird dann jeweils der Rueckgabewert
#  von   $application_object->INDEX(<spaltenname>)   fuer jede
#  angegebene Spalte eingetragen. Auf diese Weise koennen Prozesse
#  gezielt gesucht und dann auch fortgesetzt werden: Die Spalte
#  conn  enthaelt naemlich den aktuellen Kommunikations-Port, auf dem
#  der Prozess lauscht, und der damit angesprochen werden kann.
#  Der Client, der das tun will, muss nur seinen Kommunikationsport
#  entsprechend setzen, mit:  $com->connection(<port>).



use strict;
use POSIX ":sys_wait_h";
use Fcntl ":flock";
use vars qw(@ISA);
# use DivBasicF::COMsimple;
# use Server::frezthaw;
use DBD::SQLite;
use Time::HiRes;
use Digest::MD5;
use Data::Dumper;
# @ISA = qw(DivBasicF::COMsimple);


#******************************************************************

#  Parameter:
#
#  <dbstring>, <port>, [<indices>,] [<serializer>,] [<wait_time>,]  [<wait_frequenz>]
#
#  
#  <dbstring>: eine kommaseparierte Liste mit den folgenden Angaben:
#
#    DB-Connection-String  (SQLite3 oder mySQL), Parameter kommasepariert
#    optional: Name der Connection-Tabelle  (default: conn)
#    optional: Name der Prozess-Tabelle     (default: conn_store)
#    optional: Name der Locking-Tabelle     (default: conn_lock)
#    optional: Name der Semaphoren-Tabelle  (default: conn_sema)
#
#  <port>:  Connection-String: acht Zeichen langer String aus
#           Kleinbuchstaben und Zahlen, auf dem initial gelauscht wird
#
#
#  <indices>:     Kommaseparierte Liste von Spaltennamen, in denen
#                 Index-Strings zu gespeicherten Prozessen abgelegt werden.
#
#  <wait_time>:   Standard-Wartezeit von  get() in Sekunden, default: 20
# 
#  <wait_frequenz>: Standard-Anzahl der Polls von get() pro Sekunde, default: 25


sub new {

   my $class = shift;
   my $self  = {};
   bless($self,$class);
   my @pars = @_;
   
# 1. Variablen abspeichern 

   my $o;
   my $dbh = shift(@pars);
   ($self->{'DBSTRING'},$self->{'CONN'},$self->{'STORE'},$self->{'LOCK'},
        $self->{'SEMA'}) = split(/,/,$dbh); # Datenbank-Connectionstring

   $self->{'CONNECTION'} = shift(@pars);    # Initiale Connection-ID
   while (@pars) {
      $o = shift(@pars);
      if    ($o =~ /[a-zA-Z\_]/) {
         $self->{'INDEX'}     = $o; # Indexe fuer Storing
      }
      elsif (!($self->{'WAIT_TIME'})) {
         $self->{'WAIT_TIME'} = $o; # Maximale Antwort-Wartezeit in Minuten
      }
      else {
         $self->{'FREQUENZ'}  = $o; # Abfrageintervall pro Sekunde
      }
   }

# 2. Weitere Variablen und Defaultwerte:

   $self->{'RESET_ID'} = $self->{'CONNECTION'};
   if (!($self->{'CONN'}))      { $self->{'CONN'}      = "conn"; }
   if (!($self->{'STORE'}))     { $self->{'STORE'}     = "conn_store"; }
   if (!($self->{'LOCK'}))      { $self->{'LOCK'}      = "conn_lock"; }
   if (!($self->{'SEMA'}))      { $self->{'SEMA'}      = "conn_sema"; }
   if (!($self->{'FREQUENZ'}))  { $self->{'FREQUENZ'}  = 25; }
   if (!($self->{'WAIT_TIME'})) { $self->{'WAIT_TIME'} = 20; }
   ($self->{'CYCLES'},$self->{'INTERVAL'}) =
         $self->cycles_interval($self->{'WAIT_TIME'},$self->{'FREQUENZ'});

# 3. Datenbankeinrichtung vorbereiten

   my $conn  = $self->{'CONN'};
   my $store = $self->{'STORE'};
   my $lock  = $self->{'LOCK'};
   my $sema  = $self->{'SEMA'};

   my $create_index = "create_index";
   $dbh = DBI->connect(split(/ +/,$self->{'DBSTRING'}), { PrintError => 0 } );
   if ($self->{'DBSTRING'} =~ /SQLite/) {   #  SQLite DB
      $dbh->do("pragma journal_mode=off");
      $create_index = "create index if not exists ";
   }
   elsif ($self->{'DBSTRING'} =~ /^(.*)\:(.*)\:(.*)\:(.*)$/) { #  MySQL DB
      $self->{'MYSQL'} = ["dbi:mysql:host=$1\;database=$2",$3,$4];
      $dbh   = DBI->connect(@{$self->{'MYSQL'}}, { PrintError => 0 } );
   }
   
# 4. Datentabellen einrichten, wenn noetig

   $o = "," . $self->{'INDEX'} . ",";
   $o =~ s/\,([a-zA-Z0-9\_]+)/\,$1 text/g;
   $o =~ s/^(,*)(.*?)(,*)$/$2/;
   if ($o) { $o = "," . $o; }

   $dbh->do("create table if not exists $conn " .
                      "(id varchar(23),replynr varchar(8)," .
                      "msgid varchar(8),text text,connlock varchar(8))");
   $dbh->do("create table if not exists $lock " .
                      "(id varchar(8) unique)");
   $dbh->do("create table if not exists $sema " .
                      "(id varchar(30) unique,text text,semalock varchar(1))");
   $dbh->do("create table if not exists $store ".
                      " (conn varchar(8),sleep int,id varchar(22) unique," .
                      "  text text,objlock varchar(1),status varchar(1)".$o.")");

# 5. Indexe einrichten, wenn noetig

   $dbh->do("$create_index $conn"."_replynr__idx on $conn (replynr)");
   $dbh->do("$create_index $conn"."_msgid__idx   on $conn (msgid)");
   $dbh->do("$create_index $conn"."_oid__idx     on $conn (id)");

   $dbh->do("$create_index $lock"."__idx         on $lock (id)");
   $dbh->do("$create_index $sema"."__idx         on $sema (id)");

   foreach $o (split(/\,/,"conn,sleep,id,".$self->{'INDEX'})) {
      next if ($o !~ /^([a-zA-Z0-9\_]+)$/);
      $dbh->do("$create_index $store"."_".$o."_idx on $store ($o)");
   }
   
   $self->{'INDEX'} = [split(/,/,$self->{'INDEX'})];

   $dbh->disconnect();
   delete($self->{'DBH'});
   undef($dbh);

   return($self);

}

#******************************************************************

sub connection     { my $self = shift; $self->{'CONNECTION'} = shift; }
sub get_connection { my $self = shift; return($self->{'CONNECTION'}); }
sub max_time       { return(4099887766); }
sub stop           { my $self = shift; $self->msg(["___END___"]); }

#******************************************************************

#  Hilfsfunktion

sub cycles_interval {

   my $self      = shift;
   my $wait_time = shift;   
   my $frequenz  = shift;
   my $cycles    = $self->{'CYCLES'};
   my $interval  = $self->{'INTERVAL'};

   if ($wait_time < 0) {
      return(1,0);
   }
      
   if ($frequenz) {
      if (!$wait_time) {
         $wait_time = $self->{'WAIT_TIME'};
      }
      $cycles = $wait_time * $frequenz;
      $interval = 1 / $frequenz;
   }
   elsif ($wait_time) {
      $cycles = $wait_time * $self->{'FREQUENZ'};
      $cycles = 1 if ($cycles < 1);
   }

   return($cycles,$interval);

}

#********************************************************************

sub dbh {

   my $self = shift;

   if (!($self->{'DBH'})) {
      $self->{'DBH'} = 
          DBI->connect(split(/ +/,$self->{'DBSTRING'}), { PrintError => 0 } );
   }
   return($self->{'DBH'});
   
} 
      
#******************************************************************

#  Allgemeine Query

sub query {

   my $self  = shift;
   my $query = shift;
   
   my $dbh = $self->dbh();
   my $cursor = $dbh->prepare($query,{},@_);
   $cursor->execute();
   my $erg = [];
   my @ee;
   while (0 == 0) {
      @ee = $cursor->fetchrow();
      last if (!@ee);
      push(@$erg,[@ee]);
   }
   $cursor->finish();
   return($erg);
   
}

#******************************************************************

#  Senden einer Message als anonymes Array

sub msg {

   my $self       = shift;
   my $text       = shift;
   my $replynr    = shift;

   my $msg_id     = 0;
   if (!$text) {
      $text    = $msg_id;
      $replynr = $self->{'RESET_ID'};
   } else {
      $replynr = $self->{'CONNECTION'};
      $msg_id  = 1;
   }

   my $cursor; my $erg; my @ee;

   my $pattern = [qw(0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k),
                  qw(l m n o p q r s t u v w x y z z z z)];

   my $dbh  = $self->dbh();
   my $conn = $self->{'CONN'};
   my $lock = $self->{'LOCK'};
   
   if (length($self->{'ID'}) > 20 and $msg_id) { #  wenn es schon eine gueltige ID gibt
                               #  und die Message auf den Stack geschrieben wird
      $cursor = $dbh->prepare("select id from $lock where id='$replynr'");
      $cursor->execute();
      @ee = $cursor->fetchrow();
      $cursor->finish();
      if (!@ee) {  # wenn keine Rueckliefer-ID gesperrt ist, wartet niemand mehr ...
         print("NOT FOUND. CONNECTION $replynr INTERRUPTED\n");
         return("NOT FOUND. CONNECTION $replynr INTERRUPTED");
      }
   }

   while (0 == 0) { # Erstellung der neuen Message-Id
      $msg_id = [];
      while ($#{$msg_id} < 7) {
         push(@$msg_id,$pattern->[int rand(35)]);
      }
      $msg_id = join("",@$msg_id);
      next if ($msg_id eq $self->{'RESET_ID'});
      $erg = $dbh->do("insert into $lock (id) values ('$msg_id')",
               { PrintError => 0 });  #  locken
      last if ($erg ne "0E0"); #  wenn erfolgreich eingetragen
   }

   my $erg = $dbh->do("insert into $conn (id,replynr,msgid,text,connlock) " .
                      " values ('" . $self->{'ID'} .
                      "','" . $replynr . "','$msg_id',?,'0')",
                      {},Dumper($text));

   return("") if ($erg eq "0E0");
   $self->{'CONNECTION'} = $msg_id;
   return($msg_id);

}

#*********************************************************************

#  Holen einer Message

sub get {

   my $self      = shift;
   my $wait_time = shift;  #   Wartezeit
   my $frequenz  = shift;  #   Warte-Frequenz pro Sekunde
   
   my ($cycles,$interval) = $self->cycles_interval($wait_time,$frequenz);
   my $zaehler   = 0;
   my $text; my $o; my $reply_nr; my $cursor; my @ee; my $mark;
   my $dbh  = $self->dbh();
   
   my $conn = $self->{'CONN'};
   my $lock = $self->{'LOCK'};

   while (0 == 0) {
      $zaehler = $zaehler + 1;
      return() if ($zaehler > $cycles);
      select(undef,undef,undef,$interval);  # sleep 1;
      $cursor = $dbh->prepare("select msgid from $conn where replynr='" .
                               $self->{'CONNECTION'} . "' limit 1");
      $cursor->execute();
      @ee = $cursor->fetchrow();
      $cursor->finish();
      if (!@ee) {
         $cursor = $dbh->prepare("select msgid from $conn where replynr='" .
                               $self->{'RESET_ID'} . "' and id = '" .
                               $self->{'ID'} . "' limit 1");
         $cursor->execute();
         @ee = $cursor->fetchrow();
         $cursor->finish();
      }
      next if (!@ee);
      next if (!($ee[0]));
      $o    = $ee[0];
      $mark = sprintf("%1u",int(1000000 + rand(8999990)));
      $text = $dbh->do("update $conn set connlock='$mark' where replynr='" .
                         $self->{'CONNECTION'} . "' and msgid='$o' " .
                             "and connlock='0'");
      last if ($text ne "0E0");
      select(undef,undef,undef,$interval);  # sleep 1;

   }
   $cursor = $dbh->prepare("select id,msgid,text from $conn " .
                      "where replynr='" . $self->{'CONNECTION'} .
                      "' and msgid='$o' and connlock='$mark'");
   $cursor->execute();
   @ee = $cursor->fetchrow();
   $cursor->finish();
   $dbh->do("delete from $conn where replynr='" . $self->{'CONNECTION'} . 
                            "' and msgid='$o' and connlock='$mark'");


   $self->{'ID'}         = $ee[0] if ($ee[0]);
#   if ($self->{'ID'}) {  #  unlocking, wenn Session schon identifiziert ist
      $dbh->do("delete from $lock where id='".$self->{'CONNECTION'}."'");
#   }
   $self->{'CONNECTION'} = $ee[1];
   $text                 = $ee[2];

   if (length($self->{'ID'}) > 20) { #  eindeutige Session-ID
      if   ($self->{'ID'} =~ s/\_$//) { 1; }   #  toggeln
      else {$self->{'ID'} = $self->{'ID'} . "_"; }
   } else {
      if (!($self->{'ID'})) {
         $self->{'ID'} = Dumper($self).time().sprintf("%1u",int rand(100000));
      }
      $self->{'ID'} = Digest::MD5->md5_base64($self->{'ID'});
      $self->{'ID'} =~ s/\//\_/g;
      $self->{'ID'} =~ s/\+/\-/g;
   }
   
   my $VAR1;
   eval($text);
   if ($VAR1) {
      return($VAR1);
   }
   return("___ERROR_TEXT___");
   
}

#*****************************************************************

sub run {   #   Multisession-Server-Mode

   my $self       = shift;
   $self->{'OBJ'} = shift;
   my $max_new    = shift;
   my $max_run    = shift;
   my $wait       = shift;  #  Maximale Zeit, die Prozesse im Hauptspeicher
                            #  warten sollen
   my $param_file = shift;

   if (time() > 1340000000) {
      print "ERROR 522\n";
      exit;
   }

   $Data::Dumper::Deepcopy = 1;
   $Data::Dumper::Indent   = 1;
#   $Data::Dumper::Purity   = 1;  # damit NICHT immer die CODE-DUMMY-
                                  # Meldungen angezeigt werden, ist das
                                  # hier auskommentiert

   my $counter_new  = {};
   my $counter_run  = {};
   my $sleeptime    = 0;
   my $text; my $o; my $o1;
   
   my $VAR1 = Dumper([$self->{'OBJ'},[]]);
   my $IDX  = [];
   $self->{'STATUS'} = 0;
   Time::HiRes::time() =~ /(\d\d\d)$/;
   srand(sprintf("%1u",0.001*($$||1000)*$1));
   my $WAIT = 0; my $NEW = 0;
   my $d0; my $d1;
   
   while (0 == 0) {
      if ($self->lock_semaphore("__proc_nr__")) {
         $o = $self->read_semaphore() + 1;
         $self->write_semaphore("__proc_nr__",$o);
         $self->unlock_semaphore("__proc_nr__");
      }
      last if ($o);
      print "WAITING for Semaphore ...\n";
      Time::HiRes::usleep(500000);
   }
      

   while (0 == 0) {
      $o  = [keys %$counter_new];
      $o1 = [keys %$counter_run];
      $d1 = "COUNT " . $#{$o} . " " . $#{$o1} . "\n";
      print ($d1) if ($d0 ne $d1);
      $d0 = $d1;

      $o = "";
      if (length(join("",values %$counter_run)) < $max_run
                         and $self->fetch()) {
         $WAIT   = 1;
         my $dbh = $self->dbh();
         $dbh->disconnect();
         delete($self->{'DBH'});
         undef($dbh);
         $o = fork();
         if ($o) {
            $counter_run->{$o} = 1;
            $WAIT = 0;
         } else {
            Time::HiRes::time() =~ /(\d\d\d)$/;
            srand(sprintf("%1u",0.001*($$||1000)*$1));
            $VAR1 = shift(@{$self->{'___DATA___'}});
            $IDX  = $self->{'___DATA___'};
            $self->{'ID'}         = $self->{'___DUMP___'}->[0];
            $self->{'CONNECTION'} = $self->{'___DUMP___'}->[1];
            $self->{'STATUS'}     = $self->{'___DUMP___'}->[3];
            $self->{'FETCHED'}    = 1;
         }
         delete ($self->{'___DUMP___'});
         delete ($self->{'___DATA___'});
      }
      elsif (length(join("",values %$counter_new)) < $max_new) {
         $NEW = 1;
         my $dbh = $self->dbh();
         $dbh->disconnect();
         delete($self->{'DBH'});
         undef($dbh);
         $o = fork();
         if ($o) {
            $counter_new->{$o} = 1;
            $WAIT = 0;
         } else {
            Time::HiRes::time() =~ /(\d\d\d)$/;
            srand(sprintf("%1u",0.001*($$||1000)*$1));
         }
      }
      else {
         $o = "mainproc";
         $text = waitpid(-1,WNOHANG);
         if ($text and $text != -1) {
            $WAIT = 0;
            delete ($counter_new->{$text});
            delete ($counter_run->{$text});
         }
         elsif ($ENV{'SIG_INT'}) {
            if (!$max_new and !$max_run) {
               sleep 1;
            } else {
               $max_new = 0;
               $max_run = 0;
            }
            print "Waiting for ...\n" . join("\n",keys %$counter_run) . "\n";
         }
         elsif ($param_file and (-f $param_file)) {
             open(FFILE,"<".$param_file);
             $WAIT = join("",<FFILE>);
             close FFILE;
             unlink($param_file);
             if ($WAIT =~ /(\d+)\,(\d+)/) {
                $max_new = $1;
                $max_run = $2;
             }
             $WAIT = 0;
         }
         else {
            Time::HiRes::usleep(10000) if $WAIT;
            $WAIT = 1;
         }
      }
      last if (!$o);
      if (!$max_new and !$max_run and !%$counter_run) {
         print "STOP ...\n";
         foreach $o (keys %$counter_new) {
            kill(15,$o);
         }
         while (0 == 0) {
            if ($self->lock_semaphore("__proc_nr__")) {
               $o = $self->read_semaphore("__proc_nr__");
               if ($o == 1) {
                  $self->delete_all_semaphores();
               } else {
                  $self->write_semaphore("__proc_nr__",sprintf("%1u",$o-1));
                  $self->unlock_semaphore("__proc_nr__");
               }
               exit;
            }
            Time::HiRes::usleep(300000);
         }
      }
      
   }
   
#--------------------------------------------

   if (!$VAR1) { exit; }
   eval($VAR1); print $@;
   $self->{'OBJ'}    = $VAR1->[0];
   $self->{'TEXT'}   = $VAR1->[1];
   if ($@) { print "FEHLER in DBComSimple: $@\n"; exit; }

   foreach $o (@{$self->{'INDEX'}}) {          #  Manuell geaenderte Indexe 
      $self->{$o} = shift(@$IDX);              #  nachziehen
   }

   if ($self->load_classes($self->{'OBJ'})) {  #  die fehlenden Klassen
      $self->{'OBJ'}->{'PARENT'} = $self;      #  im wiederaufgetauten
   }                                           #  Prozess nachladen

   print "STATUS: " . $self->{'STATUS'};
   
   while (0 == 0) {

      if ($self->{'STATUS'} == 0) {  #  Neuer Task
         $self->{'TEXT'}   = $self->get($self->max_time());
         $self->{'STATUS'} = 2;
      }

      elsif ($self->{'STATUS'} == 1) {  #  Warten auf Anfrage DBComSimple
         $o = $self->get();
         if (ref($o)) {
            $self->{'TEXT'} = $o;
         }
         $self->{'STATUS'} = 2;
         if ($self->{'TEXT'}->[0] eq "___END___") {
            $sleeptime = -1;
         }
      }
      
      elsif ($self->{'STATUS'} == 2) {  #  Verzweigen in das
                                        #  Applikations-Objekt
         $o = shift(@{$self->{'TEXT'}});
         if (!($self->{'OBJ'})) {
            eval("use $o"); print $@;
            if ($@) {
               $self->{'TEXT'} = ["___END___","ERROR in Module $o: $@"];
            } else {
               $self->{'OBJ'} = $o->new();
               if (@{$self->{'TEXT'}}) {
                  unshift(@{$self->{'TEXT'}},"___NEXT___");
               } else {
                  $self->{'TEXT'} = ["Module $o loaded"];
               }
            }
         } else {
            $self->{'TEXT'} = $self->{'OBJ'}->$o(@{$self->{'TEXT'}});
         }
         if ($self->{'TEXT'}->[0] =~ /^___(NEXT)(\d*)___$/) {
            $sleeptime = $2;  #  warten, dann weiter in dem Objekt
            shift(@{$self->{'TEXT'}});
            if ($sleeptime <= $wait) {
               sleep($sleeptime);  #  weiter ohne Freeze
               $sleeptime = 0;
            }
         } else {
            $self->{'STATUS'} = 4;   #  Rueckgabe einer Message
         }
      }
      
      elsif ($self->{'STATUS'} == 4) {  #  Rueckgabe an den Client, dann Warten
         if ($self->{'TEXT'}->[0] =~ /^___(WAIT)(\d*)___$/) {
            $sleeptime = $2 || 1;
            shift(@{$self->{'TEXT'}});
         } else {
            $sleeptime = $self->max_time();
         }      
         $self->msg($self->{'TEXT'});
         if ($self->{'TEXT'}->[0] eq "___END___") {
            $sleeptime = -1;
         }
         $self->{'STATUS'} = 1;
      }
       
      last if ($sleeptime);
      
   }
   print " ---> $self->{'ID'}: waiting $sleeptime sec for: $self->{'CONNECTION'} \n";

   my $idx = {};
   foreach $o (@{$self->{'INDEX'}}) {
      $idx->{$o} = $self->{$o};
   }

   $o = 1;
   while ($o < 30) {
      $text = $self->push($sleeptime,$idx,$self->{'CONNECTION'});
      return() if ($sleeptime == -1);
      return() if (!$text);
      sleep 1;
      $o = $o + 1;
   }
   
}

#******************************************************************

#  Nachladen der benoetigten Klassen nach fetch

sub load_classes {

   my $self = shift;
   my $obj  = shift;
   
   print "Re-Loaded OBJ: $obj\n" if ($obj);
   
   my $rtype = ref($obj);
   my $o;
   if ($rtype eq "ARRAY") {
      foreach $o (@$obj) {
         $self->load_classes($o);
      }
   }
   elsif ($rtype eq "HASH") {
      foreach $o (values %$obj) {
         $self->load_classes($o);
      }
   }
   else {
      eval("use $rtype");
   }
   
   return($obj);

}

#******************************************************************

sub fetch {

   my $self = shift;
   my $file; my $o1; my $id; my $conn_id; my @ee;
   my $list;
   
   my $dbh = $self->dbh();

   my $conn  = $self->{'CONN'};
   my $store = $self->{'STORE'};
   

   $file = $dbh->prepare("select id,conn,sleep,status from $store" .
                           " where sleep < ".time().
                           " limit 1");
   $file->execute();    # einen Prozess holen, dessen Sleeptime abgelaufen ist
   @ee = $file->fetchrow();
   $file->finish();
   if (@ee) { if ($ee[1] =~ /^\.run\./) { @ee = (); } }
                                     # wenn Objekt schon in Bearbeitung
   if (!@ee) {  #  einen Prozess holen, fuer den ein Reply-Request vorliegt
      $file = $dbh->prepare("select " .
                       "$store.id,$store.conn,$store.sleep,$store.status " . 
                       "from $store,$conn " .
                       "where $store.conn = $conn.replynr " .
                       "limit 1");
      $file->execute();
      @ee = $file->fetchrow();
      $file->finish();
   }
   if (!@ee) {  #  einen Prozess holen, fuer den ein Stack-Request vorliegt
      $file = $dbh->prepare("select " .
                       "$store.id,$store.conn,$store.sleep,$store.status " . 
                       "from $store,$conn " .
                       "where $store.id = $conn.id and " .
                       "$conn.replynr = '" . $self->{'RESET_ID'} . "' " .
                       "limit 1");
      $file->execute();
      @ee = $file->fetchrow();
      $file->finish();
   }


   $self->{'___DUMP___'} = [@ee];

   while (0 == 0) {
      $file = $dbh->do("update $store set objlock='1' where id like '" .
                      $ee[0] . "' and objlock='0'");
      last if ($file ne "0E0");
      print "___UPDATE_FAILED___\n";
      Time::HiRes::usleep(100000);
   }
   $file = $dbh->prepare("select text" . join(",","",@{$self->{'INDEX'}}) .
                         " from $store where id='" .
                          $self->{'___DUMP___'}->[0] .
                          "' and objlock='1' limit 1");
   $file->execute();
   @ee = $file->fetchrow();
   $file->finish();
   if (!@ee) { print "FEHLER beim Locking 1...\n"; exit; }
   $self->{'___DATA___'} = \@ee;

   $file = $dbh->do("update $store set conn='.run.', " .
         "objlock='0' where id='" . $self->{'___DUMP___'}->[0]
         . "' and objlock='1'");
   if ($file eq "0E0") { print "FEHLER beim Locking 2...\n"; exit; }

   return(1);
   
}
      
#******************************************************************

sub push {

   my $self      = shift;
   my $sleeptime = shift;
   my $idx       = shift;
   my $conn_id   = shift;

   my $o; my $o1; my $o2; my @ee; my $file;

   my $dbh   = $self->dbh();
   my $store = $self->{'STORE'};
   my $lock  = $self->{'LOCK'};
   if ($self->{'OBJ'}) { delete ($self->{'OBJ'}->{'PARENT'}); }

#   $dbh->do("delete from $lock where id='".$self->{'CONNECTION'}."'");

   if    ($sleeptime == 0) {
      $sleeptime = time() - 1;
   }
   elsif ($sleeptime > 0) {
      $sleeptime = time() + $sleeptime;
      if ($sleeptime > $self->max_time()) { $sleeptime = $self->max_time(); }
   }

   if ($sleeptime == -1) {
      $self->get(1);
      $o = $dbh->do("delete from $store where id='"
                . substr($self->{'ID'},0,22) . "'");
      return("___DELETED___");
   }

   elsif (!($self->{'FETCHED'})) {  # Objekt ist noch nicht in der Datenbank
      $o1 = ""; $o2 = ""; @ee = ();
      foreach $o (keys %$idx) {
         $o1 = $o1 . "," . $o;
         $o2 = $o2 . ",?";
         push(@ee,$idx->{$o});
      }
      $o = $dbh->do("insert into $store (conn,sleep,id,text,objlock,status$o1) " .
                            " values ('$conn_id',$sleeptime,?,?,'0'," .
                                $self->{'STATUS'} . "$o2)",
                             {},substr($self->{'ID'},0,22),
                             Dumper([$self->{'OBJ'},
                                     $self->{'TEXT'}]),
                             @ee);
      if ($o eq "0E0") {
         print "___INSERT_FAILED___\n";
         return("___INSERT_FAILED___\n");
      }
   }

   else {
      $o1 = ""; $o2 = ""; @ee = ();
      foreach $o (keys %$idx) {
         $o1 = $o1 . " ," . $o . "=?";
         push(@ee,$idx->{$o});
      }
      $o = $dbh->do("update $store set conn='$conn_id', sleep=$sleeptime, " .
                    "text=?, objlock='0', status=" .
                       $self->{'STATUS'} . " $o1 where id=?",
                      {},
                      Dumper([$self->{'OBJ'},
                              $self->{'TEXT'}]),
                             @ee,
                      substr($self->{'ID'},0,22));
      if ($o eq "0E0") {
         print "___UPDATE_FAILED___\n";
         print "$self->{'ID'}  update $store set conn='$conn_id', sleep=$sleeptime, " .
                    "text=?, objlock='0' $o1 where id=?\n";
         return("___UPDATE_FAILED___") if ($o eq "0E0");
      }
   }

   return(0);
   
}

#******************************************************************
#******************************************************************

sub lock_semaphore {

   my $self = shift;
   my $id   = shift;
   
   my $dbh = $self->dbh();

   my $cursor = $dbh->prepare("select semalock from " . $self->{'SEMA'} .
                              " where id='$id' limit 1");
   $cursor->execute();
   my @ee = $cursor->fetchrow();
   $cursor->finish();
   
   if (!@ee) {
      $ee[0] = $dbh->do("insert into " . $self->{'SEMA'} .
                        " (id,text,semalock) values ('$id','',1)",
                         { PrintError => 0 });
      return(1) if ($ee[0] ne "0E0");
   }               
      
   $ee[0] = $dbh->do("update " . $self->{'SEMA'} . " set semalock='1' " .
                     "where id like '$id' and semalock='0'",
                       { PrintError => 0 });
   return(0) if ($ee[0] eq "0E0");
   return(1);
   
}

#******************************************************************

sub read_semaphore {

   my $self = shift;
   my $id   = shift;
   
   my $dbh = $self->dbh();

   my $cursor = $dbh->prepare("select text from " . $self->{'SEMA'} .
                              " where id='$id' and semalock='1' limit 1");
   $cursor->execute();
   my @ee = $cursor->fetchrow();
   $cursor->finish();
   
   if (!@ee) {
      return("___NO_SEMAPHORE_$id\_FOUND___");
   }
   return($ee[0]);
   
}

#******************************************************************

sub write_semaphore {

   my $self = shift;
   my $id   = shift;
   my $text = shift;
   
   my $dbh = $self->dbh();
   my $o   = $dbh->do("update " . $self->{'SEMA'} . " set text='$text' " .
                      "where id='$id' and semalock='1'",
                       { PrintError => 0 });
   return(0) if ($o eq "0E0");
   return(1);
   
}

#******************************************************************

sub unlock_semaphore {

   my $self = shift;
   my $id   = shift;
   
   my $dbh = $self->dbh();
   my $o   = $dbh->do("update " . $self->{'SEMA'} . " set semalock='0' " .
                      "where id='$id' and semalock='1'",
                       { PrintError => 0 });
   return(0) if ($o eq "0E0");
   return(1);
   
}

#******************************************************************

sub delete_semaphore {

   my $self = shift;
   my $id   = shift;
   
   my $dbh = $self->dbh();
   my $o   = $dbh->do("delete from " . $self->{'SEMA'} . " where id='$id'",
                       { PrintError => 0 });
   return(0) if ($o eq "0E0");
   return(1);
   
}

#******************************************************************

sub delete_all_semaphores {

   my $self = shift;
   my $id   = shift;
   
   my $dbh = $self->dbh();
   my $o   = $dbh->do("delete from " . $self->{'SEMA'} .
                      " where id like '$id\%'",
                       { PrintError => 0 });
   return(0) if ($o eq "0E0");
   return(1);
   
}

#******************************************************************

1;

bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped)
Email: contact@elmoujehidin.net bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped) Email: contact@elmoujehidin.net