libidav/webdav.c

changeset 74
da079dc0724c
parent 66
f8c1f685e08e
child 75
56962faf2b42
--- a/libidav/webdav.c	Thu Jan 29 11:43:41 2015 +0100
+++ b/libidav/webdav.c	Sun Feb 08 16:36:32 2015 +0100
@@ -41,68 +41,140 @@
 
 
 DavContext* dav_context_new() {
-    DavContext *context = malloc(sizeof(DavContext));
+    // initialize
+    DavContext *context = calloc(1, sizeof(DavContext));
     if(!context) {
         return NULL;
     }
     context->sessions = NULL;
     context->http_proxy = calloc(1, sizeof(DavProxy));
+    if(!context->http_proxy) {
+        dav_context_destroy(context);
+        return NULL;
+    }
     context->https_proxy = calloc(1, sizeof(DavProxy));
+    if(!context->https_proxy) {
+        dav_context_destroy(context);
+        return NULL;
+    }
     context->namespaces = ucx_map_new(16);
     if(!context->namespaces) {
-        free(context);
+        dav_context_destroy(context);
         return NULL;
     }
     context->keys = ucx_map_new(16);
-    DavNamespace *davns = malloc(sizeof(DavNamespace));
-    if(!davns) {
-        ucx_map_free(context->namespaces);
-        free(context);
-        return NULL;
-    }
-    davns->prefix = "D";
-    davns->name = "DAV:";
-    if(ucx_map_cstr_put(context->namespaces, "D", davns)) {
-        free(davns);
-        ucx_map_free(context->namespaces);
-        free(context);
+    if(!context->keys) {
+        dav_context_destroy(context);
         return NULL;
     }
     
-    DavNamespace *idavns = malloc(sizeof(DavNamespace));
-    if(!idavns) {
+    // add DAV: namespace
+    DavNamespace *davns = malloc(sizeof(DavNamespace));
+    if(!davns) {
         free(davns);
-        ucx_map_free(context->namespaces);
-        free(context);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    davns->prefix = strdup("D");
+    if(!davns->prefix) {
+        free(davns);
+        dav_context_destroy(context);
         return NULL;
     }
-    idavns->prefix = "idav";
-    idavns->name = DAV_NS;
-    if(ucx_map_cstr_put(context->namespaces, "idav", idavns)) {
+    davns->name = strdup("DAV:");
+    if(!davns->name) {
+        free(davns->prefix);
         free(davns);
-        free(idavns);
-        ucx_map_free(context->namespaces);
-        free(context);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    if(ucx_map_cstr_put(context->namespaces, "D", davns)) {
+        free(davns->prefix);
+        free(davns->name);
+        free(davns);
+        dav_context_destroy(context);
         return NULL;
     }
     
+    // add idav namespace
+    DavNamespace *idavns = malloc(sizeof(DavNamespace));
+    if(!idavns) {
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    idavns->prefix = strdup("idav");
+    if(!idavns->prefix) {
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    idavns->name = strdup(DAV_NS);
+    if(!idavns->name) {
+        free(idavns->prefix);
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
+    if(ucx_map_cstr_put(context->namespaces, "idav", idavns)) {
+        free(idavns->prefix);
+        free(idavns->name);
+        free(idavns);
+        dav_context_destroy(context);
+        return NULL;
+    }
     
     return context;
 }
 
 void dav_context_destroy(DavContext *ctx) {
     // destroy all sessions assoziated with this context
-    UCX_FOREACH(elm, ctx->sessions) {
-        dav_session_destroy(elm->data);
+    UcxList *elm = ctx->sessions;
+    while(elm) {
+        DavSession *sn = elm->data;
+        elm = elm->next;
+        dav_session_destroy(sn);
     }
-    free(ctx->http_proxy);
-    free(ctx->https_proxy);
+    if(ctx->http_proxy) {
+        free(ctx->http_proxy);
+    }
+    if(ctx->https_proxy) {
+        free(ctx->https_proxy);
+    }
     
-    UcxMapIterator i = ucx_map_iterator(ctx->namespaces);
-    UcxKey k;
-    DavNamespace *ns;
-    // TODO: free map elements
-    ucx_map_free(ctx->namespaces);
+    if(ctx->namespaces) {
+        UcxMapIterator i = ucx_map_iterator(ctx->namespaces);
+        UcxKey k;
+        DavNamespace *ns;
+        UCX_MAP_FOREACH(k, ns, i) {
+            if(!ns) continue;
+            if(ns->prefix) {
+                free(ns->prefix);
+            }
+            if(ns->name) {
+                free(ns->name);
+            }
+            free(ns);
+        }
+        ucx_map_free(ctx->namespaces);
+    }
+    if(ctx->keys) {
+        UcxMapIterator i = ucx_map_iterator(ctx->keys);
+        UcxKey k;
+        DavKey *key;
+        UCX_MAP_FOREACH(k, key, i) {
+            if(!key) continue;
+            if(key->name) {
+                free(key->name);
+            }
+            if(key->data) {
+                free(key->data);
+            }
+            free(key);
+        }
+        ucx_map_free(ctx->keys);
+    }    
+    
     free(ctx);
 }
 
@@ -195,12 +267,19 @@
 int dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, DavQOp *cond, size_t len) {
     // clean resource properties
     DavResourceData *data = root->data;
-    if(data->properties->count > 0) {
+    size_t pcount = data->properties->count;
+    if(pcount > 0) {
         UcxKey key;
         void *value;
         UcxMapIterator i = ucx_map_iterator(data->properties);
+        UcxKey mkeys[pcount];
+        int index = 0;
         UCX_MAP_FOREACH(key, value, i) {
-            ucx_map_remove(data->properties, key);
+            mkeys[index] = key;
+            index++;
+        }
+        for(int j=0;j<index;j++) {
+            ucx_map_remove(data->properties, mkeys[j]);
         }
     }
     
@@ -255,6 +334,12 @@
     } else {
         UcxList *proplist = parse_properties_string(sn->context, ps);
         rqbuf = create_propfind_request(sn, proplist);
+        UCX_FOREACH(elm, proplist) {
+            DavProperty *prop = elm->data;
+            free(prop->name);
+            free(prop);
+        }
+        ucx_list_free(proplist);
     }
     
     //fwrite(rqbuf->space, 1, rqbuf->size, stdout);
@@ -290,7 +375,7 @@
 
 UcxList* parse_properties_string(DavContext *context, sstr_t str) {
     UcxList *proplist = NULL;
-    size_t nprops = 0;
+    ssize_t nprops = 0;
     sstr_t *props = sstrsplit(str, S(","), &nprops);
     for(int i=0;i<nprops;i++) {
         sstr_t s = props[i];

mercurial