"syn 2.0.117",
]
+[[package]]
+name = "dav-rs"
+version = "0.1.0"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "der"
version = "0.7.10"
name = "note"
version = "0.1.0"
dependencies = [
+ "dav-rs",
"entity",
"migration",
"sea-orm",
members = [
"ui-rs",
"ui-rs-derive",
+ "dav-rs",
"application",
"entity",
"migration"
[dependencies]
ui-rs = { path = "../ui-rs" }
+dav-rs = { path = "../dav-rs" }
entity = { path = "../entity" }
migration = { path = "../migration" }
sea-orm = { version = "2.0.0-rc", features = [ "sqlx-sqlite", "sqlx-postgres", "runtime-tokio-native-tls", "macros" ] }
--- /dev/null
+[package]
+name = "dav-rs"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+libc = "0.2"
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+use std::path::Path;
+use std::fs;
+
+fn main() {
+ let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
+ let lib_dir = Path::new(&manifest_dir).join("../build/lib");
+ let config_mk = Path::new(&manifest_dir).join("../config.mk");
+
+ println!("cargo:rustc-link-search=native={}", lib_dir.display());
+ println!("cargo:rustc-link-lib=static=uitk");
+ println!("cargo:rustc-link-lib=static=ucx");
+
+ // read the toolkit linker flags from the config.mk file
+ let content = fs::read_to_string(&config_mk)
+ .expect(&format!("Failed to read {}", config_mk.display()));
+ let mut tokens = vec![];
+ for line in content.lines() {
+ if line.starts_with("TK_LDFLAGS += ") || line.starts_with("DAV_LDFLAGS = ") {
+ tokens.extend(line.split_whitespace().skip(2)); // skip "DAV_LDFLAGS ="
+ }
+ }
+
+ let mut iter = tokens.iter();
+ while let Some(token) = iter.next() {
+ if let Some(lib) = token.strip_prefix("-l") {
+ println!("cargo:rustc-link-lib={}", lib);
+ } else if token.starts_with("-L") {
+ let path = &token[2..];
+ println!("cargo:rustc-link-search=native={}", path);
+ } else if token.starts_with("-R") {
+ let path = &token[2..];
+ println!("cargo:rustc-link-arg=-Wl,-rpath,{}", path);
+ } else if token == &"-framework" {
+ // The next token is the framework name
+ if let Some(framework) = iter.next() {
+ println!("cargo:rustc-link-lib=framework={}", framework);
+ }
+ } else {
+ println!("cargo:rustc-link-arg={}", token);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#![allow(dead_code)]
+
+use crate::dav::ffi;
+
+pub struct DavContext {
+ pub ptr: *mut ffi::DavContext
+}
+
+impl DavContext {
+ pub fn new() -> DavContext {
+ unsafe {
+ DavContext { ptr: dav_context_new() }
+ }
+ }
+}
+
+impl Drop for DavContext {
+ fn drop(&mut self) {
+ unsafe {
+ dav_context_unref(self.ptr);
+ }
+ }
+}
+
+impl Clone for DavContext {
+ fn clone(&self) -> Self {
+ unsafe {
+ dav_context_ref(self.ptr);
+ }
+ DavContext { ptr: self.ptr }
+ }
+}
+
+
+
+unsafe extern "C" {
+ fn dav_context_new() -> *mut ffi::DavContext;
+
+ fn dav_context_ref(ctx: *mut ffi::DavContext);
+ fn dav_context_unref(ctx: *mut ffi::DavContext);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+use std::ffi::{c_char, c_int, c_void};
+use libc::time_t;
+
+#[repr(C)]
+pub struct DavContext {
+ _private: [u8; 0],
+}
+
+#[repr(C)]
+pub struct DavSession {
+ _private: [u8; 0],
+}
+
+#[repr(C)]
+pub struct DavResource {
+ pub session: *mut DavSession,
+ pub prev: *mut DavResource,
+ pub next: *mut DavResource,
+ pub parent: *mut DavResource,
+ pub children: *mut DavResource,
+
+ pub name: *mut c_char,
+ pub path: *mut c_char,
+ pub href: *mut c_char,
+
+ pub contentlength: u64,
+
+ pub contenttype: *mut c_char,
+
+ pub creationdate: time_t,
+ pub lastmodified: time_t,
+
+ pub data: *mut c_void,
+
+ pub iscollection: c_int,
+ pub exists: c_int,
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+mod context;
+mod ffi;
+mod session;
+mod resource;
\ No newline at end of file
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#![allow(dead_code)]
+
+use std::ffi::{c_char, c_int, CString};
+use crate::dav::context::DavContext;
+use crate::dav::ffi;
+use crate::dav::session::Session;
+
+pub struct Resource {
+ pub ptr: *mut ffi::DavResource,
+}
+
+impl Drop for Resource {
+ fn drop(&mut self) {
+ unsafe {
+ dav_resource_free_all(self.ptr);
+ }
+ }
+}
+
+impl Resource {
+ pub fn create(&self) -> bool {
+ unsafe {
+ dav_resource_create(self.ptr) != 0
+ }
+ }
+
+ pub fn delete(&self) -> bool {
+ unsafe {
+ dav_resource_delete(self.ptr) != 0
+ }
+ }
+
+ pub fn exists(&self) -> bool {
+ unsafe {
+ dav_resource_exists(self.ptr) != 0
+ }
+ }
+}
+
+impl Session {
+ pub fn new_resource(&self, path: &str) -> Resource {
+ let cstr = CString::new(path).unwrap();
+ unsafe {
+ Resource {
+ ptr: dav_resource_new(self.ptr, cstr.as_ptr())
+ }
+ }
+ }
+}
+
+unsafe extern "C" {
+ fn dav_resource_new(sn: *mut ffi::DavSession, path: *const c_char) -> *mut ffi::DavResource;
+ fn dav_resource_new_child(sn: *mut ffi::DavSession, parent: *mut ffi::DavResource, name: *const c_char) -> *mut ffi::DavResource;
+ fn dav_resource_free_all(res: *mut ffi::DavResource);
+
+ fn dav_resource_create(res: *mut ffi::DavResource) -> c_int;
+ fn dav_resource_delete(res: *mut ffi::DavResource) -> c_int;
+ fn dav_resource_exists(res: *mut ffi::DavResource) -> c_int;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#![allow(dead_code)]
+
+use std::ffi::{c_char, CString};
+use crate::dav::context::DavContext;
+use crate::dav::ffi;
+
+pub struct Session {
+ pub ptr: *mut ffi::DavSession
+}
+
+impl Drop for Session {
+ fn drop(&mut self) {
+ unsafe {
+ dav_session_unref(self.ptr);
+ }
+ }
+}
+
+impl Clone for Session {
+ fn clone(&self) -> Self {
+ unsafe {
+ Session {
+ ptr: dav_session_clone(self.ptr)
+ }
+ }
+ }
+}
+
+impl Session {
+ pub fn set_auth(&self, user: &str, password: &str) {
+ let user_cstr = CString::new(user).unwrap();
+ let password_cstr = CString::new(password).unwrap();
+ unsafe {
+ dav_session_set_auth(self.ptr, user_cstr.as_ptr(), password_cstr.as_ptr());
+ }
+ }
+}
+
+
+impl DavContext {
+ pub fn create_session(&self, base_url: &str) -> Session {
+ let cstr = CString::new(base_url).unwrap();
+ unsafe {
+ Session {
+ ptr: dav_session_new(self.ptr, cstr.as_ptr())
+ }
+ }
+ }
+
+ pub fn create_session_with_auth(&self, base_url: &str, user: &str, password: &str) -> Session {
+ let sn = self.create_session(base_url);
+ sn.set_auth(user, password);
+ sn
+ }
+}
+
+
+unsafe extern "C" {
+ fn dav_session_new(ctx: *mut ffi::DavContext, base_url: *const libc::c_char) -> *mut ffi::DavSession;
+ //fn dav_session_ref(sn: *mut ffi::DavSession);
+ fn dav_session_unref(sn: *mut ffi::DavSession);
+ fn dav_session_clone(sn: *mut ffi::DavSession) -> *mut ffi::DavSession;
+ fn dav_session_set_auth(sn: *mut ffi::DavSession, user: *const c_char, password: *const c_char);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#![allow(unused_imports)]
+
+pub mod dav;
\ No newline at end of file
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DAV_ATOMIC_H
+#define DAV_ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__gnu_linux__) || defined(OSX) || defined(BSD)
+
+#define dav_atomic_inc32(intptr) __sync_fetch_and_add(intptr, 1)
+#define dav_atomic_dec32(intptr) (__sync_fetch_and_sub(intptr, 1) - 1)
+
+#else
+// use atomic.h
+#include <atomic.h>
+
+#define dav_atomic_inc32(intptr) atomic_inc_32_nv(intptr)
+#define dav_atomic_dec32(intptr) atomic_dec_32_nv(intptr)
+// TODO
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DAV_ATOMIC_H */
+
data->length = 0;
}
-void dav_set_content_data(DavResource *res, char *content, size_t length) {
+void dav_set_content_data(DavResource *res, const char *content, size_t length) {
DavSession *sn = res->session;
DavResourceData *data = res->data;
data->content = dav_session_malloc(sn, length);
#include "session.h"
#include "resource.h"
#include "methods.h"
+#include "atomic.h"
DavSession* dav_session_new(DavContext *context, char *base_url) {
if(!base_url) {
// add to context
dav_context_add_session(context, sn);
sn->context = context;
+ dav_context_ref(context);
+
+ sn->ref = 1;
return sn;
}
// add to context
dav_context_add_session(sn->context, newsn);
newsn->context = sn->context;
+ dav_context_ref(sn->context);
+
+ newsn->ref = 1;
return newsn;
}
+void dav_session_ref(DavSession *sn) {
+ dav_atomic_inc32(&sn->ref);
+}
+
+void dav_session_unref(DavSession *sn) {
+ if(dav_atomic_dec32(&sn->ref) == 0) {
+ dav_session_destroy(sn);
+ }
+}
+
void dav_session_set_auth(DavSession *sn, const char *user, const char *password) {
if(user && password) {
dav_session_set_auth_s(sn, cx_str(user), cx_str(password));
void dav_session_destroy(DavSession *sn) {
// remove session from context
- if (dav_context_remove_session(sn->context, sn)) {
+ DavContext *ctx = sn->context;
+ dav_context_ref(ctx);
+ if (dav_context_remove_session(ctx, sn)) {
fprintf(stderr, "Error: session not found in ctx->sessions\n");
dav_session_destructor(sn);
}
+ dav_context_unref(ctx);
}
void dav_session_destructor(DavSession *sn) {
cxMempoolFree(sn->mp);
curl_easy_cleanup(sn->handle);
+ dav_context_unref(sn->context);
free(sn);
}
#include <cx/compare.h>
#include "davqlparser.h"
#include "davqlexec.h"
+#include "atomic.h"
DavContext* dav_context_new(void) {
dav_context_destroy(context);
return NULL;
}
+
+ context->ref = 1;
return context;
}
+void dav_context_ref(DavContext *ctx) {
+ dav_atomic_inc32(&ctx->ref);
+}
+
+void dav_context_unref(DavContext *ctx) {
+ if(dav_atomic_dec32(&ctx->ref) == 0) {
+ dav_context_destroy(ctx);
+ }
+}
+
void dav_context_destroy(DavContext *ctx) {
// destroy all sessions assoziated with this context
// ctx->sessions destructor must be dav_session_destructor
void(*get_progress)(DavResource *res, int64_t total, int64_t now, void *userdata);
void(*put_progress)(DavResource *res, int64_t total, int64_t now, void *userdata);
void *progress_userdata;
+
+ unsigned int ref;
};
struct DavContext {
- CxMap *namespaces;
- CxMap *namespaceinfo;
- CxMap *keys;
- CxList *sessions;
- DavProxy *http_proxy;
- DavProxy *https_proxy;
- DAV_MUTEX mutex;
- DavBool mtsafe;
+ CxMap *namespaces;
+ CxMap *namespaceinfo;
+ CxMap *keys;
+ CxList *sessions;
+ DavProxy *http_proxy;
+ DavProxy *https_proxy;
+ DAV_MUTEX mutex;
+ DavBool mtsafe;
+ unsigned int ref;
};
struct DavProxy {
};
DavContext* dav_context_new(void);
+void dav_context_ref(DavContext *ctx);
+void dav_context_unref(DavContext *ctx);
void dav_context_destroy(DavContext *ctx);
void dav_context_set_mtsafe(DavContext *ctx, DavBool enable);
char *user,
char *password);
DavSession* dav_session_clone(DavSession *sn);
+void dav_session_ref(DavSession *sn);
+void dav_session_unref(DavSession *sn);
void dav_session_set_auth(DavSession *sn, const char *user, const char *password);
void dav_session_set_auth_s(DavSession *sn, cxstring user, cxstring password);
void dav_session_set_baseurl(DavSession *sn, char *base_url);
DavPropName* dav_get_property_names(DavResource *res, size_t *count);
void dav_set_content(DavResource *res, void *stream, dav_read_func read_func, dav_seek_func seek_func);
-void dav_set_content_data(DavResource *res, char *content, size_t length);
+void dav_set_content_data(DavResource *res, const char *content, size_t length);
void dav_set_content_length(DavResource *res, size_t length);
int dav_load(DavResource *res);