gunnar: server/php-kolab/Kolab_Storage/patches/Kolab_Storage-0.5.0 issue3416.patch, NONE, 1.1 t_framework_HK_GW_ZpushAnnotations.diff, NONE, 1.1 t_framework_HK_UV_NoDuplicationOnUidChange.diff, NONE, 1.1 t_kronolith_HK_GW_ExportEventList.patch, NONE, 1.1

cvs at kolab.org cvs at kolab.org
Tue Jun 22 11:46:00 CEST 2010


Author: gunnar

Update of /kolabrepository/server/php-kolab/Kolab_Storage/patches/Kolab_Storage-0.5.0
In directory doto:/tmp/cvs-serv29694/patches/Kolab_Storage-0.5.0

Added Files:
	issue3416.patch t_framework_HK_GW_ZpushAnnotations.diff 
	t_framework_HK_UV_NoDuplicationOnUidChange.diff 
	t_kronolith_HK_GW_ExportEventList.patch 
Log Message:
Update to upstream release Kolab_Storage-0.5.0 which includes some of the Kolab patches.

--- NEW FILE: issue3416.patch ---
From: Gunnar Wrobel <wrobel at pardus.de>
Subject: [PATCH] issue3416.patch

Do not block when free/busy is not available.

STATUS: UNMERGED

REF: http://issues.kolab.org/issue3416

Signed-off-by: Gunnar Wrobel <wrobel at pardus.de>

--- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php	2010-04-28 17:18:16.000000000 +0200
+++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php	2010-04-28 18:05:34.684348740 +0200
@@ -31,6 +31,8 @@
 require_once 'Horde/String.php';
 require_once 'Horde/NLS.php';
 
