gunnar: server/php-kolab/Kolab_Filter/Filter Filter.php, 1.2, 1.3 Incoming.php, 1.3, 1.4 Outgoing.php, 1.3, 1.4 Outlook.php, 1.2, 1.3

cvs at kolab.org cvs at kolab.org
Tue Nov 27 13:35:25 CET 2007


Author: gunnar

Update of /kolabrepository/server/php-kolab/Kolab_Filter/Filter
In directory doto:/tmp/cvs-serv12401/php-kolab/Kolab_Filter/Filter

Modified Files:
	Filter.php Incoming.php Outgoing.php Outlook.php 
Log Message:
The kolab-filter error handler has been fixed. This hopefully gives us a clean exit state towards postfix at all times.

Index: Filter.php
===================================================================
RCS file: /kolabrepository/server/php-kolab/Kolab_Filter/Filter/Filter.php,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Filter.php	27 Nov 2007 10:01:52 -0000	1.2
+++ Filter.php	27 Nov 2007 12:35:23 -0000	1.3
@@ -41,12 +41,35 @@
 /* Load the Filter libraries */
 require_once 'Kolab/Filter/Transport.php';
 
+/* Some output constants */
+define('OUT_STDOUT', 128);
+define('OUT_LOG', 256);
+
+/* Failure constants from postfix src/global/sys_exits.h */
+define('EX_USAGE', 64);       /* command line usage error */
+define('EX_DATAERR', 65);     /* data format error */
+define('EX_NOINPUT', 66);     /* cannot open input */
+define('EX_NOUSER', 67);      /* user unknown */
+define('EX_NOHOST', 68);      /* host name unknown */
+define('EX_UNAVAILABLE', 69); /* service unavailable */
+define('EX_SOFTWARE', 70);    /* internal software error */
+define('EX_OSERR', 71);       /* system resource error */
+define('EX_OSFILE', 72);      /* critical OS file missing */
+define('EX_CANTCREAT', 73);   /* can't create user output file */
+define('EX_IOERR', 74);       /* input/output error */
+define('EX_TEMPFAIL', 75);    /* temporary failure */
+define('EX_PROTOCOL', 76);    /* remote error in protocol */
+define('EX_NOPERM', 77);      /* permission denied */
+define('EX_CONFIG', 78);      /* local configuration error */
+
 class Filter 
 {
     var $_transport;
 
     var $_startts;
 
+    var $_debug;
+
     var $_tmpdir;
     
     var $_tmpfile;
@@ -58,11 +81,12 @@
     var $_fqhostname;
     var $_sasl_username;
 
-    function Filter($transport = 'StdOut')
+    function Filter($transport = 'StdOut', $debug = false)
     {
         global $conf;
 
         $this->_transport = $transport;
+        $this->_debug = $debug;
 
         $this->_startts = $this->_microtime_float();
 
@@ -72,6 +96,9 @@
             $this->_tmpdir = sys_get_temp_dir();
         }
 
+        /* Set a custom PHP error handler to catch any coding errors */
+        set_error_handler(array($this, '_fatal'));
+
         // FIXME: Do we need this?
         /* This is used as the default domain for unqualified adresses */
         global $_SERVER;
@@ -100,17 +127,30 @@
         }
     }
 
