--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libidav/jmap_mail.c Fri Jul 10 17:56:21 2026 +0200 @@ -0,0 +1,121 @@ +/* + * 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_mail.h" +#include "jmap_methods.h" + +void jmap_mailbox_free(JMAPMailBox *mailbox) { + const CxAllocator *a = mailbox->session->mp->allocator; + cxFree(a, mailbox->id); + cxFree(a, mailbox->parent_id); + cxFree(a, mailbox->name); + cxFree(a, mailbox->role); + cxFree(a, mailbox); +} + +CxList* jmap_mailbox_get_list(JMAPSession *sn) { + if(!sn->primary_accounts.mail) { + return NULL; + } + const CxAllocator *a = sn->mp->allocator; + + CxBuffer *request = jm_mailbox_get_request(cx_str(sn->primary_accounts.mail)); + //printf("%.*s\n", (int)request->size, request->space); + + CxJsonValue *response = jm_do_api_request(sn, request); + cxBufferFree(request); + if(!response) { + return NULL; + } + + CxJsonValue *mailbox_list = NULL; + // check response and get mailbox response value + if(cxJsonIsObject(response)) { + CxJsonValue *method_responses = cxJsonObjGet(response, "methodResponses"); + if(cxJsonIsArray(method_responses) && method_responses->array.size > 0) { + CxJsonValue *method_response0 = method_responses->array.data[0]; + if(cxJsonIsArray(method_response0) && method_response0->array.size > 1) { + CxJsonValue *method = method_response0->array.data[0]; + if(cxJsonIsString(method) && !cx_strcmp(method->string, "Mailbox/get")) { + CxJsonValue *mailbox_response_obj = method_response0->array.data[1]; + if(cxJsonIsObject(mailbox_response_obj)) { + mailbox_list = cxJsonObjGet(mailbox_response_obj, "list"); + } + } + } + } + } + + if(!mailbox_list) { + cxJsonValueFree(response); + return NULL; + } + + CxList *list = cxArrayListCreate(a, CX_STORE_POINTERS, 16); + list->collection.simple_destructor = (cx_destructor_func)jmap_mailbox_free; + int error = 0; + for(size_t i=0;i<mailbox_list->array.size;i++) { + CxJsonValue *mailbox = mailbox_list->array.data[i]; + if(!cxJsonIsObject(mailbox)) { + error = 1; + break; + } + + CxJsonValue *id = cxJsonObjGet(mailbox, "id"); + CxJsonValue *name = cxJsonObjGet(mailbox, "name"); + CxJsonValue *parent_id = cxJsonObjGet(mailbox, "parentId"); + CxJsonValue *role = cxJsonObjGet(mailbox, "role"); + + if(!cxJsonIsString(id)) { + error = 1; + break; + } + + JMAPMailBox *mbox = cxZalloc(a, sizeof(JMAPMailBox)); + mbox->id = cx_strdup_a(a, id->string).ptr; + if(cxJsonIsString(name)) { + mbox->name = cx_strdup_a(a, name->string).ptr; + } + if(cxJsonIsString(parent_id)) { + mbox->parent_id = cx_strdup_a(a, parent_id->string).ptr; + } + if(cxJsonIsString(role)) { + mbox->role = cx_strdup_a(a, role->string).ptr; + } + + cxListAdd(list, mbox); + } + + cxJsonValueFree(response); + if(error) { + cxListFree(list); + return NULL; + } else { + return list; + } +}