add first jmap code, implement session query dav-2 tip

Wed, 08 Jul 2026 15:34:41 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 08 Jul 2026 15:34:41 +0200
branch
dav-2
changeset 925
61a231a8d8f5
parent 924
e1f053ba2c10

add first jmap code, implement session query

Makefile file | annotate | diff | comparison | revisions
jmap/Makefile file | annotate | diff | comparison | revisions
jmap/jmmail.c file | annotate | diff | comparison | revisions
jmap/jmmail.h file | annotate | diff | comparison | revisions
libidav/Makefile file | annotate | diff | comparison | revisions
libidav/jmap.c file | annotate | diff | comparison | revisions
libidav/jmap.h file | annotate | diff | comparison | revisions
libidav/jmapsession.c file | annotate | diff | comparison | revisions
libidav/jmapsession.h file | annotate | diff | comparison | revisions
libidav/session.c file | annotate | diff | comparison | revisions
libidav/session.h file | annotate | diff | comparison | revisions
libidav/xml.h file | annotate | diff | comparison | revisions
--- a/Makefile	Tue Jul 07 21:52:33 2026 +0200
+++ b/Makefile	Wed Jul 08 15:34:41 2026 +0200
@@ -26,16 +26,19 @@
 # POSSIBILITY OF SUCH DAMAGE.
 #
 
-all: config.mk build/bin build/lib build/ucx build/dav build/libidav build/test build/tool ucx libidav dav test
+all: config.mk build/bin build/lib build/ucx build/dav build/libidav build/test build/tool ucx libidav dav jmap test
 
 ucx: FORCE
 	cd ucx; $(MAKE) all
 
 libidav: build/bin build/lib build/dav build/libidav build/tool FORCE
 	cd libidav; $(MAKE) all
-	
+
 dav: FORCE build/bin build/lib build/dav build/libidav build/tool libidav ucx
 	cd dav; $(MAKE) all
