# HG changeset patch # User Olaf Wintermann # Date 1679240899 -3600 # Node ID c036a8b242a8036c7b09b4b82a9811856c122fc8 # Parent f69d88f86b9cf83dd123581f56c092c82a5cd1a3 implement webdav xattr namespace lists diff -r f69d88f86b9c -r c036a8b242a8 src/server/Makefile --- 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 diff -r f69d88f86b9c -r c036a8b242a8 src/server/webdav/multistatus.c --- 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:"); diff -r f69d88f86b9c -r c036a8b242a8 src/server/webdav/xattrbackend.c --- 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) { + // 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}; diff -r f69d88f86b9c -r c036a8b242a8 src/ucx/hash_map.c --- 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;