--- a/libidav/webdav.c Wed Jan 31 12:55:11 2024 +0100 +++ b/libidav/webdav.c Tue Feb 06 14:17:22 2024 +0100 @@ -146,15 +146,68 @@ free(ctx); } +#ifndef _WIN32 + +void dav_context_set_mtsafe(DavContext *ctx, DavBool enable) { + if (enable) { + pthread_mutex_init(&ctx->mutex, NULL); + } else { + pthread_mutex_destroy(&ctx->mutex); + } + ctx->mtsafe = enable; +} + +void dav_context_lock(DavContext *ctx) { + if (ctx->mtsafe) { + pthread_mutex_lock(&ctx->mutex); + } +} + +void dav_context_unlock(DavContext *ctx) { + if (ctx->mtsafe) { + pthread_mutex_unlock(&ctx->mutex); + } +} + +#else + +void dav_context_set_mtsafe(DavContext *ctx, DavBool enable) { + if (enable) { + ctx->mutex = CreateMutex(NULL, FALSE, NULL); + } else { + CloseHandle(ctx->mutex); + } + ctx->mtsafe = enable; +} + +void dav_context_lock(DavContext *ctx) { + if (ctx->mtsafe) { + WaitForSingleObject(ctx->mutex, INFINITE); + } +} + +void dav_context_unlock(DavContext *ctx) { + if (ctx->mtsafe) { + ReleaseMutex(ctx->mutex); + } +} + +#endif + void dav_context_add_key(DavContext *context, DavKey *key) { + dav_context_lock(context); cxMapPut(context->keys, cx_hash_key_str(key->name), key); + dav_context_unlock(context); } DavKey* dav_context_get_key(DavContext *context, const char *name) { + DavKey *key = NULL; + dav_context_lock(context); if(name) { - return cxMapGet(context->keys, cx_hash_key_str(name)); + key = cxMapGet(context->keys, cx_hash_key_str(name)); } - return NULL; + dav_context_unlock(context); + return key; } int dav_add_namespace(DavContext *context, const char *prefix, const char *name) { @@ -164,8 +217,19 @@ } char *p = strdup(prefix); + if (!p) { + free(namespace); + return 1; + } char *n = strdup(name); - + if (!n) { + free(namespace); + free(p); + return 1; + } + + dav_context_lock(context); + int err = 0; if(p && n) { namespace->prefix = p; @@ -178,19 +242,29 @@ if(p) free(p); if(n) free(n); } + + dav_context_unlock(context); return err; } DavNamespace* dav_get_namespace(DavContext *context, const char *prefix) { - return cxMapGet(context->namespaces, cx_hash_key_str(prefix)); + dav_context_lock(context); + DavNamespace *ns = cxMapGet(context->namespaces, cx_hash_key_str(prefix)); + dav_context_unlock(context); + return ns; } DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix) { - return cxMapGet(context->namespaces, cx_hash_key(prefix.ptr, prefix.length)); + dav_context_lock(context); + DavNamespace *ns = cxMapGet(context->namespaces, cx_hash_key(prefix.ptr, prefix.length)); + dav_context_unlock(context); + return ns; } int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt) { + dav_context_lock(context); + CxHashKey hkey = cx_hash_key_str(ns); DavNSInfo *info = cxMapGet(context->namespaceinfo, hkey); if(!info) { @@ -200,15 +274,21 @@ } else { info->encrypt = encrypt; } + + dav_context_unlock(context); return 0; } int dav_namespace_is_encrypted(DavContext *context, const char *ns) { + int ret = 0; + dav_context_lock(context); + DavNSInfo *info = cxMapGet(context->namespaceinfo, cx_hash_key_str(ns)); if(info) { - return info->encrypt; + ret = info->encrypt; } - return 0; + dav_context_unlock(context); + return ret; } void dav_get_property_namespace_str( @@ -262,6 +342,28 @@ } } +int dav_context_add_session(DavContext *context, DavSession *sn) { + dav_context_lock(context); + int ret = cxListAdd(context->sessions, sn); + dav_context_unlock(context); + return ret; +} + +int dav_context_remove_session(DavContext *context, DavSession *sn) { + int ret = 0; + dav_context_lock(context); + CxList *sessions = context->sessions; + ssize_t i = cxListFind(sessions, sn); + if(i >= 0) { + cxListRemove(sessions, i); + } else { + ret = 1; + } + dav_context_unlock(context); + return ret; +} + + // TODO: add sstr_t version of dav_get_property_ns void dav_set_effective_href(DavSession *sn, DavResource *resource) {