+    function parse($inh = STDIN)
+    {
+        $result = $this->_start();
+        if ($result instanceof PEAR_Error) {
+            $this->_handle($result);
+        }
+
+        $result = $this->_parse($inh);
+        if ($result instanceof PEAR_Error) {
+            $this->_handle($result);
+        }
+    }
+    
     function _start()
     {
         /* Setup the temporary storage */
         $result = $this->_initTmp();
-        if (is_a($result, 'PEAR_Error')) {
+        if ($result instanceof PEAR_Error) {
             return $result;
         }
         
         /* Parse our arguments */
         $result = $this->_parseArgs();
-        if (is_a($result, 'PEAR_Error')) {
+        if ($result instanceof PEAR_Error) {
             return $result;
         }
 
@@ -159,8 +199,8 @@
         if (!array_key_exists('r', $options) ||
             !array_key_exists('s', $options)) {
             return PEAR::raiseError(sprintf(_("Usage is %s -s sender at domain -r recipient at domain"),
-                                            $args[0]),
-                                    OUT_STDOUT | ERR_TEMPFAIL);
+                                             $args[0]),
+                                     OUT_STDOUT | EX_USAGE);
         }
 
         $this->_sender = strtolower($options['s']);
@@ -200,7 +240,7 @@
             $msg = $php_errormsg;
             return PEAR::raiseError(sprintf(_("Error: Could not open %s for writing: %s"),
                                             $this->_tmpfile, $msg),
-                                    OUT_LOG | ERR_TEMPFAIL);
+                                    OUT_LOG | EX_IOERR);
         }
 
         register_shutdown_function(array($this, '_cleanupTmp'));
@@ -226,20 +266,95 @@
             return $transport;
         }
         return PEAR::raiseError(sprintf(_("No such class \"%s\""), $class),
-                                OUT_LOG | ERR_TEMPFAIL);
+                                OUT_LOG | EX_CONFIG);
     }
 
     function _rewriteCode($result) 
     {
         if ($result->getCode() < 500) {
-            $code = ERR_TEMPFAIL;
+            $code = EX_TEMPFAIL;
         } else {
-            $code = ERR_UNAVAILABLE;
+            $code = EX_UNAVAILABLE;
         }
         $append = sprintf(_(", original code %s"), $result->getCode());
         $result->message = $result->getMessage() . $append;
         $result->code = OUT_LOG | OUT_STDOUT | $code;
         return $result;
+    }
+
+    function _fatal($errno, $errmsg, $filename, $linenum, $vars)
+    {
+        /* Ignore strict errors for now since even PEAR will raise
+         * strict notices 
+         */
+        if ($errno == E_STRICT) {
+            return false;
+        }
+
+        $fatal = array(E_ERROR,
+                       E_PARSE,
+                       E_CORE_ERROR,
+                       E_COMPILE_ERROR,
+                       E_USER_ERROR);
+
+        if (in_array($errno, $fatal)) {
+            $code = OUT_STDOUT | OUT_LOG | EX_UNAVAILABLE;
+            $msg = 'CRITICAL: You hit a fatal bug in kolab-filter. Please inform the Kolab developers at https://www.intevation.de/roundup/kolab/. The error was: ' . $errmsg;
+        } else {
+            $code = 0;
+            $msg = $errmsg;
+        }
+
+        $error = &new PEAR_Error($msg, $code);
+        $this->_handle($error);
+
+        if ($errno == E_ERROR) {
+            exit(0);
+        }
+        return false;
+    }
+
+    function _log($result)
+    {
+        $msg = $result->getMessage();
+
+        /* Log all errors */
+        $frame = $result->getBacktrace(1);
+
+        /* In debugging mode the errors get delivered to the screen
+         * without a time stamp (mainly because of unit testint) 
+         */
+        if (!$this->_debug) {
+            Horde::logMessage($msg, $frame['file'], $frame['line']);
+        } else {
+            $msg .= ' (Line ' . $frame['line'] . ' in ' . basename($frame['file']) . ")\n";
+            fwrite(STDOUT, $msg);
+        }
+    }
+    
+    function _handle($result)
+    {
+        $msg = $result->getMessage();
+        $code = $result->getCode();
+
+        if ($code & OUT_STDOUT) {
+            fwrite(STDOUT, $msg);
+        }
+
+        if ($code & OUT_LOG || empty($code)) {
+            $this->_log($result);
+        }
+        
+        // FIXME: Add a userinfo handler in case there were multiple
+        // combined errors
+
+        /* If we have an error code we want to return it to the
+         * calling application and exit here
+         */
+        if ($code) {
+            /* Return the first seven bits as error code to postfix */
+            exit($code & 127);
+        }
     }
 }
 

