implement webdav xattr namespace lists

Sun, 19 Mar 2023 16:48:19 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 19 Mar 2023 16:48:19 +0100
changeset 484
c036a8b242a8
parent 483
f69d88f86b9c
child 485
222557f4f595

implement webdav xattr namespace lists

src/server/Makefile file | annotate | diff | comparison | revisions
src/server/webdav/multistatus.c file | annotate | diff | comparison | revisions
src/server/webdav/xattrbackend.c file | annotate | diff | comparison | revisions
src/ucx/hash_map.c file | annotate | diff | comparison | revisions
--- a/src/server/Makefile	Sun Mar 19 14:02:39 2023 +0100
+++ b/src/server/Makefile	Sun Mar 19 16:48:19 2023 +0100
@@ -78,7 +78,7 @@
 
 
 $(TEST_TARGET): $(TESTOBJS) $(PLUGINS)
-	$(CC) -o $(TEST_TARGET) $(TESTOBJS) -L$(BUILD_ROOT)/build/lib $(LDFLAGS) $(TEST_PLUGIN_LDFLAGS)
+	$(CC) -o $(TEST_TARGET) $(TESTOBJS) -L$(BUILD_ROOT)/build/lib $(LDFLAGS) $(RPATH_WS_LIB_FLAG) $(TEST_PLUGIN_LDFLAGS)
 
 
 $(PLUGINS): $(MAIN_TARGET) FORCE
--- a/src/server/webdav/multistatus.c	Sun Mar 19 14:02:39 2023 +0100
+++ b/src/server/webdav/multistatus.c	Sun Mar 19 16:48:19 2023 +0100
@@ -70,7 +70,7 @@
     // write the namespaces definitions
     // key is the namespace prefix
     // the map always contains the "DAV:" namespace with the prefix "D"
-    CxIterator i = cxMapIterator(ms->namespaces);
+    CxIterator i = cxMapIterator(ms->namespaces);  
     cx_foreach(CxMapEntry*, entry, i) {
         WSNamespace *ns = entry->value;
         writer_put_lit(out, " xmlns:");
--- a/src/server/webdav/xattrbackend.c	Sun Mar 19 14:02:39 2023 +0100
+++ b/src/server/webdav/xattrbackend.c	Sun Mar 19 16:48:19 2023 +0100
@@ -482,6 +482,28 @@
     return 0;
 }
 
