Sun, 19 Mar 2023 16:48:19 +0100
implement webdav xattr namespace lists
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2020 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 WS_WEBDAV_H #define WS_WEBDAV_H #include "nsapi.h" #include "vfs.h" #include <sys/file.h> #include <sys/stat.h> #include <inttypes.h> #ifdef __cplusplus extern "C" { #endif typedef struct WebdavBackend WebdavBackend; typedef struct WebdavProperty WebdavProperty; typedef struct WebdavPList WebdavPList; typedef struct WebdavNSList WebdavNSList; typedef struct WebdavPListIterator WebdavPListIterator; typedef enum WebdavLockScope WebdavLockScope; typedef enum WebdavLockType WebdavLockType; typedef enum WebdavValueType WebdavValueType; typedef struct WebdavPropfindRequest WebdavPropfindRequest; typedef struct WebdavProppatchRequest WebdavProppatchRequest; typedef struct WebdavLockRequest WebdavLockRequest; typedef struct WebdavVFSRequest WebdavVFSRequest; typedef struct WebdavResponse WebdavResponse; typedef struct WebdavResource WebdavResource; typedef struct WebdavVFSProperties WebdavVFSProperties; typedef struct WebdavOperation WebdavOperation; typedef struct WSXmlData WSXmlData; typedef struct WSText WSText; typedef struct _xmlNs WSNamespace; typedef struct _xmlNode WSXmlNode; #define WS_NODE_ELEMENT 1 #define WS_NODE_TEXT 3 #define WS_NODE_CDATA 4 #define WS_NODE_ENTITY_REF 5 typedef int(*wsxml_func)(WSXmlNode *, void *); /* propfind settings */ /* * Use the vfs to stat files or read the directory children */ #define WS_WEBDAV_PROPFIND_USE_VFS 0x01 /* * Use the vfs to open a file for proppatch */ #define WS_WEBDAV_PROPPATCH_USE_VFS 0x02 typedef void*(*webdav_init_func)(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config); typedef WebdavBackend*(*webdav_create_func)(Session *sn, Request *rq, pblock *pb, void *initData); enum WebdavValueType { WS_VALUE_NO_TYPE = 0, WS_VALUE_XML_NODE, WS_VALUE_XML_DATA, WS_VALUE_TEXT }; struct WSText { char *str; size_t length; }; struct WSXmlData { WebdavNSList *namespaces; char *data; size_t length; }; struct WebdavProperty { WSNamespace *namespace; const char *name; char *lang; union { WSXmlNode *node; WSXmlData data; WSText text; } value; WebdavValueType vtype; }; struct WebdavPList { WebdavProperty *property; WebdavPList *prev; WebdavPList *next; }; struct WebdavNSList { WSNamespace *namespace; WebdavNSList *prev; WebdavNSList *next; }; struct WebdavPListIterator { WebdavPList **list; WebdavPList *cur; WebdavPList *next; size_t index; }; enum WebdavLockScope { WEBDAV_LOCK_EXCLUSIVE = 0, WEBDAV_LOCK_SHARED, WEBDAV_LOCK_SCOPE_UNKNOWN }; enum WebdavLockType { WEBDAV_LOCK_WRITE = 0, WEBDAV_LOCK_TYPE_UNKNOWN }; struct WebdavPropfindRequest { Session *sn; Request *rq; WebdavBackend *dav; void *doc; /* * list of requested properties */ WebdavPList *properties; /* * number of properties */ size_t propcount; WSBool allprop; WSBool propname; WSBool deadproperties; int depth; /* * custom userdata for the backend */ void *userdata; }; struct WebdavProppatchRequest { Session *sn; Request *rq; WebdavBackend *dav; void *doc; WebdavPList *set; size_t setcount; WebdavPList *remove; size_t removecount; /* * custom userdata for the backend */ void *userdata; }; struct WebdavVFSRequest { Session *sn; Request *rq; char *path; /* * custom userdata for the backend */ void *userdata; }; struct WebdavLockRequest { Session *sn; Request *rq; void *doc; WebdavLockScope scope; WebdavLockType type; WSXmlNode *owner; }; struct WebdavVFSProperties { uint32_t getcontentlength:1; uint32_t getlastmodified:1; uint32_t getresourcetype:1; uint32_t getetag:1; uint32_t creationdate:1; }; struct WebdavResponse { WebdavOperation *op; WebdavResource* (*addresource)(WebdavResponse*, const char*); }; struct WebdavResource { char *href; WSBool isclosed; int err; /* * int addprop(WebdavResource *res, WebdavProperty *property, int status); * * Adds a property to the resource */ int (*addproperty)(WebdavResource*, WebdavProperty*, int); /* * int close(WebdavResource *res); * * Closes a resource object */ int (*close)(WebdavResource*); }; struct WebdavBackend { /* * int propfind_init( * WebdavPropfindRequest *rq, * const char *path, * const char *href, * WebdavPList **outplist); * * Initializes a propfind request. This is called once for each propfind * request and should initialize everything needed for generating the * multistatus response. * */ int (*propfind_init)(WebdavPropfindRequest *, const char *, const char *, WebdavPList **); /* * int propfind_do( * WebdavPropfindRequest *rq, * WebdavResponse *response, * VFS_DIR parent, * WebdavResource *resource, * struct stat *s); * * This function is called for the requsted resource and for all children * if WS_PROPFIND_NO_VFS_CHILDREN is not set. */ int (*propfind_do)( WebdavPropfindRequest *, WebdavResponse *, VFS_DIR, WebdavResource *, struct stat *); /* * int propfind_finish(WebdavPropfindRequest *rq); * * Finishes a propfind request. */ int (*propfind_finish)(WebdavPropfindRequest *); /* * int proppatch_do( * WebdavProppatchRequest *request, * WebdavResource *response, * VFSFile *file, * WebdavPList **out_set, * WebdavPList **out_remove); * * Modifies properties of the requsted resource. */ int (*proppatch_do)( WebdavProppatchRequest *, WebdavResource *, VFSFile *, WebdavPList **, WebdavPList **); /* * int proppatch_finish( * WebdavProppatchRequest *request, * WebdavResource *response, * VFSFile *file, * WSBool commit); * * Called after all proppatch_do functions of all backends are executed * and should either permanently store the properties (commit == true) or * revert all changed (commit == false). */ int (*proppatch_finish)( WebdavProppatchRequest *, WebdavResource *, VFSFile *, WSBool); /* * int opt_mkcol(WebdavVFSRequest *request, WSBool *out_created); * * Optional mkcol callback that is called before vfs_mkdir. If the function * sets out_created to TRUE, vfs_mkdir will not be executed. */ int (*opt_mkcol)(WebdavVFSRequest *, WSBool *); /* * int opt_mkcol_finish(WebdavVFSRequest *request, WSBool success); * * Optional callback for finishing a MKCOL request. */ int(*opt_mkcol_finish)(WebdavVFSRequest *, WSBool); /* * int opt_delete(WebdavVFSRequest *request, WSBool *out_deleted); * * Optional delete callback that is called once before any VFS deletions. * When the callback sets out_deleted to TRUE, no VFS unlink operations * will be done. * */ int (*opt_delete)(WebdavVFSRequest *, WSBool *); /* * int opt_delete_finish(WebdavVFSRequest *request, WSBool success); * * Optional callback for finishing a DELETE request. */ int (*opt_delete_finish)(WebdavVFSRequest *, WSBool); /* * See the WS_WEBDAV_* macros for informations about the settings */ uint32_t settings; /* * private instance data */ void *instance; /* * next Backend */ WebdavBackend *next; }; /* * register a webdav backend */ int webdav_register_backend(const char *name, webdav_init_func webdavInit, webdav_create_func webdavCreate); WebdavBackend* webdav_create(Session *sn, Request *rq, const char *dav_class, pblock *pb, void *initData); /* * gets the requested depth * * in case of infinity, -1 is returned * if no depth is specified, 0 is returned */ int webdav_getdepth(Request *rq); int webdav_plist_add( pool_handle_t *pool, WebdavPList **begin, WebdavPList **end, WebdavProperty *prop); WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list); WebdavPList* webdav_plist_clone_s( pool_handle_t *pool, WebdavPList *list, size_t *newlen); size_t webdav_plist_size(WebdavPList *list); int webdav_nslist_add( pool_handle_t *pool, WebdavNSList **begin, WebdavNSList **end, WSNamespace *ns); WebdavPListIterator webdav_plist_iterator(WebdavPList **list); int webdav_plist_iterator_next(WebdavPListIterator *i, WebdavPList **cur); void webdav_plist_iterator_remove_current(WebdavPListIterator *i); WSNamespace* webdav_dav_namespace(void); WebdavProperty* webdav_resourcetype_collection(void); WebdavProperty* webdav_resourcetype_empty(void); WebdavProperty* webdav_dav_property( pool_handle_t *pool, const char *name); int webdav_resource_add_dav_stringproperty( WebdavResource *res, pool_handle_t pool, const char *name, const char *str, size_t len); int webdav_resource_add_stringproperty( WebdavResource *res, pool_handle_t pool, const char *xmlns_prefix, const char *xmlns_href, const char *name, const char *str, size_t len); int webdav_property_set_value( WebdavProperty *property, pool_handle_t *pool, char *value); WebdavVFSProperties webdav_vfs_properties( WebdavPList **plistInOut, WSBool removefromlist, WSBool appprop, uint32_t flags); int webdav_add_vfs_properties( WebdavResource *res, pool_handle_t *pool, WebdavVFSProperties properties, struct stat *s); int wsxml_iterator( pool_handle_t *pool, WSXmlNode *node, wsxml_func begincb, wsxml_func endcb, void *udata); WebdavNSList* wsxml_get_required_namespaces( pool_handle_t *pool, WSXmlNode *node, int *error); WSXmlData* wsxml_node2data( pool_handle_t *pool, WSXmlNode *node); /* * converts a property list to a string * * namespaces are separated by a newline character and have the format: * <prefix>:<href> */ char* wsxml_nslist2string(pool_handle_t *pool, WebdavNSList *nslist); /* * converts a namespace list string (created by wsxml_nslist2string) to * a WebdavNSList object */ WebdavNSList* wsxml_string2nslist(pool_handle_t *pool, char *nsliststr); #ifdef __cplusplus } #endif #endif /* WS_WEBDAV_H */