Index: Incoming.php
===================================================================
RCS file: /kolabrepository/server/php-kolab/Kolab_Filter/Filter/Incoming.php,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Incoming.php	27 Nov 2007 10:01:52 -0000	1.3
+++ Incoming.php	27 Nov 2007 12:35:23 -0000	1.4
@@ -41,18 +41,13 @@
 
     var $_add_headers;
 
-    function Filter_Incoming($transport = 'LMTP')
+    function Filter_Incoming($transport = 'LMTP', $debug = false)
     {
-        Filter::Filter($transport);
+        Filter::Filter($transport, $debug);
     }
     
-    function parse($inh = STDIN)
+    function _parse($inh = STDIN)
     {
-        $result = $this->_start();
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
         $ical = false;
         $add_headers = array();
         $headers_done = false;
@@ -72,7 +67,7 @@
                 $msg = $php_errormsg;
                 return PEAR::raiseError(sprintf(_("Error: Could not write to %s: %s"),
                                                 $this->_tmpfile, $msg),
-                                        OUT_LOG | ERR_TEMPFAIL);
+                                        OUT_LOG | EX_TEMPFAIL);
             }
         }
 
@@ -82,7 +77,7 @@
                 $msg = $php_errormsg;
                 return PEAR::raiseError(sprintf(_("Error: Could not write to %s: %s"),
                                                 $this->_tmpfile, $msg),
-                                        OUT_LOG | ERR_TEMPFAIL);
+                                        OUT_LOG | EX_TEMPFAIL);
             }
         }
 
@@ -90,7 +85,7 @@
             $msg = $php_errormsg;
             return PEAR::raiseError(sprintf(_("Error: Failed closing %s: %s"),
                                             $this->_tmpfile, $msg),
-                                    OUT_LOG | ERR_TEMPFAIL);
+                                    OUT_LOG | EX_TEMPFAIL);
         }
 
         if ($ical) {
@@ -156,7 +151,7 @@
             $msg = $php_errormsg;
             return PEAR::raiseError(sprintf(_("Error: Could not open %s for writing: %s"),
                                             $this->_tmpfile, $msg),
-                                    OUT_LOG | ERR_TEMPFAIL);
+                                    OUT_LOG | EX_TEMPFAIL);
         }
 
         $result = $transport->start($this->_sender, $this->_recipients);

Index: Outgoing.php
===================================================================
RCS file: /kolabrepository/server/php-kolab/Kolab_Filter/Filter/Outgoing.php,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- Outgoing.php	27 Nov 2007 10:01:52 -0000	1.3
+++ Outgoing.php	27 Nov 2007 12:35:23 -0000	1.4
@@ -43,12 +43,12 @@
 
 class Filter_Outgoing extends Filter
 {
-    function Filter_Outgoing($transport = 'SMTP')
+    function Filter_Outgoing($transport = 'SMTP', $debug = false)
     {
-        Filter::Filter($transport);
+        Filter::Filter($transport, $debug);
     }
     
-    function parse($inh = STDIN)
+    function _parse($inh = STDIN)
     {
         global $conf;
 
@@ -70,11 +70,6 @@
             $allow_outlook_ical_forward = true;
         }
 
-        $result = $this->_start();
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
         $ical = false;
         $from = false;
         $subject = false;
@@ -147,7 +142,7 @@
                 $msg = $php_errormsg;
                 return PEAR::raiseError(sprintf(_("Error: Could not write to %s: %s"),
                                                 $this->_tmpfile, $msg),
-                                        OUT_LOG | ERR_TEMPFAIL);
+                                        OUT_LOG | EX_IOERR);
             }
         }
         while (!feof($inh)) {
@@ -156,7 +151,7 @@
                 $msg = $php_errormsg;
                 return PEAR::raiseError(sprintf(_("Error: Could not write to %s: %s"),
                                                 $this->_tmpfile, $msg),
-                                        OUT_LOG | ERR_TEMPFAIL);
+                                        OUT_LOG | EX_IOERR);
             }
         }
 