+require_once 'HTTP/Request.php';
+
 /**
  * The root of the Kolab annotation hierarchy, used on the various IMAP folder
  * that are used by Kolab clients.
@@ -1256,14 +1258,15 @@
 
         $options['method'] = 'GET';
         $options['timeout'] = 5;
+        $options['readTimeout'] = array(5, 1000);
+        $options['socketOptions']['http']['timeout'] = 5.0;
         $options['allowRedirects'] = true;
 
         if (isset($conf['http']['proxy']) && !empty($conf['http']['proxy']['proxy_host'])) {
             $options = array_merge($options, $conf['http']['proxy']);
         }
 
-        require_once 'HTTP/Request.php';
-        $http = new HTTP_Request($url, $options);
+        $http = new HTTP_Request_NonBlocking($url, $options);
         $http->setBasicAuth(Auth::getAuth(), Auth::getCredential('password'));
         @$http->sendRequest();
         if ($http->getResponseCode() != 200) {
@@ -1643,3 +1646,157 @@
                                      $value);
     }
 }
+
+class HTTP_Request_NonBlocking extends HTTP_Request
+{
+    /**
+    * Sends the request
+    *
+    * @access public
+    * @param  bool   Whether to store response body in Response object property,
+    *                set this to false if downloading a LARGE file and using a Listener
+    * @return mixed  PEAR error on error, true otherwise
+    */
+    function sendRequest($saveBody = true)
+    {
+        if (!is_a($this->_url, 'Net_URL')) {
+            return PEAR::raiseError('No URL given', HTTP_REQUEST_ERROR_URL);
+        }
+
+        $host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host;
+        $port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port;
+
+        if (strcasecmp($this->_url->protocol, 'https') == 0) {
+            // Bug #14127, don't try connecting to HTTPS sites without OpenSSL
+            if (version_compare(PHP_VERSION, '4.3.0', '<') || !extension_loaded('openssl')) {
+                return PEAR::raiseError('Need PHP 4.3.0 or later with OpenSSL support for https:// requests',
+                                        HTTP_REQUEST_ERROR_URL);
+            } elseif (isset($this->_proxy_host)) {
+                return PEAR::raiseError('HTTPS proxies are not supported', HTTP_REQUEST_ERROR_PROXY);
+            }
+            $host = 'ssl://' . $host;
+        }
+
+        // magic quotes may fuck up file uploads and chunked response processing
+        $magicQuotes = ini_get('magic_quotes_runtime');
+        ini_set('magic_quotes_runtime', false);
+
+        // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+        // connection token to a proxy server...
+        if (isset($this->_proxy_host) && !empty($this->_requestHeaders['connection']) &&
+            'Keep-Alive' == $this->_requestHeaders['connection'])
+        {
+            $this->removeHeader('connection');
+        }
+
+        $keepAlive = (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && empty($this->_requestHeaders['connection'])) ||
+                     (!empty($this->_requestHeaders['connection']) && 'Keep-Alive' == $this->_requestHeaders['connection']);
+        $sockets   = &PEAR::getStaticProperty('HTTP_Request', 'sockets');
+        $sockKey   = $host . ':' . $port;
+        unset($this->_sock);
+
+        // There is a connected socket in the "static" property?
+        if ($keepAlive && !empty($sockets[$sockKey]) &&
+            !empty($sockets[$sockKey]->fp))
+        {
+            $this->_sock =& $sockets[$sockKey];
+            $err = null;
+        } else {
+            $this->_notify('connect');
+            $this->_sock =& new Net_Socket();
+            $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions);
+            $this->_sock->setBlocking(false);
+        }
+        PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest());
+
+if (!PEAR::isError($err)) {
+            if (!empty($this->_readTimeout)) {
+                $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]);
+            }
+
+            $this->_notify('sentRequest');
+
+            // Read the response
+            $this->_response = &new HTTP_Response($this->_sock, $this->_listeners);
+            $err = $this->_response->process(
+                $this->_saveBody && $saveBody,
+                HTTP_REQUEST_METHOD_HEAD != $this->_method
+            );
+
+            if ($keepAlive) {
+                $keepAlive = (isset($this->_response->_headers['content-length'])
+                              || (isset($this->_response->_headers['transfer-encoding'])
+                                  && strtolower($this->_response->_headers['transfer-encoding']) == 'chunked'));
+                if ($keepAlive) {
+                    if (isset($this->_response->_headers['connection'])) {
+                        $keepAlive = strtolower($this->_response->_headers['connection']) == 'keep-alive';
+                    } else {
+                        $keepAlive = 'HTTP/'.HTTP_REQUEST_HTTP_VER_1_1 == $this->_response->_protocol;
+                    }
+                }
+            }
+        }
+
+        ini_set('magic_quotes_runtime', $magicQuotes);
+
+        if (PEAR::isError($err)) {
+            return $err;
+        }
+
+        if (!$keepAlive) {
+            $this->disconnect();
+        // Store the connected socket in "static" property
+        } elseif (empty($sockets[$sockKey]) || empty($sockets[$sockKey]->fp)) {
+            $sockets[$sockKey] =& $this->_sock;
+        }
+
+        // Check for redirection
+        if (    $this->_allowRedirects
+            AND $this->_redirects <= $this->_maxRedirects
+            AND $this->getResponseCode() > 300
+            AND $this->getResponseCode() < 399
+            AND !empty($this->_response->_headers['location'])) {
+
+
+            $redirect = $this->_response->_headers['location'];
+
+            // Absolute URL
+            if (preg_match('/^https?:\/\//i', $redirect)) {
+                $this->_url = &new Net_URL($redirect);
+                $this->addHeader('Host', $this->_generateHostHeader());
+            // Absolute path
+            } elseif ($redirect{0} == '/') {
+                $this->_url->path = $redirect;
+
+            // Relative path
+            } elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') {
+                if (substr($this->_url->path, -1) == '/') {
+                    $redirect = $this->_url->path . $redirect;
+                } else {
+                    $redirect = dirname($this->_url->path) . '/' . $redirect;
+                }
+                $redirect = Net_URL::resolvePath($redirect);
+                $this->_url->path = $redirect;
+
+            // Filename, no path
+            } else {
+                if (substr($this->_url->path, -1) == '/') {
+                    $redirect = $this->_url->path . $redirect;
+                } else {
+                    $redirect = dirname($this->_url->path) . '/' . $redirect;
+                }
+                $this->_url->path = $redirect;
+            }
+
+            $this->_redirects++;
+            return $this->sendRequest($saveBody);
+
+        // Too many redirects
+        } elseif ($this->_allowRedirects AND $this->_redirects > $this->_maxRedirects) {
+            return PEAR::raiseError('Too many redirects', HTTP_REQUEST_ERROR_REDIRECTS);
+        }
+
+        return true;
+    }
+
+}

