UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2020 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef WS_WEBDAV_H 30 #define WS_WEBDAV_H 31 32 #include "nsapi.h" 33 #include "vfs.h" 34 35 #include <sys/file.h> 36 #include <sys/stat.h> 37 #include <inttypes.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 typedef struct WebdavBackend WebdavBackend; 44 45 typedef struct WebdavProperty WebdavProperty; 46 typedef struct WebdavPList WebdavPList; 47 typedef struct WebdavNSList WebdavNSList; 48 49 typedef struct WebdavPListIterator WebdavPListIterator; 50 51 typedef enum WebdavLockScope WebdavLockScope; 52 typedef enum WebdavLockType WebdavLockType; 53 54 typedef enum WebdavValueType WebdavValueType; 55 56 typedef struct WebdavPropfindRequest WebdavPropfindRequest; 57 typedef struct WebdavProppatchRequest WebdavProppatchRequest; 58 typedef struct WebdavLockRequest WebdavLockRequest; 59 60 typedef struct WebdavVFSRequest WebdavVFSRequest; 61 62 typedef struct WebdavResponse WebdavResponse; 63 typedef struct WebdavResource WebdavResource; 64 65 typedef struct WebdavVFSProperties WebdavVFSProperties; 66 67 typedef struct WebdavOperation WebdavOperation; 68 69 typedef struct WSXmlData WSXmlData; 70 typedef struct WSText WSText; 71 72 typedef struct _xmlNs WSNamespace; 73 typedef struct _xmlNode WSXmlNode; 74 75 #define WS_NODE_ELEMENT 1 76 #define WS_NODE_TEXT 3 77 #define WS_NODE_CDATA 4 78 #define WS_NODE_ENTITY_REF 5 79 80 typedef int(*wsxml_func)(WSXmlNode *, void *); 81 82 /* propfind settings */ 83 84 /* 85 * Use the vfs to stat files or read the directory children 86 */ 87 #define WS_WEBDAV_PROPFIND_USE_VFS 0x01 88 89 /* 90 * Use the vfs to open a file for proppatch 91 */ 92 #define WS_WEBDAV_PROPPATCH_USE_VFS 0x02 93 94 95 typedef void*(*webdav_init_func)(ServerConfiguration *cfg, pool_handle_t *pool, WSConfigNode *config); 96 typedef WebdavBackend*(*webdav_create_func)(Session *sn, Request *rq, pblock *pb, void *initData); 97 98 enum WebdavValueType { 99 WS_VALUE_NO_TYPE = 0, 100 WS_VALUE_XML_NODE, 101 WS_VALUE_XML_DATA, 102 WS_VALUE_TEXT 103 }; 104 105 struct WSText { 106 char *str; 107 size_t length; 108 }; 109 110 struct WSXmlData { 111 WebdavNSList *namespaces; 112 char *data; 113 size_t length; 114 }; 115 116 struct WebdavProperty { 117 WSNamespace *namespace; 118 119 const char *name; 120 121 char *lang; 122 123 union { 124 WSXmlNode *node; 125 WSXmlData data; 126 WSText text; 127 } value; 128 WebdavValueType vtype; 129 }; 130 131 struct WebdavPList { 132 WebdavProperty *property; 133 WebdavPList *prev; 134 WebdavPList *next; 135 }; 136 137 struct WebdavNSList { 138 WSNamespace *namespace; 139 WebdavNSList *prev; 140 WebdavNSList *next; 141 }; 142 143 struct WebdavPListIterator { 144 WebdavPList **list; 145 WebdavPList *cur; 146 WebdavPList *next; 147 size_t index; 148 }; 149 150 enum WebdavLockScope { 151 WEBDAV_LOCK_EXCLUSIVE = 0, 152 WEBDAV_LOCK_SHARED, 153 WEBDAV_LOCK_SCOPE_UNKNOWN 154 }; 155 156 enum WebdavLockType { 157 WEBDAV_LOCK_WRITE = 0, 158 WEBDAV_LOCK_TYPE_UNKNOWN 159 }; 160 161 struct WebdavPropfindRequest { 162 Session *sn; 163 Request *rq; 164 165 WebdavBackend *dav; 166 167 void *doc; 168 169 /* 170 * list of requested properties 171 */ 172 WebdavPList *properties; 173 174 /* 175 * number of properties 176 */ 177 size_t propcount; 178 179 WSBool allprop; 180 WSBool propname; 181 WSBool deadproperties; 182 183 int depth; 184 185 /* 186 * custom userdata for the backend 187 */ 188 void *userdata; 189 }; 190 191 struct WebdavProppatchRequest { 192 Session *sn; 193 Request *rq; 194 195 WebdavBackend *dav; 196 197 void *doc; 198 199 WebdavPList *set; 200 size_t setcount; 201 202 WebdavPList *remove; 203 size_t removecount; 204 205 /* 206 * custom userdata for the backend 207 */ 208 void *userdata; 209 }; 210 211 struct WebdavVFSRequest { 212 Session *sn; 213 Request *rq; 214 215 char *path; 216 217 /* 218 * custom userdata for the backend 219 */ 220 void *userdata; 221 }; 222 223 struct WebdavLockRequest { 224 Session *sn; 225 Request *rq; 226 227 void *doc; 228 229 WebdavLockScope scope; 230 WebdavLockType type; 231 232 WSXmlNode *owner; 233 }; 234 235 struct WebdavVFSProperties { 236 uint32_t getcontentlength:1; 237 uint32_t getlastmodified:1; 238 uint32_t getresourcetype:1; 239 uint32_t getetag:1; 240 uint32_t creationdate:1; 241 }; 242 243 struct WebdavResponse { 244 WebdavOperation *op; 245 246 WebdavResource* (*addresource)(WebdavResponse*, const char*); 247 }; 248 249 struct WebdavResource { 250 char *href; 251 252 WSBool isclosed; 253 254 int err; 255 256 /* 257 * int addprop(WebdavResource *res, WebdavProperty *property, int status); 258 * 259 * Adds a property to the resource 260 */ 261 int (*addproperty)(WebdavResource*, WebdavProperty*, int); 262 263 /* 264 * int close(WebdavResource *res); 265 * 266 * Closes a resource object 267 */ 268 int (*close)(WebdavResource*); 269 }; 270 271 struct WebdavBackend { 272 /* 273 * int propfind_init( 274 * WebdavPropfindRequest *rq, 275 * const char *path, 276 * const char *href, 277 * WebdavPList **outplist); 278 * 279 * Initializes a propfind request. This is called once for each propfind 280 * request and should initialize everything needed for generating the 281 * multistatus response. 282 * 283 */ 284 int (*propfind_init)(WebdavPropfindRequest *, const char *, const char *, WebdavPList **); 285 286 /* 287 * int propfind_do( 288 * WebdavPropfindRequest *rq, 289 * WebdavResponse *response, 290 * VFS_DIR parent, 291 * WebdavResource *resource, 292 * struct stat *s); 293 * 294 * This function is called for the requsted resource and for all children 295 * if WS_PROPFIND_NO_VFS_CHILDREN is not set. 296 */ 297 int (*propfind_do)( 298 WebdavPropfindRequest *, 299 WebdavResponse *, 300 VFS_DIR, 301 WebdavResource *, 302 struct stat *); 303 304 /* 305 * int propfind_finish(WebdavPropfindRequest *rq); 306 * 307 * Finishes a propfind request. 308 */ 309 int (*propfind_finish)(WebdavPropfindRequest *); 310 311 /* 312 * int proppatch_do( 313 * WebdavProppatchRequest *request, 314 * WebdavResource *response, 315 * VFSFile *file, 316 * WebdavPList **out_set, 317 * WebdavPList **out_remove); 318 * 319 * Modifies properties of the requsted resource. 320 */ 321 int (*proppatch_do)( 322 WebdavProppatchRequest *, 323 WebdavResource *, 324 VFSFile *, 325 WebdavPList **, 326 WebdavPList **); 327 328 /* 329 * int proppatch_finish( 330 * WebdavProppatchRequest *request, 331 * WebdavResource *response, 332 * VFSFile *file, 333 * WSBool commit); 334 * 335 * Called after all proppatch_do functions of all backends are executed 336 * and should either permanently store the properties (commit == true) or 337 * revert all changed (commit == false). 338 */ 339 int (*proppatch_finish)( 340 WebdavProppatchRequest *, 341 WebdavResource *, 342 VFSFile *, 343 WSBool); 344 345 /* 346 * int opt_mkcol(WebdavVFSRequest *request, WSBool *out_created); 347 * 348 * Optional mkcol callback that is called before vfs_mkdir. If the function 349 * sets out_created to TRUE, vfs_mkdir will not be executed. 350 */ 351 int (*opt_mkcol)(WebdavVFSRequest *, WSBool *); 352 353 /* 354 * int opt_mkcol_finish(WebdavVFSRequest *request, WSBool success); 355 * 356 * Optional callback for finishing a MKCOL request. 357 */ 358 int(*opt_mkcol_finish)(WebdavVFSRequest *, WSBool); 359 360 /* 361 * int opt_delete(WebdavVFSRequest *request, WSBool *out_deleted); 362 * 363 * Optional delete callback that is called once before any VFS deletions. 364 * When the callback sets out_deleted to TRUE, no VFS unlink operations 365 * will be done. 366 * 367 */ 368 int (*opt_delete)(WebdavVFSRequest *, WSBool *); 369 370 /* 371 * int opt_delete_finish(WebdavVFSRequest *request, WSBool success); 372 * 373 * Optional callback for finishing a DELETE request. 374 */ 375 int (*opt_delete_finish)(WebdavVFSRequest *, WSBool); 376 377 /* 378 * See the WS_WEBDAV_* macros for informations about the settings 379 */ 380 uint32_t settings; 381 382 /* 383 * private instance data 384 */ 385 void *instance; 386 387 /* 388 * next Backend 389 */ 390 WebdavBackend *next; 391 }; 392 393 /* 394 * register a webdav backend 395 */ 396 int webdav_register_backend(const char *name, webdav_init_func webdavInit, webdav_create_func webdavCreate); 397 398 WebdavBackend* webdav_create(Session *sn, Request *rq, const char *dav_class, pblock *pb, void *initData); 399 400 /* 401 * gets the requested depth 402 * 403 * in case of infinity, -1 is returned 404 * if no depth is specified, 0 is returned 405 */ 406 int webdav_getdepth(Request *rq); 407 408 int webdav_plist_add( 409 pool_handle_t *pool, 410 WebdavPList **begin, 411 WebdavPList **end, 412 WebdavProperty *prop); 413 414 WebdavPList* webdav_plist_clone(pool_handle_t *pool, WebdavPList *list); 415 WebdavPList* webdav_plist_clone_s( 416 pool_handle_t *pool, 417 WebdavPList *list, 418 size_t *newlen); 419 420 size_t webdav_plist_size(WebdavPList *list); 421 422 int webdav_nslist_add( 423 pool_handle_t *pool, 424 WebdavNSList **begin, 425 WebdavNSList **end, 426 WSNamespace *ns); 427 428 WebdavPListIterator webdav_plist_iterator(WebdavPList **list); 429 int webdav_plist_iterator_next(WebdavPListIterator *i, WebdavPList **cur); 430 void webdav_plist_iterator_remove_current(WebdavPListIterator *i); 431 432 WSNamespace* webdav_dav_namespace(void); 433 WebdavProperty* webdav_resourcetype_collection(void); 434 WebdavProperty* webdav_resourcetype_empty(void); 435 WebdavProperty* webdav_dav_property( 436 pool_handle_t *pool, 437 const char *name); 438 439 int webdav_resource_add_dav_stringproperty( 440 WebdavResource *res, 441 pool_handle_t pool, 442 const char *name, 443 const char *str, 444 size_t len); 445 int webdav_resource_add_stringproperty( 446 WebdavResource *res, 447 pool_handle_t pool, 448 const char *xmlns_prefix, 449 const char *xmlns_href, 450 const char *name, 451 const char *str, 452 size_t len); 453 454 int webdav_property_set_value( 455 WebdavProperty *property, 456 pool_handle_t *pool, 457 char *value); 458 459 WebdavVFSProperties webdav_vfs_properties( 460 WebdavPList **plistInOut, 461 WSBool removefromlist, 462 WSBool appprop, 463 uint32_t flags); 464 465 int webdav_add_vfs_properties( 466 WebdavResource *res, 467 pool_handle_t *pool, 468 WebdavVFSProperties properties, 469 struct stat *s); 470 471 int wsxml_iterator( 472 pool_handle_t *pool, 473 WSXmlNode *node, 474 wsxml_func begincb, 475 wsxml_func endcb, 476 void *udata); 477 478 WebdavNSList* wsxml_get_required_namespaces( 479 pool_handle_t *pool, 480 WSXmlNode *node, 481 int *error); 482 483 WSXmlData* wsxml_node2data( 484 pool_handle_t *pool, 485 WSXmlNode *node); 486 487 /* 488 * converts a property list to a string 489 * 490 * namespaces are separated by a newline character and have the format: 491 * <prefix>:<href> 492 */ 493 char* wsxml_nslist2string(pool_handle_t *pool, WebdavNSList *nslist); 494 495 /* 496 * converts a namespace list string (created by wsxml_nslist2string) to 497 * a WebdavNSList object 498 */ 499 WebdavNSList* wsxml_string2nslist(pool_handle_t *pool, char *nsliststr); 500 501 #ifdef __cplusplus 502 } 503 #endif 504 505 #endif /* WS_WEBDAV_H */ 506 507