@@ -164,7 +159,7 @@
             $msg = $php_errormsg;
             return PEAR::raiseError(sprintf(_("Error: Failed closing %s: %s"),
                                             $this->_tmpfile, $msg),
-                                    OUT_LOG | ERR_TEMPFAIL);
+                                    OUT_LOG | EX_IOERR);
         }
 
         if (!$senderok) {
@@ -180,7 +175,7 @@
             } else {
                 return PEAR::raiseError(sprintf(_("Invalid From: header. %s looks like a forged sender"),
                                                 $from),
-                                        OUT_LOG | OUT_STDOUT | ERR_UNAVAILABLE);
+                                        OUT_LOG | OUT_STDOUT | EX_NOPERM);
             }
         }
 
@@ -215,7 +210,7 @@
             $msg = $php_errormsg;
             return PEAR::raiseError(sprintf(_("Error: Could not open %s for writing: %s"),
                                             $this->_tmpfile, $msg),
-                                    OUT_LOG | ERR_TEMPFAIL);
+                                    OUT_LOG | EX_IOERR);
         }
 
         $result = $transport->start($this->_sender, $this->_recipients);
@@ -324,7 +319,7 @@
     if (!ldap_bind($ldap, $conf['filter']['bind_dn'], $conf['filter']['bind_pw'])) {
         return PEAR::raiseError(sprintf(_("Unable to contact LDAP server: %s"),
                                         ldap_error($ldap)),
-                                OUT_LOG | ERR_TEMPFAIL);
+                                OUT_LOG | EX_TEMPFAIL);
     }
   
     $filter = "(&(objectClass=kolabInetOrgPerson)(|(mail=$sasluser)(uid=$sasluser)))";
@@ -334,14 +329,14 @@
     if (!$result) {
         return PEAR::raiseError(sprintf(_("Unable to perform LDAP search: %s"),
                                         ldap_error($ldap)),
-                                OUT_LOG | ERR_TEMPFAIL);
+                                OUT_LOG | EX_TEMPFAIL);
     }
   
     $entries = ldap_get_entries($ldap, $result);
     if ($entries['count'] != 1) {
         return PEAR::raiseError(sprintf(_("%s objects returned for uid %s. Unable to look up user."),
                                         $entries['count'], $sasluser),
-                                OUT_LOG | ERR_TEMPFAIL);
+                                OUT_LOG | EX_TEMPFAIL);
     }
     unset($entries[0]['mail']['count']);
     unset($entries[0]['alias']['count']);
@@ -357,7 +352,7 @@
     if (!$result) {
         return PEAR::raiseError(sprintf(_("Unable to perform LDAP search: %s"),
                                         ldap_error($ldap)),
-                                OUT_LOG | ERR_TEMPFAIL);
+                                OUT_LOG | EX_TEMPFAIL);
     }
   
     $entries = ldap_get_entries($ldap, $result);

Index: Outlook.php
===================================================================
RCS file: /kolabrepository/server/php-kolab/Kolab_Filter/Filter/Outlook.php,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Outlook.php	27 Nov 2007 10:01:52 -0000	1.2
+++ Outlook.php	27 Nov 2007 12:35:23 -0000	1.3
@@ -160,7 +160,7 @@
         $msg = $php_errormsg;
         return PEAR::raiseError(sprintf(_("Error: Could not open %s for writing: %s"),
                                         $tmpfname, $msg),
-                                OUT_LOG | ERR_TEMPFAIL);
+                                OUT_LOG | EX_TEMPFAIL);
     }
     while (!feof($handle)) {
         $requestText .= fread($handle, 8192);
@@ -223,7 +223,7 @@
     if (is_a($result, 'PEAR_Error')) {
         $append = sprintf(_(", original code %s"), $result->getCode());
         $result->message = $result->getMessage() . $append;
-        $result->code = OUT_LOG | OUT_STDOUT | ERR_TEMPFAIL;
+        $result->code = OUT_LOG | OUT_STDOUT | EX_TEMPFAIL;
         return $result;
     }
 





More information about the commits mailing list