+	
+jmap: FORCE build/bin build/lib build/dav build/libidav build/tool libidav ucx
+	cd jmap; $(MAKE) all
 
 test: build/bin build/lib build/dav build/libidav build/test FORCE dav
 	cd test; $(MAKE) all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmap/Makefile	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,50 @@
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2018 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.
+#
+
+include ../config.mk
+
+JMMAIL_SRC  = jmmail.c
+
+JMMAIL_OBJ = $(JMMAIL_SRC:%.c=../build/tool/%$(OBJ_EXT))
+
+JMMAIL_BIN = ../build/bin/jmmail$(APP_EXT)
+
+all: $(JMMAIL_BIN)
+
+$(JMMAIL_BIN): $(JMMAIL_OBJ) ../build/lib/libidav$(LIB_EXT)
+	$(CC) -o $(JMMAIL_BIN) $(JMMAIL_OBJ) \
+		../build/lib/libidav$(LIB_EXT) ../build/lib/libucx$(LIB_EXT)  \
+		$(LDFLAGS) $(DAV_LDFLAGS)
+
+../build/tool/%$(OBJ_EXT): %.c 
+	$(CC) -I../ucx -I../ $(CFLAGS) $(DAV_CFLAGS) -c -o $@ $<
+
+../build/lib/libidav$(LIB_EXT):
+	test -f '$@'
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmap/jmmail.c	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#include "jmmail.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/wait.h>
+#include <unistd.h>
+#endif
+#include <cx/string.h>
+#include <cx/printf.h>
+#include <cx/hash_map.h>
+#include <cx/linked_list.h>
+#include <cx/streams.h>
+
+int jmap_main(int argc, char **argv);
+
+#ifdef _WIN32
+
+#define strcasecmp _stricmp
+
+static char* wchar2utf8(const wchar_t *wstr, size_t wlen) {
+    size_t maxlen = wlen * 4;
+    char *ret = malloc(maxlen + 1);
+    int ret_len = WideCharToMultiByte(
+        CP_UTF8,
+        0,
+        wstr,
+        wlen,
+        ret,
+        maxlen,
+        NULL,
+        NULL);
+    ret[ret_len] = 0;
+    return ret;
+}
+
+int wmain(int argc, wchar_t **argv) {
+    char **argv_utf8 = calloc(argc, sizeof(char*));
+    for(int i=0;i<argc;i++) {
+        argv_utf8[i] = wchar2utf8(argv[i], wcslen(argv[i]));
+    }
+    
+    int ret = jmap_main(argc, argv_utf8);
+    
+
+    for(int i=0;i<argc;i++) {
+        free(argv_utf8[i]);
+    }
+    free(argv_utf8);
+    
+    return ret;
+}
+#else
+int main(int argc, char **argv) {
+    return jmap_main(argc, argv);
+}
+#endif
+
+
+int jmap_main(int argc, char **argv) {
+    if(argc < 4) {
+        fprintf(stderr, "Missing args\n");
+        //print_usage(argv[0]);
+        return -1;
+    }
+    
+    putenv("LC_TIME=C");
+    
+    const char *session_url = argv[1];
+    const char *user = argv[2];
+    const char *password = argv[3];
+    
+    JMAPSession *sn = jmap_session_new_with_user(session_url, user, password);
+    
+    
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmap/jmmail.h	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef JMMAIL_H
+#define JMMAIL_H
+
+#include <libidav/jmap.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JMMAIL_H */
+
--- a/libidav/Makefile	Tue Jul 07 21:52:33 2026 +0200
+++ b/libidav/Makefile	Wed Jul 08 15:34:41 2026 +0200
@@ -41,6 +41,8 @@
 SRC += versioning.c
 SRC += config.c
 SRC += pwdstore.c
+SRC += jmap.c
+SRC += jmapsession.c
 
 OBJ = $(SRC:%.c=../build/libidav/%$(OBJ_EXT))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libidav/jmap.c	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#include "jmap.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libidav/jmap.h	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef JMAP_H
+#define JMAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <cx/map.h>
+#include <cx/json.h>
+#include <cx/mempool.h>
+#include <curl/curl.h>
+    
+typedef struct JMAPSession JMAPSession;
+
+struct JMAPSession {
+    CURL *handle;
+    CxMempool *mp;
+    
+    CxJsonValue *obj;
+    
+    char *username;
+    char *apiUrl;
+    char *downloadUrl;
+    char *uploadUrl;
+    char *eventSourceUrl;
+};
+
+JMAPSession* jmap_session_new_with_user(const char *session_url, const char *user, const char *password);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JMAP_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libidav/jmapsession.c	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+#include "jmapsession.h"
+#include "session.h"
+
+#include <cx/buffer.h>
+
+static void jm_session_curl_destructor(CURL *handle) {
+    curl_easy_cleanup(handle);
+}
+
+JMAPSession* jmap_session_new_with_user(const char *session_url, const char *user, const char *password) {
+    CURL *handle = curl_easy_init();
+    if(!handle) {
+        return NULL;
+    }
+    curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
+    
+    if(user && password) {
+        if(jm_session_set_auth(handle, user, password)) {
+            curl_easy_cleanup(handle);
+            return NULL;
+        }
+    }
+    
+    CxMempool *mp = cxMempoolCreate(256, CX_MEMPOOL_TYPE_SIMPLE);
+    if(!mp) {
+        curl_easy_cleanup(handle);
+        return NULL;
+    }
+    cxMempoolRegister(mp, handle, (cx_destructor_func)jm_session_curl_destructor);
+    
+    JMAPSession *sn = cxZalloc(mp->allocator, sizeof(JMAPSession));
+    if(!sn) {
+        cxMempoolFree(mp);
+        return NULL;
+    }
+    
+    sn->handle = handle;
+    sn->mp = mp;
+    
+    CxJsonValue *sessionValue = jm_query_session(sn, session_url);
+    if(!sessionValue) {
+        cxMempoolFree(mp);
+        return NULL;
+    }
+    sn->obj = sessionValue;
+    
+    CxJsonValue *username = cxJsonObjGet(sessionValue, "username");
+    CxJsonValue *apiUrl = cxJsonObjGet(sessionValue, "apiUrl");
+    CxJsonValue *downloadUrl = cxJsonObjGet(sessionValue, "downloadUrl");
+    CxJsonValue *uploadUrl = cxJsonObjGet(sessionValue, "uploadUrl");
+    
+    if(cxJsonIsString(username)) {
+        sn->username = cx_strdup_a(mp->allocator, username->string.ptr).ptr;
+    }
+    if(cxJsonIsString(apiUrl)) {
+        sn->apiUrl = cx_strdup_a(mp->allocator, apiUrl->string.ptr).ptr;
+    }
+    if(cxJsonIsString(downloadUrl)) {
+        sn->downloadUrl = cx_strdup_a(mp->allocator, downloadUrl->string.ptr).ptr;
+    }
+    if(cxJsonIsString(uploadUrl)) {
+        sn->uploadUrl = cx_strdup_a(mp->allocator, uploadUrl->string.ptr).ptr;
+    }
+    
+    return sn;
+}
+
+int jm_session_set_auth(CURL *handle, const char *user, const char *password) {
+    return dav_curl_set_auth(handle, cx_str(user), cx_str(password));
+}
+
+CxJsonValue* jm_query_session(JMAPSession *sn, const char *url) {
+    curl_easy_setopt(sn->handle, CURLOPT_URL, url);
+    
+    CxBuffer *response = cxBufferCreate(NULL, NULL, 1024, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS);
+    if(!response) {
+        return NULL;
+    }
+    
+    curl_easy_setopt(sn->handle, CURLOPT_WRITEFUNCTION, cxBufferWrite);
+    curl_easy_setopt(sn->handle, CURLOPT_WRITEDATA, response);
+    
+    CxJsonValue *json = NULL;
+    CURLcode ret = curl_easy_perform(sn->handle);
+    long http_status;
+    curl_easy_getinfo(sn->handle, CURLINFO_RESPONSE_CODE, &http_status);
+    if(ret == CURLE_OK) {
+        if(http_status >= 200 && http_status <= 299) {
+            (void)cx_json_from_string(sn->mp->allocator, cx_strn(response->space, response->size), &json);
+        }
+    }
+    cxBufferFree(response);
+    
+    return json;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libidav/jmapsession.h	Wed Jul 08 15:34:41 2026 +0200
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+#ifndef JMAPSESSION_H
+#define JMAPSESSION_H
+
+#include "jmap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int jm_session_set_auth(CURL *handle, const char *user, const char *password);
+
+CxJsonValue* jm_query_session(JMAPSession *sn, const char *url);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JMAPSESSION_H */
+
--- a/libidav/session.c	Tue Jul 07 21:52:33 2026 +0200
+++ b/libidav/session.c	Wed Jul 08 15:34:41 2026 +0200
@@ -162,13 +162,22 @@
 }
 
 void dav_session_set_auth_s(DavSession *sn, cxstring user, cxstring password) {
+    dav_curl_set_auth(sn->handle, user, password);
+}
+
+int dav_curl_set_auth(CURL *handle, cxstring user, cxstring password) {
     if(user.length > 0 && password.length > 0) {
         size_t upwdlen = user.length + password.length + 2;
         char *upwdbuf = malloc(upwdlen);
+        if(!upwdbuf) {
+            return 1;
+        }
         snprintf(upwdbuf, upwdlen, "%.*s:%.*s", (int)user.length, user.ptr, (int)password.length, password.ptr);
-        curl_easy_setopt(sn->handle, CURLOPT_USERPWD, upwdbuf);
+        curl_easy_setopt(handle, CURLOPT_USERPWD, upwdbuf);
         free(upwdbuf);
+        return 0;
     }
+    return -1;
 }
 
 void dav_session_set_baseurl(DavSession *sn, const char *base_url) {
--- a/libidav/session.h	Tue Jul 07 21:52:33 2026 +0200
+++ b/libidav/session.h	Wed Jul 08 15:34:41 2026 +0200
@@ -112,6 +112,8 @@
 DavLock* dav_get_lock(DavSession *sn, const char *path);
 void dav_remove_lock(DavSession *sn, const char *path, DavLock *lock);
 
+int dav_curl_set_auth(CURL *handle, cxstring user, cxstring password);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/libidav/xml.h	Tue Jul 07 21:52:33 2026 +0200
+++ b/libidav/xml.h	Wed Jul 08 15:34:41 2026 +0200
@@ -25,6 +25,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+
 #ifndef DAV_XML_H
 #define DAV_XML_H
 

mercurial