]> uap-core.de Git - note.git/commitdiff
begin rust bindings for libidav main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 20 Jun 2026 17:21:50 +0000 (19:21 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 20 Jun 2026 17:21:50 +0000 (19:21 +0200)
16 files changed:
Cargo.lock
Cargo.toml
application/Cargo.toml
dav-rs/Cargo.toml [new file with mode: 0644]
dav-rs/build.rs [new file with mode: 0644]
dav-rs/src/dav/context.rs [new file with mode: 0644]
dav-rs/src/dav/ffi.rs [new file with mode: 0644]
dav-rs/src/dav/mod.rs [new file with mode: 0644]
dav-rs/src/dav/resource.rs [new file with mode: 0644]
dav-rs/src/dav/session.rs [new file with mode: 0644]
dav-rs/src/lib.rs [new file with mode: 0644]
libidav/atomic.h [new file with mode: 0644]
libidav/resource.c
libidav/session.c
libidav/webdav.c
libidav/webdav.h

index 6db192c6fc3b47d183e3399c9f016bb56d530bfb..bcbe107559a9cea3fac525c407c43840701bfc38 100644 (file)
@@ -666,6 +666,13 @@ dependencies = [
  "syn 2.0.117",
 ]
 
+[[package]]
+name = "dav-rs"
+version = "0.1.0"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "der"
 version = "0.7.10"
@@ -1515,6 +1522,7 @@ dependencies = [
 name = "note"
 version = "0.1.0"
 dependencies = [
+ "dav-rs",
  "entity",
  "migration",
  "sea-orm",
index 4065e4a7efcc6ef9bda70aa872823f9d46202de3..4497b47ae1457f5d537c1da48fd26a26af66f7ef 100644 (file)
@@ -2,6 +2,7 @@
 members = [
     "ui-rs",
     "ui-rs-derive",
+    "dav-rs",
     "application",
     "entity",
     "migration"
index ed6f7a683a11f00874275778e22a5b873f2127af..af0ace567dde30b2722c70b7894b7e1d6a5d9141 100644 (file)
@@ -5,6 +5,7 @@ edition = "2024"
 
 [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" ] }
diff --git a/dav-rs/Cargo.toml b/dav-rs/Cargo.toml
new file mode 100644 (file)
index 0000000..05db057
--- /dev/null
@@ -0,0 +1,7 @@
+[package]
+name = "dav-rs"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+libc = "0.2"
diff --git a/dav-rs/build.rs b/dav-rs/build.rs
new file mode 100644 (file)
index 0000000..58d97f0
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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);
+        }
+    }
+
+}
diff --git a/dav-rs/src/dav/context.rs b/dav-rs/src/dav/context.rs
new file mode 100644 (file)
index 0000000..5090278
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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
diff --git a/dav-rs/src/dav/ffi.rs b/dav-rs/src/dav/ffi.rs
new file mode 100644 (file)
index 0000000..93279af
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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,
+}
diff --git a/dav-rs/src/dav/mod.rs b/dav-rs/src/dav/mod.rs
new file mode 100644 (file)
index 0000000..19d865a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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
diff --git a/dav-rs/src/dav/resource.rs b/dav-rs/src/dav/resource.rs
new file mode 100644 (file)
index 0000000..9f58871
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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
diff --git a/dav-rs/src/dav/session.rs b/dav-rs/src/dav/session.rs
new file mode 100644 (file)
index 0000000..f63c41e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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
diff --git a/dav-rs/src/lib.rs b/dav-rs/src/lib.rs
new file mode 100644 (file)
index 0000000..e8f9469
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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
diff --git a/libidav/atomic.h b/libidav/atomic.h
new file mode 100644 (file)
index 0000000..8f63d46
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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 */
+
index bf57861ca1276d5aa5bcfc0d65040f54ecabe20b..3b55213ea67d1bad36f97f63f4382787de4b1fd4 100644 (file)
@@ -761,7 +761,7 @@ void dav_set_content(DavResource *res, void *stream, dav_read_func read_func, da
     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);
index bf66e7976355b16d4c6282bfe8821b290925a597..e922593c52afd8bf04ed0355fac9c9bf95772096 100644 (file)
@@ -38,6 +38,7 @@
 #include "session.h"
 #include "resource.h"
 #include "methods.h"
+#include "atomic.h"
 
 DavSession* dav_session_new(DavContext *context, char *base_url) {
     if(!base_url) {
@@ -95,6 +96,9 @@ DavSession* dav_session_new(DavContext *context, char *base_url) {
     // add to context
     dav_context_add_session(context, sn);
     sn->context = context;
+    dav_context_ref(context);
+    
+    sn->ref = 1;
     
     return sn;
 }
@@ -138,10 +142,23 @@ DavSession* dav_session_clone(DavSession *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));
@@ -344,15 +361,19 @@ void dav_session_set_errstr(DavSession *sn, const char *str) {
 
 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);
 }
 
index 0a4afed2523d06b7f61ba216882f172f8ddd8e40..a7dc580c1d87e64e839c937c48e1c2a399cb7c01 100644 (file)
@@ -41,6 +41,7 @@
 #include <cx/compare.h>
 #include "davqlparser.h"
 #include "davqlexec.h"
+#include "atomic.h"
 
 
 DavContext* dav_context_new(void) {
@@ -94,10 +95,22 @@ 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
index 3bd60acbacac97ba442abca8c09630fd87f45371..e1efa31637fd4a79ed2a543959a065a2552f42a7 100644 (file)
@@ -189,17 +189,20 @@ struct DavSession {
     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 {
@@ -264,6 +267,8 @@ struct DavXmlAttr {
 };
 
 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);
 
@@ -290,6 +295,8 @@ DavSession* dav_session_new_auth(
         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);
@@ -371,7 +378,7 @@ void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name);
 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);