[Pkg-owncloud-commits] [owncloud-client] 23/332: CSync: Use context instead of global variable

Sandro Knauß hefee-guest at moszumanska.debian.org
Thu Aug 14 21:06:33 UTC 2014


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit 8a55f831f478e8bff2ae23af69cf5fce19963d8b
Author: Markus Goetz <markus at woboq.com>
Date:   Thu May 29 12:02:46 2014 +0200

    CSync: Use context instead of global variable
---
 csync/src/csync.c                                  |   4 +-
 csync/src/csync_owncloud.c                         | 324 +++++++++------------
 csync/src/csync_owncloud.h                         | 160 +---------
 .../{csync_owncloud.h => csync_owncloud_private.h} | 133 +++++----
 csync/src/csync_owncloud_recursive_propfind.c      |  75 +++--
 csync/src/csync_owncloud_util.c                    |  47 ++-
 csync/src/csync_private.h                          |   4 +
 csync/src/vio/csync_vio.c                          |  12 +-
 8 files changed, 310 insertions(+), 449 deletions(-)

diff --git a/csync/src/csync.c b/csync/src/csync.c
index 065d4e1..f20064f 100644
--- a/csync/src/csync.c
+++ b/csync/src/csync.c
@@ -191,7 +191,7 @@ int csync_init(CSYNC *ctx) {
   ctx->local.type = LOCAL_REPLICA;
 
   if ( !ctx->options.local_only_mode) {
-      owncloud_init(csync_get_userdata(ctx));
+      owncloud_init(ctx);
       ctx->remote.type = REMOTE_REPLICA;
   } else {
     ctx->remote.type = LOCAL_REPLICA;
@@ -679,6 +679,8 @@ int csync_destroy(CSYNC *ctx) {
   SAFE_FREE(ctx->options.config_dir);
   SAFE_FREE(ctx->error_string);
 
+  owncloud_destroy(ctx);
+
 #ifdef WITH_ICONV
   c_close_iconv();
 #endif
diff --git a/csync/src/csync_owncloud.c b/csync/src/csync_owncloud.c
index 23be021..bed68da 100644
--- a/csync/src/csync_owncloud.c
+++ b/csync/src/csync_owncloud.c
@@ -20,60 +20,10 @@
  */
 
 #include "csync_owncloud.h"
+#include "csync_owncloud_private.h"
 
 #include <inttypes.h>
 
-/*
- * free the fetchCtx
- */
-static void free_fetchCtx( struct listdir_context *ctx )
-{
-    struct resource *newres, *res;
-    if( ! ctx ) return;
-    newres = ctx->list;
-    res = newres;
-
-    ctx->ref--;
-    if (ctx->ref > 0) return;
-
-    SAFE_FREE(ctx->target);
-
-    while( res ) {
-        SAFE_FREE(res->uri);
-        SAFE_FREE(res->name);
-        SAFE_FREE(res->md5);
-        memset( res->file_id, 0, FILE_ID_BUF_SIZE+1 );
-
-        newres = res->next;
-        SAFE_FREE(res);
-        res = newres;
-    }
-    SAFE_FREE(ctx);
-}
-
-
-/*
- * local variables.
- */
-
-struct dav_session_s dav_session; /* The DAV Session, initialised in dav_connect */
-int _connected = 0;                   /* flag to indicate if a connection exists, ie.
-                                     the dav_session is valid */
-
-
-void *_userdata;
-
-struct listdir_context *propfind_cache = 0;
-
-bool is_first_propfind = true;
-
-static void clean_caches() {
-    clear_propfind_recursive_cache();
-
-    free_fetchCtx(propfind_cache);
-    propfind_cache = NULL;
-}
-
 
 /*
  * helper method to build up a user text for SSL problems, called from the
@@ -105,8 +55,8 @@ static int verify_sslcert(void *userdata, int failures,
     int ret = -1;
     const ne_ssl_certificate *cert = certificate;
     csync_auth_callback authcb = NULL;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
 
-    (void) userdata;
     memset( problem, 0, LEN );
 
     while( cert ) {
@@ -142,14 +92,14 @@ static int verify_sslcert(void *userdata, int failures,
     }
     addSSLWarning( problem, "Do you want to accept the certificate chain anyway?\nAnswer yes to do so and take the risk: ", LEN );
 
-    if( dav_session.csync_ctx ) {
-        authcb = csync_get_auth_callback( dav_session.csync_ctx );
+    if( ctx->csync_ctx ) {
+        authcb = csync_get_auth_callback( ctx->csync_ctx );
     }
     if( authcb ){
         /* call the csync callback */
         DEBUG_WEBDAV("Call the csync callback for SSL problems");
         memset( buf, 0, NE_ABUFSIZ );
-        (*authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, _userdata );
+        (*authcb) ( problem, buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) );
         if( buf[0] == 'y' || buf[0] == 'Y') {
             ret = 0;
         } else {
@@ -171,35 +121,35 @@ static int ne_auth( void *userdata, const char *realm, int attempt,
     char buf[NE_ABUFSIZ];
     csync_auth_callback authcb = NULL;
     int re = attempt;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
 
-    (void) userdata;
     (void) realm;
 
     /* DEBUG_WEBDAV( "Authentication required %s", realm ); */
     if( username && password ) {
         DEBUG_WEBDAV( "Authentication required %s", username );
-        if( dav_session.user ) {
+        if( ctx->dav_session.user ) {
             /* allow user without password */
-            if( strlen( dav_session.user ) < NE_ABUFSIZ ) {
-                strcpy( username, dav_session.user );
+            if( strlen( ctx->dav_session.user ) < NE_ABUFSIZ ) {
+                strcpy( username, ctx->dav_session.user );
             }
-            if( dav_session.pwd && strlen( dav_session.pwd ) < NE_ABUFSIZ ) {
-                strcpy( password, dav_session.pwd );
+            if( ctx->dav_session.pwd && strlen( ctx->dav_session.pwd ) < NE_ABUFSIZ ) {
+                strcpy( password, ctx->dav_session.pwd );
             }
         } else {
-            if( dav_session.csync_ctx ) {
-               authcb = csync_get_auth_callback( dav_session.csync_ctx );
+            if( ctx->dav_session.csync_ctx ) {
+               authcb = csync_get_auth_callback( ctx->dav_session.csync_ctx );
             }
             if( authcb != NULL ){
                 /* call the csync callback */
                 DEBUG_WEBDAV("Call the csync callback for %s", realm );
                 memset( buf, 0, NE_ABUFSIZ );
-                (*authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, _userdata );
+                (*authcb) ("Enter your username: ", buf, NE_ABUFSIZ-1, 1, 0, csync_get_userdata(ctx->csync_ctx) );
                 if( strlen(buf) < NE_ABUFSIZ ) {
                     strcpy( username, buf );
                 }
                 memset( buf, 0, NE_ABUFSIZ );
-                (*authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, _userdata );
+                (*authcb) ("Enter your password: ", buf, NE_ABUFSIZ-1, 0, 0, csync_get_userdata(ctx->csync_ctx) );
                 if( strlen(buf) < NE_ABUFSIZ) {
                     strcpy( password, buf );
                 }
@@ -219,12 +169,12 @@ static int ne_auth( void *userdata, const char *realm, int attempt,
 static int ne_proxy_auth( void *userdata, const char *realm, int attempt,
                           char *username, char *password)
 {
-    (void) userdata;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
     (void) realm;
-    if( dav_session.proxy_user && strlen( dav_session.proxy_user ) < NE_ABUFSIZ) {
-        strcpy( username, dav_session.proxy_user );
-        if( dav_session.proxy_pwd && strlen( dav_session.proxy_pwd ) < NE_ABUFSIZ) {
-            strcpy( password, dav_session.proxy_pwd );
+    if( ctx->dav_session.proxy_user && strlen( ctx->dav_session.proxy_user ) < NE_ABUFSIZ) {
+        strcpy( username, ctx->dav_session.proxy_user );
+        if( ctx->dav_session.proxy_pwd && strlen( ctx->dav_session.proxy_pwd ) < NE_ABUFSIZ) {
+            strcpy( password, ctx->dav_session.proxy_pwd );
         }
     }
     /* NTLM needs several attempts */
@@ -232,42 +182,42 @@ static int ne_proxy_auth( void *userdata, const char *realm, int attempt,
 }
 
 /* Configure the proxy depending on the variables */
-static int configureProxy( ne_session *session )
+static int configureProxy( csync_owncloud_ctx_t *ctx, ne_session *session )
 {
     int port = 8080;
     int re = -1;
 
     if( ! session ) return -1;
-    if( ! dav_session.proxy_type ) return 0; /* Go by NoProxy per default */
+    if( ! ctx->dav_session.proxy_type ) return 0; /* Go by NoProxy per default */
 
-    if( dav_session.proxy_port > 0 ) {
-        port = dav_session.proxy_port;
+    if( ctx->dav_session.proxy_port > 0 ) {
+        port = ctx->dav_session.proxy_port;
     }
 
-    if( c_streq(dav_session.proxy_type, "NoProxy" )) {
+    if( c_streq(ctx->dav_session.proxy_type, "NoProxy" )) {
         DEBUG_WEBDAV("No proxy configured.");
         re = 0;
-    } else if( c_streq(dav_session.proxy_type, "DefaultProxy") ||
-               c_streq(dav_session.proxy_type, "HttpProxy")    ||
-               c_streq(dav_session.proxy_type, "HttpCachingProxy") ||
-               c_streq(dav_session.proxy_type, "Socks5Proxy")) {
-
-        if( dav_session.proxy_host ) {
-            DEBUG_WEBDAV("%s at %s:%d", dav_session.proxy_type, dav_session.proxy_host, port );
-            if (c_streq(dav_session.proxy_type, "Socks5Proxy")) {
-                ne_session_socks_proxy(session, NE_SOCK_SOCKSV5, dav_session.proxy_host, port,
-                                       dav_session.proxy_user, dav_session.proxy_pwd);
+    } else if( c_streq(ctx->dav_session.proxy_type, "DefaultProxy") ||
+               c_streq(ctx->dav_session.proxy_type, "HttpProxy")    ||
+               c_streq(ctx->dav_session.proxy_type, "HttpCachingProxy") ||
+               c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) {
+
+        if( ctx->dav_session.proxy_host ) {
+            DEBUG_WEBDAV("%s at %s:%d", ctx->dav_session.proxy_type, ctx->dav_session.proxy_host, port );
+            if (c_streq(ctx->dav_session.proxy_type, "Socks5Proxy")) {
+                ne_session_socks_proxy(session, NE_SOCK_SOCKSV5, ctx->dav_session.proxy_host, port,
+                                       ctx->dav_session.proxy_user, ctx->dav_session.proxy_pwd);
             } else {
-                ne_session_proxy(session, dav_session.proxy_host, port );
+                ne_session_proxy(session, ctx->dav_session.proxy_host, port );
             }
             re = 2;
         } else {
-            DEBUG_WEBDAV("%s requested but no proxy host defined.", dav_session.proxy_type );
+            DEBUG_WEBDAV("%s requested but no proxy host defined.", ctx->dav_session.proxy_type );
 	    /* we used to try ne_system_session_proxy here, but we should rather err out
 	       to behave exactly like the caller. */
         }
     } else {
-        DEBUG_WEBDAV( "Unsupported Proxy: %s", dav_session.proxy_type );
+        DEBUG_WEBDAV( "Unsupported Proxy: %s", ctx->dav_session.proxy_type );
     }
 
     return re;
@@ -284,9 +234,9 @@ static void post_request_hook(ne_request *req, void *userdata, const ne_status *
     const char *sc  = NULL;
     char *key = NULL;
 
-    (void) userdata;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
 
-    if (dav_session.session_key)
+    if (ctx->dav_session.session_key)
         return; /* We already have a session cookie, and we should ignore other ones */
 
     if(!(status && req)) return;
@@ -354,8 +304,8 @@ static void post_request_hook(ne_request *req, void *userdata, const ne_status *
     }
     if( key ) {
         DEBUG_WEBDAV("----> Session-key: %s", key);
-        SAFE_FREE(dav_session.session_key);
-        dav_session.session_key = key;
+        SAFE_FREE(ctx->dav_session.session_key);
+        ctx->dav_session.session_key = key;
     }
 }
 
@@ -366,13 +316,14 @@ static void post_request_hook(ne_request *req, void *userdata, const ne_status *
 static void request_created_hook(ne_request *req, void *userdata,
                                  const char *method, const char *requri)
 {
-    (void) userdata;
+    // FIXME Can possibly be merged with pre_send_hook
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
     (void) method;
     (void) requri;
 
     if( !req ) return;
 
-    if(dav_session.proxy_type) {
+    if(ctx->dav_session.proxy_type) {
         /* required for NTLM */
         ne_add_request_header(req, "Proxy-Connection", "Keep-Alive");
     }
@@ -385,12 +336,12 @@ static void request_created_hook(ne_request *req, void *userdata,
 static void pre_send_hook(ne_request *req, void *userdata,
                           ne_buffer *header)
 {
-    (void) userdata;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
 
     if( !req ) return;
 
-    if(dav_session.session_key) {
-        ne_buffer_concat(header, "Cookie: ", dav_session.session_key, "\r\n", NULL);
+    if(ctx->dav_session.session_key) {
+        ne_buffer_concat(header, "Cookie: ", ctx->dav_session.session_key, "\r\n", NULL);
     } else {
         DEBUG_WEBDAV("csync pre_send_hook We don't have a Auth Cookie (session_key), this is wrong!");
     }
@@ -400,16 +351,15 @@ static int post_send_hook(ne_request *req, void *userdata,
                           const ne_status *status)
 {
     const char *location;
-
-    (void) userdata;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t *) userdata;
     (void) status;
 
     location = ne_get_response_header(req, "Location");
 
     if( !location ) return NE_OK;
 
-    if( dav_session.redir_callback ) {
-        if( dav_session.redir_callback( dav_session.csync_ctx, location ) ) {
+    if( ctx->dav_session.redir_callback ) {
+        if( ctx->dav_session.redir_callback( ctx->dav_session.csync_ctx, location ) ) {
             return NE_REDIRECT;
         } else {
             return NE_RETRY;
@@ -449,7 +399,7 @@ static const char* get_platform() {
  * This function sets the flag _connected if the connection is established
  * and returns if the flag is set, so calling it frequently is save.
  */
-static int dav_connect(const char *base_url) {
+static int dav_connect(csync_owncloud_ctx_t *ctx,  const char *base_url) {
     int useSSL = 0;
     int rc;
     char protocol[6] = {'\0'};
@@ -460,11 +410,14 @@ static int dav_connect(const char *base_url) {
     unsigned int port = 0;
     int proxystate = -1;
 
-    if (_connected) {
+    if (ctx->_connected) {
         return 0;
     }
 
-    rc = c_parse_uri( base_url, &scheme, &dav_session.user, &dav_session.pwd, &host, &port, &path );
+    rc = c_parse_uri( base_url, &scheme,
+                      &ctx->dav_session.user,
+                      &ctx->dav_session.pwd,
+                      &host, &port, &path );
     if( rc < 0 ) {
         DEBUG_WEBDAV("Failed to parse uri %s", base_url );
         goto out;
@@ -486,29 +439,29 @@ static int dav_connect(const char *base_url) {
         goto out;
     }
 
-    DEBUG_WEBDAV("* user %s", dav_session.user ? dav_session.user : "");
+    DEBUG_WEBDAV("* user %s", ctx->dav_session.user ? ctx->dav_session.user : "");
 
     if (port == 0) {
         port = ne_uri_defaultport(protocol);
     }
 
-    dav_session.ctx = ne_session_create( protocol, host, port);
+    ctx->dav_session.ctx = ne_session_create( protocol, host, port);
 
-    if (dav_session.ctx == NULL) {
+    if (ctx->dav_session.ctx == NULL) {
         DEBUG_WEBDAV("Session create with protocol %s failed", protocol );
         rc = -1;
         goto out;
     }
 
-    if (dav_session.read_timeout != 0) {
-        ne_set_read_timeout(dav_session.ctx, dav_session.read_timeout);
-        DEBUG_WEBDAV("Timeout set to %u seconds", dav_session.read_timeout );
+    if (ctx->dav_session.read_timeout != 0) {
+        ne_set_read_timeout(ctx->dav_session.ctx, ctx->dav_session.read_timeout);
+        DEBUG_WEBDAV("Timeout set to %u seconds", ctx->dav_session.read_timeout );
     }
 
     snprintf( uaBuf, sizeof(uaBuf), "Mozilla/5.0 (%s) csyncoC/%s",
               get_platform(), CSYNC_STRINGIFY( LIBCSYNC_VERSION ));
-    ne_set_useragent( dav_session.ctx, uaBuf);
-    ne_set_server_auth(dav_session.ctx, ne_auth, 0 );
+    ne_set_useragent( ctx->dav_session.ctx, uaBuf);
+    ne_set_server_auth(ctx->dav_session.ctx, ne_auth, ctx);
 
     if( useSSL ) {
         if (!ne_has_support(NE_FEATURE_SSL)) {
@@ -517,28 +470,28 @@ static int dav_connect(const char *base_url) {
             goto out;
         }
 
-        ne_ssl_trust_default_ca( dav_session.ctx );
-        ne_ssl_set_verify( dav_session.ctx, verify_sslcert, 0 );
+        ne_ssl_trust_default_ca( ctx->dav_session.ctx );
+        ne_ssl_set_verify( ctx->dav_session.ctx, verify_sslcert, ctx);
     }
 
     /* Hook called when a request is created. It sets the proxy connection header. */
-    ne_hook_create_request( dav_session.ctx, request_created_hook, NULL );
+    ne_hook_create_request( ctx->dav_session.ctx, request_created_hook, ctx );
     /* Hook called after response headers are read. It gets the Session ID. */
-    ne_hook_post_headers( dav_session.ctx, post_request_hook, NULL );
+    ne_hook_post_headers( ctx->dav_session.ctx, post_request_hook, ctx );
     /* Hook called before a request is sent. It sets the cookies. */
-    ne_hook_pre_send( dav_session.ctx, pre_send_hook, NULL );
+    ne_hook_pre_send( ctx->dav_session.ctx, pre_send_hook, ctx );
     /* Hook called after request is dispatched. Used for handling possible redirections. */
-    ne_hook_post_send( dav_session.ctx, post_send_hook, NULL );
+    ne_hook_post_send( ctx->dav_session.ctx, post_send_hook, ctx );
 
     /* Proxy support */
-    proxystate = configureProxy( dav_session.ctx );
+    proxystate = configureProxy( ctx, ctx->dav_session.ctx );
     if( proxystate < 0 ) {
         DEBUG_WEBDAV("Error: Proxy-Configuration failed.");
     } else if( proxystate > 0 ) {
-        ne_set_proxy_auth( dav_session.ctx, ne_proxy_auth, 0 );
+        ne_set_proxy_auth( ctx->dav_session.ctx, ne_proxy_auth, 0 );
     }
 
-    _connected = 1;
+    ctx->_connected = 1;
     rc = 0;
 out:
     SAFE_FREE(path);
@@ -624,7 +577,7 @@ static void results(void *userdata,
 /*
  * fetches a resource list from the WebDAV server. This is equivalent to list dir.
  */
-static struct listdir_context *fetch_resource_list(const char *uri, int depth)
+static struct listdir_context *fetch_resource_list(csync_owncloud_ctx_t *ctx, const char *uri, int depth)
 {
     struct listdir_context *fetchCtx;
     int ret = 0;
@@ -638,12 +591,12 @@ static struct listdir_context *fetch_resource_list(const char *uri, int depth)
 
     /* The old legacy one-level PROPFIND cache. Also gets filled
        by the recursive cache if 'infinity' did not suceed. */
-    if (propfind_cache) {
-        if (c_streq(curi, propfind_cache->target)) {
+    if (ctx->propfind_cache) {
+        if (c_streq(curi, ctx->propfind_cache->target)) {
             DEBUG_WEBDAV("fetch_resource_list Using simple PROPFIND cache %s", curi);
-            propfind_cache->ref++;
+            ctx->propfind_cache->ref++;
             SAFE_FREE(curi);
-            return propfind_cache;
+            return ctx->propfind_cache;
         }
     }
 
@@ -659,7 +612,7 @@ static struct listdir_context *fetch_resource_list(const char *uri, int depth)
     fetchCtx->ref = 1;
 
     /* do a propfind request and parse the results in the results function, set as callback */
-    hdl = ne_propfind_create(dav_session.ctx, curi, depth);
+    hdl = ne_propfind_create(ctx->dav_session.ctx, curi, depth);
 
     if(hdl) {
         ret = ne_propfind_named(hdl, ls_props, results, fetchCtx);
@@ -675,14 +628,14 @@ static struct listdir_context *fetch_resource_list(const char *uri, int depth)
             DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code,
                          req_status->reason_phrase);
             ret = NE_CONNECT;
-            set_error_message(req_status->reason_phrase);
+            set_error_message(ctx, req_status->reason_phrase);
         }
         DEBUG_WEBDAV("Simple propfind result code %d.", req_status->code);
     } else {
         if( ret == NE_ERROR && req_status->code == 404) {
             errno = ENOENT;
         } else {
-            set_errno_from_neon_errcode(ret);
+            set_errno_from_neon_errcode(ctx, ret);
         }
     }
 
@@ -697,18 +650,18 @@ static struct listdir_context *fetch_resource_list(const char *uri, int depth)
             DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.",
                          content_type ?  content_type: "<empty>");
             errno = ERRNO_WRONG_CONTENT;
-            set_error_message("Server error: PROPFIND reply is not XML formatted!");
+            set_error_message(ctx, "Server error: PROPFIND reply is not XML formatted!");
             ret = NE_CONNECT;
         }
     }
 
     if( ret != NE_OK ) {
         const char *err = NULL;
-        set_errno_from_neon_errcode(ret);
+        set_errno_from_neon_errcode(ctx, ret);
 
-        err = ne_get_error( dav_session.ctx );
+        err = ne_get_error( ctx->dav_session.ctx );
         if(err) {
-            set_error_message(err);
+            set_error_message(ctx, err);
         }
         DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>");
     }
@@ -721,19 +674,19 @@ static struct listdir_context *fetch_resource_list(const char *uri, int depth)
         return NULL;
     }
 
-    free_fetchCtx(propfind_cache);
-    propfind_cache = fetchCtx;
-    propfind_cache->ref++;
+    free_fetchCtx(ctx->propfind_cache);
+    ctx->propfind_cache = fetchCtx;
+    ctx->propfind_cache->ref++;
     return fetchCtx;
 }
 
-static struct listdir_context *fetch_resource_list_attempts(const char *uri, int depth)
+static struct listdir_context *fetch_resource_list_attempts(csync_owncloud_ctx_t *ctx, const char *uri, int depth)
 {
     int i;
 
     struct listdir_context *fetchCtx = NULL;
     for(i = 0; i < 10; ++i) {
-        fetchCtx = fetch_resource_list(uri, depth);
+        fetchCtx = fetch_resource_list(ctx, uri, depth);
         if(fetchCtx) break;
         /* only loop in case the content is not XML formatted. Otherwise for every
          * non successful stat (for non existing directories) its tried 10 times. */
@@ -749,35 +702,35 @@ static struct listdir_context *fetch_resource_list_attempts(const char *uri, int
 /*
  * directory functions
  */
-csync_vio_handle_t *owncloud_opendir(const char *uri) {
+csync_vio_handle_t *owncloud_opendir(CSYNC *ctx, const char *uri) {
     struct listdir_context *fetchCtx = NULL;
     char *curi = NULL;
 
     DEBUG_WEBDAV("opendir method called on %s", uri );
 
-    if (dav_connect( uri ) < 0) {
+    if (dav_connect( ctx->owncloud_context, uri ) < 0) {
         DEBUG_WEBDAV("connection failed");
         return NULL;
     }
 
     curi = _cleanPath( uri );
-    if (is_first_propfind && !dav_session.no_recursive_propfind) {
-        is_first_propfind = false;
+    if (ctx->owncloud_context->is_first_propfind && !ctx->owncloud_context->dav_session.no_recursive_propfind) {
+        ctx->owncloud_context->is_first_propfind = false;
         // Try to fill it
-        fill_recursive_propfind_cache(uri, curi);
+        fill_recursive_propfind_cache(ctx->owncloud_context, uri, curi);
     }
-    if (propfind_recursive_cache) {
+    if (ctx->owncloud_context->propfind_recursive_cache) {
         // Try to fetch from recursive cache (if we have one)
-        fetchCtx = get_listdir_context_from_recursive_cache(curi);
+        fetchCtx = get_listdir_context_from_recursive_cache(ctx->owncloud_context, curi);
     }
     SAFE_FREE(curi);
-    is_first_propfind = false;
+    ctx->owncloud_context->is_first_propfind = false;
     if (fetchCtx) {
         return fetchCtx;
     }
 
     /* fetchCtx = fetch_resource_list( uri, NE_DEPTH_ONE ); */
-    fetchCtx = fetch_resource_list_attempts( uri, NE_DEPTH_ONE);
+    fetchCtx = fetch_resource_list_attempts( ctx->owncloud_context, uri, NE_DEPTH_ONE);
     if( !fetchCtx ) {
         /* errno is set properly in fetch_resource_list */
         DEBUG_WEBDAV("Errno set to %d", errno);
@@ -790,7 +743,8 @@ csync_vio_handle_t *owncloud_opendir(const char *uri) {
     /* no freeing of curi because its part of the fetchCtx and gets freed later */
 }
 
-int owncloud_closedir(csync_vio_handle_t *dhandle) {
+int owncloud_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
+    (void)ctx;
 
     struct listdir_context *fetchCtx = dhandle;
 
@@ -799,7 +753,8 @@ int owncloud_closedir(csync_vio_handle_t *dhandle) {
     return 0;
 }
 
-csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle) {
+csync_vio_file_stat_t *owncloud_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
+    (void)ctx;
     struct listdir_context *fetchCtx = dhandle;
 
 //    DEBUG_WEBDAV("owncloud_readdir" );
@@ -841,39 +796,51 @@ csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle) {
     return NULL;
 }
 
-char *owncloud_error_string(void)
+char *owncloud_error_string(CSYNC* ctx)
 {
-    return dav_session.error_string;
+    return ctx->owncloud_context->dav_session.error_string;
 }
 
-int owncloud_commit(void) {
+int owncloud_commit(CSYNC* ctx) {
+    clear_propfind_recursive_cache(ctx->owncloud_context);
+
+    free_fetchCtx(ctx->owncloud_context->propfind_cache);
+    ctx->owncloud_context->propfind_cache = NULL;
 
-  clean_caches();
+    if( ctx->owncloud_context->dav_session.ctx ) {
+        ne_forget_auth(ctx->owncloud_context->dav_session.ctx);
+        ne_session_destroy(ctx->owncloud_context->dav_session.ctx );
+        ctx->owncloud_context->dav_session.ctx = 0;
+    }
 
-  if( dav_session.ctx ) {
-      ne_forget_auth(dav_session.ctx);
-      ne_session_destroy( dav_session.ctx );
-  }
+    ctx->owncloud_context->is_first_propfind = true;
   /* DEBUG_WEBDAV( "********** vio_module_shutdown" ); */
 
-  dav_session.ctx = 0;
+  ctx->owncloud_context->dav_session.ctx = 0;
 
   // ne_sock_exit();
-  _connected = 0;  /* triggers dav_connect to go through the whole neon setup */
+  ctx->owncloud_context->_connected = 0;  /* triggers dav_connect to go through the whole neon setup */
 
-  SAFE_FREE( dav_session.user );
-  SAFE_FREE( dav_session.pwd );
-  SAFE_FREE( dav_session.session_key);
-  SAFE_FREE( dav_session.error_string );
+  SAFE_FREE( ctx->owncloud_context->dav_session.user );
+  SAFE_FREE( ctx->owncloud_context->dav_session.pwd );
+  SAFE_FREE( ctx->owncloud_context->dav_session.session_key);
+  SAFE_FREE( ctx->owncloud_context->dav_session.error_string );
 
   return 0;
 }
 
-int owncloud_set_property(const char *key, void *data) {
+void owncloud_destroy(CSYNC* ctx)
+{
+    owncloud_commit(ctx);
+    SAFE_FREE(ctx->owncloud_context);
+    ctx->owncloud_context = 0;
+}
+
+int owncloud_set_property(CSYNC* ctx, const char *key, void *data) {
 #define READ_STRING_PROPERTY(P) \
     if (c_streq(key, #P)) { \
-        SAFE_FREE(dav_session.P); \
-        dav_session.P = c_strdup((const char*)data); \
+        SAFE_FREE(ctx->owncloud_context->dav_session.P); \
+        ctx->owncloud_context->dav_session.P = c_strdup((const char*)data); \
         return 0; \
     }
     READ_STRING_PROPERTY(session_key)
@@ -884,48 +851,47 @@ int owncloud_set_property(const char *key, void *data) {
 #undef READ_STRING_PROPERTY
 
     if (c_streq(key, "proxy_port")) {
-        dav_session.proxy_port = *(int*)(data);
+        ctx->owncloud_context->dav_session.proxy_port = *(int*)(data);
         return 0;
     }
     if (c_streq(key, "read_timeout") || c_streq(key, "timeout")) {
-        dav_session.read_timeout = *(int*)(data);
+        ctx->owncloud_context->dav_session.read_timeout = *(int*)(data);
         return 0;
     }
     if( c_streq(key, "csync_context")) {
-        dav_session.csync_ctx = data;
+        ctx->owncloud_context->dav_session.csync_ctx = data;
         return 0;
     }
     if( c_streq(key, "get_dav_session")) {
         /* Give the ne_session to the caller */
-        *(ne_session**)data = dav_session.ctx;
+        *(ne_session**)data = ctx->owncloud_context->dav_session.ctx;
         return 0;
     }
     if( c_streq(key, "no_recursive_propfind")) {
-        dav_session.no_recursive_propfind = *(bool*)(data);
+        ctx->owncloud_context->dav_session.no_recursive_propfind = *(bool*)(data);
         return 0;
     }
     if( c_streq(key, "redirect_callback")) {
         if (data) {
             csync_owncloud_redirect_callback_t* cb_wrapper = data;
 
-            dav_session.redir_callback = *cb_wrapper;
+            ctx->owncloud_context->dav_session.redir_callback = *cb_wrapper;
         } else {
-            dav_session.redir_callback = NULL;
+            ctx->owncloud_context->dav_session.redir_callback = NULL;
         }
     }
 
     return -1;
 }
 
-void owncloud_init(void *userdata) {
-
-    _userdata = userdata;
-    _connected = 0;  /* triggers dav_connect to go through the whole neon setup */
+void owncloud_init(CSYNC* ctx) {
 
-    memset(&dav_session, 0, sizeof(dav_session));
+    ctx->owncloud_context = c_malloc( sizeof( struct csync_owncloud_ctx_s ));
+    ctx->owncloud_context->csync_ctx = ctx; // back reference
+    ctx->owncloud_context->is_first_propfind = true;
 
     /* Disable it, Mirall can enable it for the first sync (= no DB)*/
-    dav_session.no_recursive_propfind = true;
+    ctx->owncloud_context->dav_session.no_recursive_propfind = true;
 }
 
 /* vim: set ts=4 sw=4 et cindent: */
diff --git a/csync/src/csync_owncloud.h b/csync/src/csync_owncloud.h
index 152a2d9..8940ca8 100644
--- a/csync/src/csync_owncloud.h
+++ b/csync/src/csync_owncloud.h
@@ -21,160 +21,18 @@
 #ifndef CSYNC_OWNCLOUD_H
 #define CSYNC_OWNCLOUD_H
 
-#include <errno.h>
-#include <stdio.h>
-#include <time.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "config_csync.h"
-#ifdef NEON_WITH_LFS /* Switch on LFS in libneon. Never remove the NE_LFS! */
-#define NE_LFS
-#endif
-
-#include <neon/ne_basic.h>
-#include <neon/ne_socket.h>
-#include <neon/ne_session.h>
-#include <neon/ne_request.h>
-#include <neon/ne_props.h>
-#include <neon/ne_auth.h>
-#include <neon/ne_dates.h>
-#include <neon/ne_compress.h>
-#include <neon/ne_redirect.h>
-
-
-#include "c_rbtree.h"
-
-#include "c_lib.h"
 #include "csync.h"
-#include "csync_misc.h"
-#include "csync_macros.h"
-#include "c_private.h"
-#include "httpbf.h"
-
 #include "vio/csync_vio_file_stat.h"
 #include "vio/csync_vio.h"
 
-#include "csync_log.h"
-
-
-#define DEBUG_WEBDAV(...) csync_log( 9, "oc_module", __VA_ARGS__);
-
-enum resource_type {
-    resr_normal = 0,
-    resr_collection,
-    resr_reference,
-    resr_error
-};
-
-/* Struct to store data for each resource found during an opendir operation.
- * It represents a single file entry.
- */
-
-typedef struct resource {
-    char *uri;           /* The complete uri */
-    char *name;          /* The filename only */
-
-    enum resource_type type;
-    int64_t              size;
-    time_t             modtime;
-    char*              md5;
-    char               file_id[FILE_ID_BUF_SIZE+1];
-
-    struct resource    *next;
-} resource;
-
-/* Struct to hold the context of a WebDAV PropFind operation to fetch
- * a directory listing from the server.
- */
-struct listdir_context {
-    struct resource *list;           /* The list of result resources */
-    struct resource *currResource;   /* A pointer to the current resource */
-    char            *target;        /* Request-URI of the PROPFIND */
-    unsigned int     result_count;   /* number of elements stored in list */
-    int ref; /* reference count, only destroy when it reaches 0 */
-};
-
-
-/* Our cache, key is a char* */
-extern c_rbtree_t *propfind_recursive_cache;
-/* Values are propfind_recursive_element: */
-struct propfind_recursive_element {
-    struct resource *self;
-    struct resource *children;
-    struct propfind_recursive_element *parent;
-};
-typedef struct propfind_recursive_element propfind_recursive_element_t;
-void clear_propfind_recursive_cache(void);
-struct listdir_context *get_listdir_context_from_recursive_cache(const char *curi);
-void fill_recursive_propfind_cache(const char *uri, const char *curi);
-struct listdir_context *get_listdir_context_from_cache(const char *curi);
-void fetch_resource_list_recursive(const char *uri, const char *curi);
-
-typedef int (*csync_owncloud_redirect_callback_t)(CSYNC* ctx, const char* uri);
-
-/* Struct with the WebDAV session */
-struct dav_session_s {
-    ne_session *ctx;
-    char *user;
-    char *pwd;
-
-    char *proxy_type;
-    char *proxy_host;
-    int   proxy_port;
-    char *proxy_user;
-    char *proxy_pwd;
-
-    char *session_key;
-
-    char *error_string;
-
-    int read_timeout;
-
-    CSYNC *csync_ctx;
-
-    bool no_recursive_propfind;
-
-    csync_owncloud_redirect_callback_t redir_callback;
-};
-extern struct dav_session_s dav_session;
-
-/* The list of properties that is fetched in PropFind on a collection */
-static const ne_propname ls_props[] = {
-    { "DAV:", "getlastmodified" },
-    { "DAV:", "getcontentlength" },
-    { "DAV:", "resourcetype" },
-    { "DAV:", "getetag"},
-    { "http://owncloud.org/ns", "id"},
-    { NULL, NULL }
-};
-
-void set_errno_from_http_errcode( int err );
-void set_error_message( const char *msg );
-void set_errno_from_neon_errcode( int neon_code );
-int http_result_code_from_session(void);
-void set_errno_from_session(void);
-
-time_t oc_httpdate_parse( const char *date );
-
-char *_cleanPath( const char* uri );
-
-int _stat_perms( int type );
-void resourceToFileStat( csync_vio_file_stat_t *lfs, struct resource *res );
-void resource_free(struct resource* o);
-struct resource* resource_dup(struct resource* o);
-
-// Public API from vio
-csync_vio_handle_t *owncloud_opendir(const char *uri);
-csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle);
-int owncloud_closedir(csync_vio_handle_t *dhandle);
-int owncloud_commit(void);
-char *owncloud_error_string(void);
-void owncloud_init(void *userdata);
-int owncloud_set_property(const char *key, void *data);
+// Public API used by csync
+csync_vio_handle_t *owncloud_opendir(CSYNC* ctx, const char *uri);
+csync_vio_file_stat_t *owncloud_readdir(CSYNC* ctx, csync_vio_handle_t *dhandle);
+int owncloud_closedir(CSYNC* ctx, csync_vio_handle_t *dhandle);
+int owncloud_commit(CSYNC* ctx);
+void owncloud_destroy(CSYNC* ctx);
+char *owncloud_error_string(CSYNC* ctx);
+void owncloud_init(CSYNC* ctx);
+int owncloud_set_property(CSYNC* ctx, const char *key, void *data);
 
 #endif /* CSYNC_OWNCLOUD_H */
diff --git a/csync/src/csync_owncloud.h b/csync/src/csync_owncloud_private.h
similarity index 73%
copy from csync/src/csync_owncloud.h
copy to csync/src/csync_owncloud_private.h
index 152a2d9..83b8dc3 100644
--- a/csync/src/csync_owncloud.h
+++ b/csync/src/csync_owncloud_private.h
@@ -18,8 +18,9 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
-#ifndef CSYNC_OWNCLOUD_H
-#define CSYNC_OWNCLOUD_H
+
+#ifndef CSYNC_OWNCLOUD_PRIVATE_H
+#define CSYNC_OWNCLOUD_PRIVATE_H
 
 #include <errno.h>
 #include <stdio.h>
@@ -61,9 +62,57 @@
 
 #include "csync_log.h"
 
+#include "csync_owncloud.h"
+
 
 #define DEBUG_WEBDAV(...) csync_log( 9, "oc_module", __VA_ARGS__);
 
+typedef int (*csync_owncloud_redirect_callback_t)(CSYNC* ctx, const char* uri);
+
+/* Struct with the WebDAV session */
+struct dav_session_s {
+    ne_session *ctx;
+    char *user;
+    char *pwd;
+
+    char *proxy_type;
+    char *proxy_host;
+    int   proxy_port;
+    char *proxy_user;
+    char *proxy_pwd;
+
+    char *session_key;
+
+    char *error_string;
+
+    int read_timeout;
+
+    CSYNC *csync_ctx;
+
+    bool no_recursive_propfind;
+
+    csync_owncloud_redirect_callback_t redir_callback;
+};
+
+struct csync_owncloud_ctx_s {
+    CSYNC *csync_ctx;
+
+    // For the PROPFIND results
+    bool is_first_propfind;
+    struct listdir_context *propfind_cache;
+    c_rbtree_t *propfind_recursive_cache;
+    int propfind_recursive_cache_depth;
+    int propfind_recursive_cache_file_count;
+    int propfind_recursive_cache_folder_count;
+
+    // For the WebDAV connection
+    struct dav_session_s dav_session; /* The DAV Session, initialised in dav_connect */
+    int _connected;                   /* flag to indicate if a connection exists, ie.
+                                         the dav_session is valid */
+};
+typedef struct csync_owncloud_ctx_s csync_owncloud_ctx_t;
+//typedef csync_owncloud_ctx_t* csync_owncloud_ctx_p;
+
 enum resource_type {
     resr_normal = 0,
     resr_collection,
@@ -71,10 +120,19 @@ enum resource_type {
     resr_error
 };
 
+/* The list of properties that is fetched in PropFind on a collection */
+static const ne_propname ls_props[] = {
+    { "DAV:", "getlastmodified" },
+    { "DAV:", "getcontentlength" },
+    { "DAV:", "resourcetype" },
+    { "DAV:", "getetag"},
+    { "http://owncloud.org/ns", "id"},
+    { NULL, NULL }
+};
+
 /* Struct to store data for each resource found during an opendir operation.
  * It represents a single file entry.
  */
-
 typedef struct resource {
     char *uri;           /* The complete uri */
     char *name;          /* The filename only */
@@ -100,8 +158,6 @@ struct listdir_context {
 };
 
 
-/* Our cache, key is a char* */
-extern c_rbtree_t *propfind_recursive_cache;
 /* Values are propfind_recursive_element: */
 struct propfind_recursive_element {
     struct resource *self;
@@ -109,55 +165,18 @@ struct propfind_recursive_element {
     struct propfind_recursive_element *parent;
 };
 typedef struct propfind_recursive_element propfind_recursive_element_t;
-void clear_propfind_recursive_cache(void);
-struct listdir_context *get_listdir_context_from_recursive_cache(const char *curi);
-void fill_recursive_propfind_cache(const char *uri, const char *curi);
-struct listdir_context *get_listdir_context_from_cache(const char *curi);
-void fetch_resource_list_recursive(const char *uri, const char *curi);
-
-typedef int (*csync_owncloud_redirect_callback_t)(CSYNC* ctx, const char* uri);
-
-/* Struct with the WebDAV session */
-struct dav_session_s {
-    ne_session *ctx;
-    char *user;
-    char *pwd;
-
-    char *proxy_type;
-    char *proxy_host;
-    int   proxy_port;
-    char *proxy_user;
-    char *proxy_pwd;
-
-    char *session_key;
-
-    char *error_string;
-
-    int read_timeout;
-
-    CSYNC *csync_ctx;
-
-    bool no_recursive_propfind;
-
-    csync_owncloud_redirect_callback_t redir_callback;
-};
-extern struct dav_session_s dav_session;
 
-/* The list of properties that is fetched in PropFind on a collection */
-static const ne_propname ls_props[] = {
-    { "DAV:", "getlastmodified" },
-    { "DAV:", "getcontentlength" },
-    { "DAV:", "resourcetype" },
-    { "DAV:", "getetag"},
-    { "http://owncloud.org/ns", "id"},
-    { NULL, NULL }
-};
+void clear_propfind_recursive_cache(csync_owncloud_ctx_t *ctx);
+struct listdir_context *get_listdir_context_from_recursive_cache(csync_owncloud_ctx_t *ctx, const char *curi);
+void fill_recursive_propfind_cache(csync_owncloud_ctx_t *ctx, const char *uri, const char *curi);
+struct listdir_context *get_listdir_context_from_cache(csync_owncloud_ctx_t *ctx, const char *curi);
+void fetch_resource_list_recursive(csync_owncloud_ctx_t *ctx, const char *uri, const char *curi);
 
 void set_errno_from_http_errcode( int err );
-void set_error_message( const char *msg );
-void set_errno_from_neon_errcode( int neon_code );
-int http_result_code_from_session(void);
-void set_errno_from_session(void);
+void set_error_message( csync_owncloud_ctx_t *ctx, const char *msg );
+void set_errno_from_neon_errcode(csync_owncloud_ctx_t *ctx, int neon_code );
+int http_result_code_from_session(csync_owncloud_ctx_t *ctx);
+void set_errno_from_session(csync_owncloud_ctx_t *ctx);
 
 time_t oc_httpdate_parse( const char *date );
 
@@ -167,14 +186,8 @@ int _stat_perms( int type );
 void resourceToFileStat( csync_vio_file_stat_t *lfs, struct resource *res );
 void resource_free(struct resource* o);
 struct resource* resource_dup(struct resource* o);
+void free_fetchCtx( struct listdir_context *ctx );
+
 
-// Public API from vio
-csync_vio_handle_t *owncloud_opendir(const char *uri);
-csync_vio_file_stat_t *owncloud_readdir(csync_vio_handle_t *dhandle);
-int owncloud_closedir(csync_vio_handle_t *dhandle);
-int owncloud_commit(void);
-char *owncloud_error_string(void);
-void owncloud_init(void *userdata);
-int owncloud_set_property(const char *key, void *data);
 
-#endif /* CSYNC_OWNCLOUD_H */
+#endif // CSYNC_OWNCLOUD_PRIVATE_H
diff --git a/csync/src/csync_owncloud_recursive_propfind.c b/csync/src/csync_owncloud_recursive_propfind.c
index 4b8c424..6f233bb 100644
--- a/csync/src/csync_owncloud_recursive_propfind.c
+++ b/csync/src/csync_owncloud_recursive_propfind.c
@@ -20,14 +20,7 @@
  */
 
 #include "csync_owncloud.h"
-
-c_rbtree_t *propfind_recursive_cache = NULL;
-int propfind_recursive_cache_depth = 0;
-int propfind_recursive_cache_file_count = 0;
-int propfind_recursive_cache_folder_count = 0;
-
-
-
+#include "csync_owncloud_private.h"
 
 static void _tree_destructor(void *data) {
     propfind_recursive_element_t *element = data;
@@ -36,27 +29,27 @@ static void _tree_destructor(void *data) {
     SAFE_FREE(element);
 }
 
-void clear_propfind_recursive_cache(void)
+void clear_propfind_recursive_cache(csync_owncloud_ctx_t *ctx)
 {
-    if (propfind_recursive_cache) {
+    if (ctx->propfind_recursive_cache) {
         DEBUG_WEBDAV("clear_propfind_recursive_cache Invalidating..");
-        c_rbtree_destroy(propfind_recursive_cache, _tree_destructor);
-        propfind_recursive_cache = NULL;
+        c_rbtree_destroy(ctx->propfind_recursive_cache, _tree_destructor);
+        ctx->propfind_recursive_cache = NULL;
     }
 }
 
-struct listdir_context *get_listdir_context_from_recursive_cache(const char *curi)
+struct listdir_context *get_listdir_context_from_recursive_cache(csync_owncloud_ctx_t *ctx, const char *curi)
 {
     propfind_recursive_element_t *element = NULL;
     struct listdir_context *fetchCtx = NULL;
     struct resource *iterator, *r;
 
-    if (!propfind_recursive_cache) {
+    if (!ctx->propfind_recursive_cache) {
         DEBUG_WEBDAV("get_listdir_context_from_recursive_cache No cache");
         return NULL;
     }
 
-    element = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache, curi));
+    element = c_rbtree_node_data(c_rbtree_find(ctx->propfind_recursive_cache, curi));
     if (!element) {
         DEBUG_WEBDAV("get_listdir_context_from_recursive_cache No element %s in cache found", curi);
         return NULL;
@@ -111,16 +104,15 @@ static void propfind_results_recursive(void *userdata,
     const ne_status *status = NULL;
     char *path = ne_path_unescape( uri->path );
     char *parentPath;
-    char *propfindRootUri = (char*) userdata;
     propfind_recursive_element_t *element = NULL;
     propfind_recursive_element_t *pElement = NULL;
     int depth = 0;
+    csync_owncloud_ctx_t *ctx = (csync_owncloud_ctx_t*) userdata;
 
     (void) status;
-    (void) propfindRootUri;
 
-    if (!propfind_recursive_cache) {
-        c_rbtree_create(&propfind_recursive_cache, _key_cmp, _data_cmp);
+    if (!ctx->propfind_recursive_cache) {
+        c_rbtree_create(&ctx->propfind_recursive_cache, _key_cmp, _data_cmp);
     }
 
     /* Fill the resource structure with the data about the file */
@@ -139,10 +131,10 @@ static void propfind_results_recursive(void *userdata,
     newres->type = resr_normal;
     if( resourcetype && strncmp( resourcetype, "<DAV:collection>", 16 ) == 0) {
         newres->type = resr_collection;
-        propfind_recursive_cache_folder_count++;
+        ctx->propfind_recursive_cache_folder_count++;
     } else {
         /* DEBUG_WEBDAV("propfind_results_recursive %s [%d]", newres->uri, newres->type); */
-        propfind_recursive_cache_file_count++;
+        ctx->propfind_recursive_cache_file_count++;
     }
 
     if (modtime) {
@@ -169,7 +161,7 @@ static void propfind_results_recursive(void *userdata,
     if (newres->type == resr_collection) {
         DEBUG_WEBDAV("propfind_results_recursive %s is a folder", newres->uri);
         /* Check if in rb tree */
-        element = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache,uri->path));
+        element = c_rbtree_node_data(c_rbtree_find(ctx->propfind_recursive_cache,uri->path));
         /* If not, create a new item and insert it */
         if (!element) {
             element = c_malloc(sizeof(propfind_recursive_element_t));
@@ -177,7 +169,7 @@ static void propfind_results_recursive(void *userdata,
             element->self->next = 0;
             element->children = NULL;
             element->parent = NULL;
-            c_rbtree_insert(propfind_recursive_cache, element);
+            c_rbtree_insert(ctx->propfind_recursive_cache, element);
             /* DEBUG_WEBDAV("results_recursive Added collection %s", newres->uri); */
         }
     }
@@ -187,7 +179,7 @@ static void propfind_results_recursive(void *userdata,
     if (parentPath) {
         propfind_recursive_element_t *parentElement = NULL;
 
-        parentElement = c_rbtree_node_data(c_rbtree_find(propfind_recursive_cache,parentPath));
+        parentElement = c_rbtree_node_data(c_rbtree_find(ctx->propfind_recursive_cache,parentPath));
         free(parentPath);
 
         if (parentElement) {
@@ -203,9 +195,9 @@ static void propfind_results_recursive(void *userdata,
                 depth++;
                 pElement = pElement->parent;
             }
-            if (depth > propfind_recursive_cache_depth) {
+            if (depth > ctx->propfind_recursive_cache_depth) {
                 DEBUG_WEBDAV("propfind_results_recursive %s new maximum tree depth %d", newres->uri, depth);
-                propfind_recursive_cache_depth = depth;
+                ctx->propfind_recursive_cache_depth = depth;
             }
 
             /* DEBUG_WEBDAV("results_recursive Added child %s to collection %s", newres->uri, element->self->uri); */
@@ -218,7 +210,7 @@ static void propfind_results_recursive(void *userdata,
 
 }
 
-void fetch_resource_list_recursive(const char *uri, const char *curi)
+void fetch_resource_list_recursive(csync_owncloud_ctx_t *ctx, const char *uri, const char *curi)
 {
     int ret = 0;
     ne_propfind_handler *hdl = NULL;
@@ -230,10 +222,10 @@ void fetch_resource_list_recursive(const char *uri, const char *curi)
     DEBUG_WEBDAV("fetch_resource_list_recursive Starting recursive propfind %s %s", uri, curi);
 
     /* do a propfind request and parse the results in the results function, set as callback */
-    hdl = ne_propfind_create(dav_session.ctx, curi, depth);
+    hdl = ne_propfind_create(ctx->dav_session.ctx, curi, depth);
 
     if(hdl) {
-        ret = ne_propfind_named(hdl, ls_props, propfind_results_recursive, (void*)curi);
+        ret = ne_propfind_named(hdl, ls_props, propfind_results_recursive, ctx);
         request = ne_propfind_get_request( hdl );
         req_status = ne_get_status( request );
     }
@@ -245,14 +237,14 @@ void fetch_resource_list_recursive(const char *uri, const char *curi)
             DEBUG_WEBDAV("ERROR: Request failed: status %d (%s)", req_status->code,
                          req_status->reason_phrase);
             ret = NE_CONNECT;
-            set_error_message(req_status->reason_phrase);
+            set_error_message(ctx, req_status->reason_phrase);
         }
         DEBUG_WEBDAV("Recursive propfind result code %d.", req_status ? req_status->code : 0);
     } else {
         if( ret == NE_ERROR && req_status->code == 404) {
             errno = ENOENT;
         } else {
-            set_errno_from_neon_errcode(ret);
+            set_errno_from_neon_errcode(ctx, ret);
         }
     }
 
@@ -267,7 +259,7 @@ void fetch_resource_list_recursive(const char *uri, const char *curi)
             DEBUG_WEBDAV("ERROR: Content type of propfind request not XML: %s.",
                          content_type ?  content_type: "<empty>");
             errno = ERRNO_WRONG_CONTENT;
-            set_error_message("Server error: PROPFIND reply is not XML formatted!");
+            set_error_message(ctx, "Server error: PROPFIND reply is not XML formatted!");
             ret = NE_CONNECT;
         }
     }
@@ -275,7 +267,7 @@ void fetch_resource_list_recursive(const char *uri, const char *curi)
     if( ret != NE_OK ) {
         const char *err = NULL;
 
-        err = ne_get_error( dav_session.ctx );
+        err = ne_get_error( ctx->dav_session.ctx );
         DEBUG_WEBDAV("WRN: propfind named failed with %d, request error: %s", ret, err ? err : "<nil>");
     }
 
@@ -290,22 +282,21 @@ void fetch_resource_list_recursive(const char *uri, const char *curi)
 }
 
 /* Called by owncloud_opendir()->fetch_resource_list() to fill the cache */
-extern struct listdir_context *propfind_cache;
-void fill_recursive_propfind_cache(const char *uri, const char *curi) {
-    fetch_resource_list_recursive(uri, curi);
+void fill_recursive_propfind_cache(csync_owncloud_ctx_t *ctx, const char *uri, const char *curi) {
+    fetch_resource_list_recursive(ctx, uri, curi);
 
-    if (propfind_recursive_cache_depth <= 2) {
+    if (ctx->propfind_recursive_cache_depth <= 2) {
         DEBUG_WEBDAV("fill_recursive_propfind_cache %s Server maybe did not give us an 'infinity' depth result", curi);
         /* transform the cache to the normal cache in propfind_cache */
-        propfind_cache = get_listdir_context_from_recursive_cache(curi);
+        ctx->propfind_cache = get_listdir_context_from_recursive_cache(ctx, curi);
         /* clear the cache, it is bogus since the server returned only results for Depth 1 */
-        clear_propfind_recursive_cache();
+        clear_propfind_recursive_cache(ctx);
     } else {
         DEBUG_WEBDAV("fill_recursive_propfind_cache %s We received %d elements deep for 'infinity' depth (%d folders, %d files)",
                      curi,
-                     propfind_recursive_cache_depth,
-                     propfind_recursive_cache_folder_count,
-                     propfind_recursive_cache_file_count);
+                     ctx->propfind_recursive_cache_depth,
+                     ctx->propfind_recursive_cache_folder_count,
+                     ctx->propfind_recursive_cache_file_count);
 
     }
 }
diff --git a/csync/src/csync_owncloud_util.c b/csync/src/csync_owncloud_util.c
index 0c5d7d4..7f77d8c 100644
--- a/csync/src/csync_owncloud_util.c
+++ b/csync/src/csync_owncloud_util.c
@@ -20,13 +20,15 @@
  */
 
 #include "csync_owncloud.h"
+#include "csync_owncloud_private.h"
+
 #include "csync_misc.h"
 
-void set_error_message( const char *msg )
+void set_error_message( csync_owncloud_ctx_t *ctx, const char *msg )
 {
-    SAFE_FREE(dav_session.error_string);
+    SAFE_FREE(ctx->dav_session.error_string);
     if( msg )
-        dav_session.error_string = c_strdup(msg);
+        ctx->dav_session.error_string = c_strdup(msg);
 }
 
 void set_errno_from_http_errcode( int err ) {
@@ -104,12 +106,12 @@ void set_errno_from_http_errcode( int err ) {
     errno = new_errno;
 }
 
-int http_result_code_from_session() {
-    const char *p = ne_get_error( dav_session.ctx );
+int http_result_code_from_session(csync_owncloud_ctx_t *ctx) {
+    const char *p = ne_get_error( ctx->dav_session.ctx );
     char *q;
     int err;
 
-    set_error_message(p); /* remember the error message */
+    set_error_message(ctx, p); /* remember the error message */
 
     err = strtol(p, &q, 10);
     if (p == q) {
@@ -118,8 +120,8 @@ int http_result_code_from_session() {
     return err;
 }
 
-void set_errno_from_session() {
-    int err = http_result_code_from_session();
+void set_errno_from_session(csync_owncloud_ctx_t *ctx) {
+    int err = http_result_code_from_session(ctx);
 
     if( err == EIO || err == ERRNO_ERROR_STRING) {
         errno = err;
@@ -128,7 +130,7 @@ void set_errno_from_session() {
     }
 }
 
-void set_errno_from_neon_errcode( int neon_code ) {
+void set_errno_from_neon_errcode(csync_owncloud_ctx_t *ctx, int neon_code ) {
 
     if( neon_code != NE_OK ) {
         DEBUG_WEBDAV("Neon error code was %d", neon_code);
@@ -137,7 +139,7 @@ void set_errno_from_neon_errcode( int neon_code ) {
     switch(neon_code) {
     case NE_OK:     /* Success, but still the possiblity of problems */
     case NE_ERROR:  /* Generic error; use ne_get_error(session) for message */
-        set_errno_from_session(); /* Something wrong with http communication */
+        set_errno_from_session(ctx); /* Something wrong with http communication */
         break;
     case NE_LOOKUP:  /* Server or proxy hostname lookup failed */
         errno = ERRNO_LOOKUP_ERROR;
@@ -361,3 +363,28 @@ void resource_free(struct resource* o) {
         SAFE_FREE(old);
     }
 }
+
+void free_fetchCtx( struct listdir_context *ctx )
+{
+    struct resource *newres, *res;
+    if( ! ctx ) return;
+    newres = ctx->list;
+    res = newres;
+
+    ctx->ref--;
+    if (ctx->ref > 0) return;
+
+    SAFE_FREE(ctx->target);
+
+    while( res ) {
+        SAFE_FREE(res->uri);
+        SAFE_FREE(res->name);
+        SAFE_FREE(res->md5);
+        memset( res->file_id, 0, FILE_ID_BUF_SIZE+1 );
+
+        newres = res->next;
+        SAFE_FREE(res);
+        res = newres;
+    }
+    SAFE_FREE(ctx);
+}
diff --git a/csync/src/csync_private.h b/csync/src/csync_private.h
index cfb642a..cf019b6 100644
--- a/csync/src/csync_private.h
+++ b/csync/src/csync_private.h
@@ -90,6 +90,8 @@ enum csync_replica_e {
 
 typedef struct csync_file_stat_s csync_file_stat_t;
 
+struct csync_owncloud_ctx_s; // csync_owncloud.c
+
 /**
  * @brief csync public structure
  */
@@ -162,6 +164,8 @@ struct csync_s {
   volatile int abort;
   void *rename_info;
   int  read_from_db_disabled;
+
+  struct csync_owncloud_ctx_s *owncloud_context;
 };
 
 
diff --git a/csync/src/vio/csync_vio.c b/csync/src/vio/csync_vio.c
index 282c8de..0db0bdf 100644
--- a/csync/src/vio/csync_vio.c
+++ b/csync/src/vio/csync_vio.c
@@ -44,7 +44,7 @@ csync_vio_handle_t *csync_vio_opendir(CSYNC *ctx, const char *name) {
       if(ctx->remote.read_from_db) {
           CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Read from db flag is true, should not!" );
       }
-      return owncloud_opendir(name);
+      return owncloud_opendir(ctx, name);
       break;
     case LOCAL_REPLICA:
       return csync_vio_local_opendir(name);
@@ -69,7 +69,7 @@ int csync_vio_closedir(CSYNC *ctx, csync_vio_handle_t *dhandle) {
       if( ctx->remote.read_from_db ) {
           CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote ReadFromDb is true, should not!");
       }
-      rc = owncloud_closedir(dhandle);
+      rc = owncloud_closedir(ctx, dhandle);
       break;
   case LOCAL_REPLICA:
       rc = csync_vio_local_closedir(dhandle);
@@ -87,7 +87,7 @@ csync_vio_file_stat_t *csync_vio_readdir(CSYNC *ctx, csync_vio_handle_t *dhandle
       if( ctx->remote.read_from_db ) {
           CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Remote readfromdb is true, should not!");
       }
-      return owncloud_readdir(dhandle);
+      return owncloud_readdir(ctx, dhandle);
       break;
     case LOCAL_REPLICA:
       return csync_vio_local_readdir(dhandle);
@@ -127,15 +127,15 @@ char *csync_vio_get_status_string(CSYNC *ctx) {
   if(ctx->error_string) {
     return ctx->error_string;
   }
-  return owncloud_error_string();
+  return owncloud_error_string(ctx);
 }
 
 int csync_vio_set_property(CSYNC* ctx, const char* key, void* data) {
   (void) ctx;
-  return owncloud_set_property(key, data);
+  return owncloud_set_property(ctx, key, data);
 }
 
 int csync_vio_commit(CSYNC *ctx) {
   (void) ctx;
-  return owncloud_commit();
+  return owncloud_commit(ctx);
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list