--- NEW FILE: t_framework_HK_GW_ZpushAnnotations.diff ---
diff -Naur a/framework/Kolab_Storage/lib/Horde/Kolab/Storage.orig/Folder.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php
--- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php	2010-05-04 23:44:49.522328256 +0200
+++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php	2010-05-06 07:46:01.507036608 +0200
@@ -390,7 +390,7 @@
 
         /** Handle the folder type */
         $folder_type = $this->_type . ($this->_default ? '.default' : '');
-        if ($this->_type_annotation != $folder_type) {
+        if ($this->_owner == Auth::getAuth() && $this->_type_annotation != $folder_type) {
             $result = $this->_setAnnotation(KOLAB_ANNOT_FOLDER_TYPE, $folder_type);
             if (is_a($result, 'PEAR_Error')) {
                 $this->_type = null;
@@ -412,19 +412,38 @@
                         if (is_a($result, 'PEAR_Error')) {
                             return $result;
                         }
+                        unset($params['xfbaccess']);
                     }
                     if (isset($params['fbrelevance'])) {
                         $result = $this->setFbrelevance($params['fbrelevance']);
                         if (is_a($result, 'PEAR_Error')) {
                             return $result;
                         }
+                        unset($params['fbrelevance']);
                     }
+                    if (isset($params['activesync'])) {
+                        $result = $this->setActiveSyncDeviceData($params['activesync'], 'FOLDER');
+                        if (is_a($result, 'PEAR_Error')) {
+                            return $result;
+                        }
+                        unset($params['activesync']);
+                    }
+                    if (empty($params)) {
+                        continue;
+                    }
+                    $value = serialize($params);
                 }
 
                 // setAnnotation apparently does not suppoort UTF-8 nor any special characters
                 $store = base64_encode($value);
                 if ($key == 'desc') {
-                    $entry = '/comment';
+                    if ($this->_owner == Auth::getAuth()) {
+                        $entry = '/comment';
+                    } else {
+                        continue;
+                    }
+                } else if ($key == 'params' && $this->_owner != Auth::getAuth()) {
+                    continue;
                 } else {
                     $entry = HORDE_ANNOT_SHARE_ATTR . $key;
                 }
@@ -447,7 +450,7 @@
         }
 
         /** Now save the folder permissions */
-        if (isset($this->_perms)) {
+        if ($this->_owner == Auth::getAuth() && isset($this->_perms)) {
             $result = $this->_perms->save();
             if (is_a($result, 'PEAR_Error')) {
                 return $result;
@@ -1645,6 +1655,132 @@
         return $this->_setAnnotation(KOLAB_ANNOT_ROOT . 'pxfb-readable-for',
                                      $value);
     }
+
+    /**
+     * Get the active sync settings for this folder.
+     *
+     * @return array  Array containing the active sync information.
+     */
+    function getActiveSync()
+    {
+        $imap = Horde_Kolab_Session::singleton()->getImap();
+        if (is_a($imap, 'PEAR_Error')) {
+            return $imap;
+        }
+        $raw = $imap->getAnnotation(
+            KOLAB_ANNOT_ROOT . 'activesync', 'value.priv', $this->name
+        );
+        $local = json_decode(base64_decode($raw), true);
+        if (!$this->name != 'INBOX') {
+            $raw = $imap->getAnnotation(
+                KOLAB_ANNOT_ROOT . 'activesync', 'value.priv', 'INBOX'
+            );
+            $global = json_decode(base64_decode($raw), true);
+            if (!is_array($local)) {
+                $result = array(
+                    'DEVICE' => isset($global['DEVICE']) ? $global['DEVICE'] : array(),
+                    'FOLDER' => array()
+                );
+            } elseif (is_array($global)) {
+                $result = array(
+                    'DEVICE' => isset($global['DEVICE']) ? $global['DEVICE'] : array(),
+                    'FOLDER' => isset($local['FOLDER']) ? $local['FOLDER'] : array(),
+                );
+            } else {
+                $result = array(
+                    'DEVICE' => array(),
+                    'FOLDER' => isset($local['FOLDER']) ? $local['FOLDER'] : array(),
+                );
+            }
+        } else {
+            $result = array(
+                'DEVICE' => isset($global['DEVICE']) ? $global['DEVICE'] : array(),
+                'FOLDER' => array()
+            );
+        }
+        $result['NAMESPACE'] = $this->_list->namespace->matchNamespace($this->name)->getType();
+        return $result;
+    }
+
+    /**
+     * Delete an active sync device for this folder.
+     *
+     * @param string $id The id of the device.
+     *
+     * @return mixed  True on success or a PEAR_Error.
+     */
+    function deleteActiveSyncDevice($id)
+    {
+        $imap = Horde_Kolab_Session::singleton()->getImap();
+        if (is_a($imap, 'PEAR_Error')) {
+            return $imap;
+        }
+        $raw = $imap->getAnnotation(
+            KOLAB_ANNOT_ROOT . 'activesync', 'value.priv', $this->name
+        );
+        $result = json_decode(base64_decode($raw), true);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        if (!is_array($result)) {
+            return true;
+        }
+        unset($result['DEVICE'][$id]);
+        $result = $imap->setAnnotation(
+            KOLAB_ANNOT_ROOT . 'activesync',
+            array('value.priv' => base64_encode(json_encode($result))),
+            $this->name
+        );
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        return true;
+    }
+
+    /**
+     * Set the active sync annotation.
+     *
+     * @param string $data  The data to store in the annotation.
+     * @param string $type  The type of the data (DEVICE|FOLDER).
+     *
+     * @return mixed  True on success or a PEAR_Error.
+     */
+    function setActiveSyncDeviceData($data, $type = 'DEVICE')
+    {
+        $imap = Horde_Kolab_Session::singleton()->getImap();
+        if (is_a($imap, 'PEAR_Error')) {
+            return $imap;
+        }
+        $raw = $imap->getAnnotation(
+            KOLAB_ANNOT_ROOT . 'activesync', 'value.priv', $this->name
+        );
+        $old = json_decode(base64_decode($raw), true);
+        if (is_a($old, 'PEAR_Error')) {
+            return $data;
+        }
+        if (!is_array($old)) {
+            $old = array();
+        }
+
+        $new_type = isset($old[$type]) ? $old[$type] : array();
+        $data_type = isset($data[$type]) ? $data[$type] : array();
+        foreach ($data_type as $id => $settings) {
+            foreach ($settings as $key => $value) {
+                $new_type[$id][$key] = $value;
+            }
+        }
+        $new = array($type => $new_type);
+        $result = $imap->setAnnotation(
+            KOLAB_ANNOT_ROOT . 'activesync',
+            array('value.priv' => base64_encode(json_encode($new))),
+            $this->name
+        );
+
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        return true;
+    }
 }
 
 class HTTP_Request_NonBlocking extends HTTP_Request

--- NEW FILE: t_framework_HK_UV_NoDuplicationOnUidChange.diff ---
From: root <Gunnar Wrobel wrobel at pardus.de>
Subject: [PATCH] t/SyncML/HK/GW/DoubleSyncFix

When the uid validity of an IMAP folder changes this confuses the Kolab storage
driver and leads to double entries. The attached patch has been proposed by
Univention and should be applied after some cleanup.

REF: https://issues.kolab.org/issue3238

Signed-off-by: root <Gunnar Wrobel wrobel at pardus.de>

--- a/a/a/lib/Horde/Kolab/Storage/Data.php	2008-10-20 16:27:27.000000000 +0200
+++ a/a/a/lib/Horde/Kolab/Storage/Data.php	2008-10-20 16:38:34.000000000 +0200
@@ -457,6 +457,14 @@ class Kolab_Data {
         $history = &Horde_History::singleton();
 
         $history_id = $app . ':' . $this->_folder->getShareId() . ':' . $object_uid;
+
+        // entries that should be added to the history MUST not
+        // have an existing entry in the history!! otherwise
+        // they are just marked as "modified"
+        if ($action == 'add' && $history->getActionTimestamp($history_id, 'add') == 0) {
+            $action = 'modify';
+        }
+
         $history->log($history_id, array('action' => $action, 'ts' => $mod_ts), true);
     }
 

--- NEW FILE: t_kronolith_HK_GW_ExportEventList.patch ---
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
index a9bff36..a31ef82 100644
--- a/a/a/lib/Horde/Kolab/Storage/List.php
+++ b/a/a/lib/Horde/Kolab/Storage/List.php
@@ -136,7 +136,7 @@ class Kolab_List {
      */
     function &listFolders()
     {
-        if (!isset($this->_list)) {
+        if (!isset($this->_list) || is_a($this->_list, 'PEAR_Error')) {
             $session = &Horde_Kolab_Session::singleton();
             $imap = &$session->getImap();
             if (is_a($imap, 'PEAR_Error')) {





More information about the commits mailing list