+static int webdav_xattr_parse_ns(cxstring line, cxstring *prefix, cxstring *href) {
+    size_t i = 0;
+    for(i=1;i<line.length;i++) {
+        if(line.ptr[i] == ':') {
+            break;
+        }
+    }
+    if(i == 0 || i+1 >= line.length) {
+        // error: ':' not found or ':' is the last character
+        return 1;
+    }
+    
+    cxstring pre;
+    pre.ptr = line.ptr;
+    pre.length = i;
+    *prefix = pre;
+    
+    *href = cx_strsubs(line, i+1);
+    
+    return 0;
+}
+
 int webdav_xattr_put_prop(CxMap *pmap, WebdavProperty *prop) {
     CxHashKey key = webdav_property_key_a(
             pmap->allocator,
@@ -502,13 +524,13 @@
     }
     cxstring dat = cx_strn(data, len);
     
-    printf("\n\n");
-    
     cxstring s_elm  = CX_STR("prop ");
     cxstring s_ns   = CX_STR("ns ");
     cxstring s_data = CX_STR("data ");
     
     WebdavProperty *prop = NULL;
+    WebdavNSList *ns_begin = NULL;
+    WebdavNSList *ns_end = NULL;
     
     int error = 0;
     
@@ -534,7 +556,7 @@
             if(webdav_xattr_parse_elm(line, &name, &prefix, &xmlns, &lang)) {
                 log_ereport(
                         LOG_FAILURE,
-                        "webdav xattr backend: %file %s: invalid xattr format[%d]: cannot parse elm line",
+                        "webdav xattr backend: file %s: invalid xattr format[%d]: cannot parse elm line",
                         path,
                         elmno);
                 error = 1;
@@ -548,12 +570,15 @@
                 break;
             }
             ZERO(prop, sizeof(WebdavProperty));
+            ns_begin = NULL;
+            ns_end = NULL;
             
             WSNamespace *ns = cxMalloc(a, sizeof(WSNamespace));
             if(!ns) {
                 error = 1;
                 break;
             }
+            ZERO(ns, sizeof(WSNamespace));
             
             char *name_str = cx_strdup_a(a, name).ptr;
             char *prefix_str = cx_strdup_a(a, prefix).ptr;
@@ -572,7 +597,38 @@
             elmno++;
         } else if(prop) {
             if(cx_strprefix(line, s_ns)) {
-                // TODO
+                line = cx_strsubs(line, 3);
+                
+                cxstring prefix;
+                cxstring href;
+                if(webdav_xattr_parse_ns(line, &prefix, &href)) {
+                    log_ereport(
+                            LOG_FAILURE,
+                            "webdav xattr backend: file %s: invalid xattr format[%d]: cannot parse ns",
+                            path,
+                            elmno);
+                    error = 1;
+                    break;
+                }
+                
+                WSNamespace *ns_decl = cxMalloc(a, sizeof(WSNamespace));
+                if(!ns_decl) {
+                    error = 1;
+                    break;
+                }
+                ZERO(ns_decl, sizeof(WSNamespace));
+                
+                ns_decl->prefix = (const xmlChar*)cx_strdup_a(a, prefix).ptr;
+                ns_decl->href = (const xmlChar*)cx_strdup_a(a, href).ptr;
+                if(!(ns_decl->prefix && ns_decl->href)) {
+                    error = 1;
+                    break;
+                }
+                
+                if(webdav_nslist_add(a->data, &ns_begin, &ns_end, ns_decl)) {
+                    error = 1;
+                    break;
+                }
             } else if(cx_strprefix(line, s_data)) {
                 line = cx_strsubs(line, 5);
                 
@@ -582,7 +638,7 @@
                 if(!util_strtoint(line.ptr, &data_len)) {
                     log_ereport(
                             LOG_FAILURE,
-                            "webdav xattr backend: %file %s: invalid xattr format[%d]: number expected after data",
+                            "webdav xattr backend: file %s: invalid xattr format[%d]: number expected after data",
                             path,
                             elmno);
                     error = 1;
@@ -594,7 +650,7 @@
                     if(data_len > dat.length - pos) {
                         log_ereport(
                                 LOG_FAILURE,
-                                "webdav xattr backend: %file %s: invalid data length %" PRId64 " in prop %d",
+                                "webdav xattr backend: file %s: invalid data length %" PRId64 " in prop %d",
                                 path,
                                 data_len,
                                 elmno);
@@ -613,7 +669,7 @@
                         break;
                     }
                     prop->vtype = WS_VALUE_XML_DATA;
-                    prop->value.data.namespaces = NULL;
+                    prop->value.data.namespaces = ns_begin;
                     prop->value.data.data = propdata_cp.ptr;
                     prop->value.data.length = propdata_cp.length;
                     
@@ -624,16 +680,13 @@
             } else {
                 log_ereport(
                         LOG_FAILURE,
-                        "webdav xattr backend: %file %s: invalid xattr format[%d]: unknown element",
+                        "webdav xattr backend: file %s: invalid xattr format[%d]: unknown element",
                         path,
                         elmno);
                 error = 1;
                 break;
             }
         }
-        
-        //printf("line: {%.*s}\n", (int)line.length, line.ptr);
-        //fflush(stdout);
     }
     
     // add last property
@@ -649,10 +702,6 @@
         pmap = NULL;
     }
     
-    //printf("\n\n");
-    //fflush(stdout);
-    
-    
     return pmap;
 }
 
@@ -681,7 +730,7 @@
         if(property_value) {
             WebdavNSList *ns = property_value->namespaces; 
             while(ns) {
-                ret = cx_bprintf(&buf, "ns %s:%s\n", prop->namespace->prefix, prop->namespace->href);
+                ret = cx_bprintf(&buf, "ns %s:%s\n", ns->namespace->prefix, ns->namespace->href);
                 if(ret <= 0) {
                     pool_free(pool, buf.space);
                     return (cxmutstr){NULL,0};
--- a/src/ucx/hash_map.c	Sun Mar 19 14:02:39 2023 +0100
+++ b/src/ucx/hash_map.c	Sun Mar 19 16:48:19 2023 +0100
@@ -302,12 +302,12 @@
 
     iter.slot = 0;
     iter.index = 0;
-
+    
     if (map->size > 0) {
         struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
         struct cx_hash_map_element_s *elm = hash_map->buckets[0];
-        for (; elm == NULL; iter.slot++) {
-            elm = hash_map->buckets[iter.slot];
+        while (elm == NULL) {
+            elm = hash_map->buckets[++iter.slot];
         }
         iter.elem_handle = elm;
         iter.kv_data.key = &elm->key;

mercurial