Anzeige:
Ergebnis 1 bis 8 von 8

Thema: Maximale Anzahl der Filehandler

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.01.2005
    Ort
    Nettetal
    Beiträge
    72

    Maximale Anzahl der Filehandler

    Hallo,
    Ich schreib mir grade ein Script, dass alle Mails in bestimmten Ordnern meiner Mailboxen in nen Temp-Ordner verschiebt und dann dem Spamassasin diese Mails als Spam beibringt.

    Um jede Mailbox bei jeder Domain zu durchlaufen brauche ich 3 oder 4 Schleifen, bei denen halt die Ordner durchsucht werden.
    Jetzt hab ich das Problem, dass PHP bei der letzten Schleife mit der Fehlermeldung "Warning: readdir(): 7 is not a valid Directory resource in /root/sa-learn.php on line 40" abbricht.

    Ich schließe den Filehandler vorher auch nicht. Wenn ich ihn mit echo ausgeben lasse, erhalte ich "Resource id #7". Sollte stimmen.

    Gibts da irgendwie ne Begrenzung wie viele Filehandler man öffnen kann in PHP? Aber wenn ja, dann liegt die doch nicht bei 3 oder 4 oder?
    Und das System selber kann auch nicht so viele Handler offen haben.
    In der Config hab ich nichts dazu gefunden.

    Hier mein Script... Die Kommentare sind mal Englisch, mal Deutsch. Nicht gut, aber ich bin ja auch noch nicht fertig mit dem Script:
    Code:
    #!/usr/bin/php
    <?php
    
    ###################### CONFIG ######################
    
    $tmpdir = "/tmp/salearn"; #WITHOUT slash at the end
    $maildir = "/home/vmail"; #WITHOUT slash at the end
    
    ###################### SCRIPT ######################
    //Don't edit anything unless you know what you are doing!
    
    echo "Starting sa-learn.php at " . date("j.n.y H:i:s") . "\n";
    
    echo "Creating " . $tmpdir . " and subdirs\n";
    mkdir($tmpdir);
    mkdir($tmpdir . "/ham");
    mkdir($tmpdir . "/spam");
    
    echo "Moving all Messages into temporary Folders\n";
    if($dir = opendir($maildir))
    {
      while(($domaindir = readdir($dir)) != false) //Alle Domains durchgehen
      {
        if($domaindir != "deleted-maildirs" && is_dir($maildir . "/" . $domaindir) && $domaindir != "."  && $domaindir != "..") //Nur Ordner und nicht deleted-maildirs
        {
        echo $domaindir . "\n";
          if($accounts = opendir($maildir . "/" .$domaindir))
          {
            while(($accountdir = readdir($accounts)) != false) //Alle Accounts durchgehen
            {
              if(is_dir($maildir . "/" . $domaindir . "/" . $accountdir) && $accountdir != "."  && $accountdir != "..") //Nur Verzeichnisse
              {
              echo $accountdir . "\n";
                if(file_exists($maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam")) //Only go on if spam learning dir exists
                {
                  if($mails = opendir($maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam/cur")) //Open Spamdir for learning
                  {
                  echo $mails."\n";
                  echo $maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam/cur";
                    while(($mail = readdir($mails)) != false)
                    {
                      if(!is_dir($maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam/cur/" . $mail))
                      {
                        //copy($maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam/cur/" . $mail, $tmpdir . "/spam");
                      }
    
                      closedir($mails);
                    }
                  }
                  else
                    echo "ERROR while opening Maildir " . $maildir . "/" .$domaindir . $accountdir . "/.Spam.Learn-Spam/cur";
                }
                else
                  echo "INFO: Spam learning dir doesn't exist in " . $maildir . "/" . $domaindir . "/" . $accountdir . "\n";
              }
            }
            closedir($accounts);
            echo "closed accounts\n";
          }
          else
            echo "ERROR while opening Maildir " . $maildir . "/" .$domaindir;
        }
      }
    
      closedir($dir);
      echo "closed dir\n";
    }
    else
      echo "ERROR while opening Maildir " . $maildir;
    
    
    echo "Cleaning up...\n";
    recursiveRemoveDirectory($tmpdir);
    
    
    
    function recursiveRemoveDirectory($path)
    {
      $dir = new RecursiveDirectoryIterator($path);
      foreach(new RecursiveIteratorIterator($dir) as $file)
      {
        unlink($file);
      }
    
      foreach($dir as $subdir)
      {
        if(!@rmdir($subdir))
        {
          recursiveRemoveDirectory($subdir);
        }
      }
      rmdir($path);
    }
    
    ?>

  2. #2
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Zitat Zitat von Andy1988 Beitrag anzeigen
    Fehlermeldung "Warning: readdir(): 7 is not a valid Directory resource in /root/sa-learn.php on line 40" abbricht.

    Ich schließe den Filehandler vorher auch nicht. Wenn ich ihn mit echo ausgeben lasse, erhalte ich "Resource id #7". Sollte stimmen.

    Gibts da irgendwie ne Begrenzung wie viele Filehandler man öffnen kann in PHP? Aber wenn ja, dann liegt die doch nicht bei 3 oder 4 oder?
    Und das System selber kann auch nicht so viele Handler offen haben.
    In der Config hab ich nichts dazu gefunden.
    Ne mit Filehandler hat das nix zu tun.
    Schau dir mal die Dateifunktionen von PHP an.
    Unter Linux gibt es nicht nur Dateien und Verzeichnisse. Es fehlen
    einfach einige Prüfungen.

    Zitat Zitat von Andy1988 Beitrag anzeigen
    Hier mein Script... Die Kommentare sind mal Englisch, mal Deutsch. Nicht gut, aber ich bin ja auch noch nicht fertig mit dem Script:
    Es das wirklich dein Script, oder Copy/Paste mit ein wenig Mauschel Mauschel oben drauf?

    Wenn Du es richtig machen willst, schreib das Ding neu.
    So schwer ist das nicht, und blickst du auch durch.
    Tip: php -q + nimm ne Recursion für deine Verzeichnisse.
    Das ist schneller.
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.01.2005
    Ort
    Nettetal
    Beiträge
    72
    Ja... Ist mein Script.

    Das komische ist nur, dass das Verzeichnis, dass ich mit opendir() öffne auch wirklich ein Verzeichnis ist. Und keine Datei oder ein Link oder sonst was.

  4. #4
    Registrierter Benutzer Avatar von Romanday
    Registriert seit
    03.02.2004
    Beiträge
    829
    Zitat Zitat von Andy1988 Beitrag anzeigen
    Ja... Ist mein Script.

    Das komische ist nur, dass das Verzeichnis, dass ich mit opendir() öffne auch wirklich ein Verzeichnis ist. Und keine Datei oder ein Link oder sonst was.
    Mag sein, aber irgendwo hast 1 oder mehrere Prüfungen zu wenig.
    Sonst würde keine Fehlermeldung kommen. opendir ist ja auch richtig,
    bloß die Fehlermeldung bezieht sich auf readdir().

    Mach mal ein Backup Verzeichnis mit wenig Files und Dir und laß dir
    anzeigen was verschoben wurde. Dann kannst du doch viel schneller
    herausfinden wo der Fehler ist.

    Ich würde auch mal eine Fehlermeldung mit is_readable() einbauen.
    Abriss, bzw. die Sprengung des World Trade Centers
    WDR Dokumentation
    Doku + DT Untertitel
    Weitere Infos - Terrorstorm

  5. #5
    Registrierter Benutzer
    Registriert seit
    19.08.2004
    Beiträge
    404
    Hallo Andy1988,

    Dieser codeteil ist verantwortlich für den Fehler:

    PHP-Code:
    while(($mail readdir($mails)) != false)
    {
      if(!
    is_dir($maildir "/" $domaindir "/" $accountdir "/.Spam.Learn-Spam/cur/" $mail))
      {
        
    //copy($maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam/cur/" . $mail, $tmpdir . "/spam");
      
    }
      
    closedir($mails);

    Vermutlich siehst Du das Problem jetzt schon selber...
    Beim ersten Durchlauf der while-Schleife schließt Du das Filehandle $mails wieder... damit schlägt der nächste Leseversuch von readddir natürlich fehl, weil das angegebene Filehandle ja garnicht mehr exisitert...

    richtig wäre also:
    PHP-Code:
    while(($mail readdir($mails)) != false)
    {
      if(!
    is_dir($maildir "/" $domaindir "/" $accountdir "/.Spam.Learn-Spam/cur/" $mail))
      {
        
    //copy($maildir . "/" . $domaindir . "/" . $accountdir . "/.Spam.Learn-Spam/cur/" . $mail, $tmpdir . "/spam");
      
    }
    }
    closedir($mails); 
    hth, Michael

  6. #6
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Also was du vorhast solltest du eher mit einem Shell Script und Cron machen.
    Wenn du das Unbedingt mit PHP machen willst werfe die Schleifen weg und sehe dir die Imap Funktion in PHP an. Denn es ist Wichtig das die Nachrichten geflaggt werden. Sonst haben dein E-Mail Clienten massive Probleme
    PHP-Code:
       public function SetSpamMailByID$id )
       {
          if ( (int)
    $id == )
             return 
    false;

          
    // DebugToLog( array( $Header, imap_last_error() ) );
          
    $Header imap_headerinfo$this->IMAP$id );
          if ( 
    is_object$Header ) && (int)$Header->Msgno >= )
          {
             
    imap_setflag_full$this->IMAP$Header->Msgno'\\Seen \\Flagged' );
             if ( 
    array_key_exists'Spam'$this->MBOXES ) )
             {
                
    $b imap_mail_move$this->IMAP$Header->Msgno"INBOX.Spam" );
                
    imap_expunge$this->IMAP );
                
    // DebugToLog( $b );
                
    return $b;
             } else
                return 
    false;
          } else
             return 
    false;
       } 
    Mit Cron - Das ist im Übrigen auch meine Variante - geht das schneller.
    Denn es gibt nur einen Benutzer der lernen muss das ist entweder spamd oder der amavis Daemon.
    Bei mir sieht jede Stunde cron.hourly in Jeden Benutzer Spam Postfach nach Mails.
    Code:
    #!/bin/bash
    umask 022
    
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    export PATH
    
    # get information from /etc/sysconfig
    if [ -f /etc/sysconfig/cron ] ; then
        . /etc/sysconfig/cron
    fi
    
    VIRTUAL=/var/spool/virtual_mailboxes
    
    AMAVISD_DB=/var/spool/amavis/var
    VIRTUAL_DB=/var/spool/virtual_mailboxes/my-domain.de
    
    if [ -d $VIRTUAL ] ; then
      echo "sa-learn [`date +"%T"`]" >> /var/log/spamassassin-sa-learn.log
      for i in `find $VIRTUAL -mindepth 2 -maxdepth 3 -type d` ; do
        if [ -d $i/.Spam ] ; then
          for mfile in `find $i/.Spam -type f -exec grep -l '^X\-' {} \;` ; do
            if [ ! -n "`grep 'application\/pgp' $mfile`" ] ; then
              echo $mfile >> /var/log/spamassassin-sa-learn.log
              /usr/bin/sa-learn --dbpath $AMAVISD_DB/.spamassassin --spam $mfile > /dev/null
              /usr/bin/sa-learn --dbpath $VIRTUAL_DB/.spamassassin --spam $mfile > /dev/null
              rm -f $mfile
            fi
          done
          rm -f $i/.Spam/*/.avrc
        fi
      done
      chown -R vscan.vscan $AMAVISD_DB
      chown -R popuser.popuser $VIRTUAL_DB
    fi
    exit 0
    Ich füttere in diesem Fall Zwei Benutzer einmal Amavis das von Postfix aufgerufen wird und einmal Virtual was ein ACL Postfach von Courier ist.
    Geändert von undefined (10-12-2006 um 10:56 Uhr)
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  7. #7
    Registrierter Benutzer
    Registriert seit
    02.01.2005
    Ort
    Nettetal
    Beiträge
    72
    OK... Überzeugt!
    Shellscript ist eindeutig besser

    Danke für deine Variante!

    edit:
    Eine Frage:
    Was bewirkt das Löschen dieser Datei?
    Code:
    rm -f $i/.Spam/*/.avrc
    Geändert von Andy1988 (11-12-2006 um 15:04 Uhr)

  8. #8
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Sie beinhaltet den MBOX Index.
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •