UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2018 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 WEBDAV_H 30 #define WEBDAV_H 31 32 #include <inttypes.h> 33 #include <stdbool.h> 34 #include <cx/map.h> 35 #include <cx/mempool.h> 36 #include <cx/linked_list.h> 37 #include <cx/string.h> 38 #include <cx/buffer.h> 39 #include <curl/curl.h> 40 #include <libxml/tree.h> 41 42 #ifndef _WIN32 43 #include <pthread.h> 44 #else 45 #include <Windows.h> 46 #endif 47 48 #ifdef __cplusplus 49 extern "C" { 50 #endif 51 52 typedef char DavBool; 53 #ifndef TRUE 54 #define TRUE 1 55 #endif 56 #ifndef FALSE 57 #define FALSE 0 58 #endif 59 60 typedef struct DavContext DavContext; 61 typedef struct DavProxy DavProxy; 62 typedef struct DavSession DavSession; 63 typedef struct DavResource DavResource; 64 typedef struct DavResult DavResult; 65 typedef struct DavNamespace DavNamespace; 66 typedef struct DavProperty DavProperty; 67 typedef struct DavPropName DavPropName; 68 typedef struct DavKey DavKey; 69 typedef struct DavNSInfo DavNSInfo; 70 typedef struct DavXmlNode DavXmlNode; 71 typedef struct DavXmlAttr DavXmlAttr; 72 73 typedef struct DavInputStream DavInputStream; 74 typedef struct DavOutputStream DavOutputStream; 75 76 #ifndef _WIN32 77 #define DAV_MUTEX pthread_mutex_t 78 #else 79 #define DAV_MUTEX HANDLE 80 #endif 81 82 typedef size_t(*dav_read_func)(void*, size_t, size_t, void*); 83 typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*); 84 typedef int(*dav_seek_func)(const void *, long, int); 85 86 typedef int(*dav_auth_func)(DavSession *, void *); 87 typedef void(*dav_progress_func)(DavResource *, int64_t, int64_t, void *); 88 89 90 typedef void(*dav_rqlog_func)( 91 DavSession *sn, 92 const char *method, 93 const char *url, 94 const char *request_body, 95 size_t request_bodylen, 96 int status, 97 const char *response_body, 98 size_t response_bodylen); 99 100 enum DavError { 101 DAV_OK = 0, 102 DAV_ERROR, 103 DAV_NOT_FOUND, 104 DAV_UNAUTHORIZED, 105 DAV_FORBIDDEN, 106 DAV_METHOD_NOT_ALLOWED, 107 DAV_CONFLICT, 108 DAV_LOCKED, 109 DAV_UNSUPPORTED_PROTOCOL, 110 DAV_COULDNT_RESOLVE_PROXY, 111 DAV_COULDNT_RESOLVE_HOST, 112 DAV_COULDNT_CONNECT, 113 DAV_TIMEOUT, 114 DAV_SSL_ERROR, 115 DAV_QL_ERROR, 116 DAV_CONTENT_VERIFICATION_ERROR, 117 DAV_PRECONDITION_FAILED, 118 DAV_REQUEST_ENTITY_TOO_LARGE, 119 DAV_REQUEST_URL_TOO_LONG, 120 DAV_PROXY_AUTH_REQUIRED, 121 DAV_NET_AUTH_REQUIRED 122 }; 123 124 typedef enum DavError DavError; 125 126 enum DavXmlNodeType { 127 DAV_XML_NONE = 0, 128 DAV_XML_ELEMENT, 129 DAV_XML_TEXT 130 }; 131 132 typedef enum DavXmlNodeType DavXmlNodeType; 133 134 #define DAV_SESSION_ENCRYPT_CONTENT 0x0001 135 #define DAV_SESSION_ENCRYPT_NAME 0x0002 136 #define DAV_SESSION_ENCRYPT_PROPERTIES 0x0004 137 #define DAV_SESSION_DECRYPT_CONTENT 0x0008 138 #define DAV_SESSION_DECRYPT_NAME 0x0010 139 #define DAV_SESSION_DECRYPT_PROPERTIES 0x0020 140 #define DAV_SESSION_STORE_HASH 0x0040 141 142 #define DAV_SESSION_CONTENT_ENCRYPTION 0x0009 143 #define DAV_SESSION_FULL_ENCRYPTION 0x003f 144 145 146 #define DAV_NS "http://davutils.org/" 147 #define DAV_PROPS_NS "http://davutils.org/props/" 148 149 struct DavNamespace { 150 char *prefix; 151 char *name; 152 }; 153 154 struct DavResource { 155 DavSession *session; 156 DavResource *prev; 157 DavResource *next; 158 DavResource *parent; 159 DavResource *children; 160 char *name; 161 char *path; 162 char *href; 163 uint64_t contentlength; 164 char *contenttype; 165 time_t creationdate; 166 time_t lastmodified; 167 void *data; 168 int iscollection; 169 int exists; 170 }; 171 172 struct DavSession { 173 DavContext *context; 174 CURL *handle; 175 char *base_url; 176 CxMempool *mp; 177 CxMap *pathcache; 178 DavKey *key; 179 void *locks; 180 uint32_t flags; 181 DavError error; 182 char *errorstr; 183 184 int(*auth_prompt)(DavSession *sn, void *userdata); 185 void *authprompt_userdata; 186 187 dav_rqlog_func logfunc; 188 189 void(*get_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); 190 void(*put_progress)(DavResource *res, int64_t total, int64_t now, void *userdata); 191 void *progress_userdata; 192 }; 193 194 struct DavContext { 195 CxMap *namespaces; 196 CxMap *namespaceinfo; 197 CxMap *keys; 198 CxList *sessions; 199 DavProxy *http_proxy; 200 DavProxy *https_proxy; 201 DAV_MUTEX mutex; 202 DavBool mtsafe; 203 }; 204 205 struct DavProxy { 206 char *url; 207 char *username; 208 char *password; 209 char *no_proxy; 210 }; 211 212 struct DavProperty { 213 DavNamespace *ns; 214 char *name; 215 DavXmlNode *value; 216 }; 217 218 struct DavPropName { 219 char *ns; 220 char *name; 221 }; 222 223 struct DavResult { 224 DavResource *result; 225 int status; 226 }; 227 228 #define DAV_KEY_AES128 0 229 #define DAV_KEY_AES256 1 230 231 struct DavKey { 232 char *name; 233 int type; 234 void *data; 235 size_t length; 236 }; 237 238 struct DavNSInfo { 239 char *prefix; 240 DavBool encrypt; 241 }; 242 243 struct DavXmlNode { 244 DavXmlNodeType type; 245 246 char *namespace; 247 char *name; 248 249 DavXmlNode *prev; 250 DavXmlNode *next; 251 DavXmlNode *children; 252 DavXmlNode *parent; 253 254 DavXmlAttr *attributes; 255 256 char *content; 257 size_t contentlength; 258 }; 259 260 struct DavXmlAttr { 261 char *name; 262 char *value; 263 DavXmlAttr *next; 264 }; 265 266 DavContext* dav_context_new(void); 267 void dav_context_destroy(DavContext *ctx); 268 void dav_context_set_mtsafe(DavContext *ctx, DavBool enable); 269 270 void dav_context_lock(DavContext *ctx); 271 void dav_context_unlock(DavContext *ctx); 272 273 void dav_context_add_key(DavContext *context, DavKey *key); 274 DavKey* dav_context_get_key(DavContext *context, const char *name); 275 276 int dav_add_namespace(DavContext *context, const char *prefix, const char *ns); 277 DavNamespace* dav_get_namespace(DavContext *context, const char *prefix); 278 DavNamespace* dav_get_namespace_s(DavContext *context, cxstring prefix); 279 280 int dav_enable_namespace_encryption(DavContext *context, const char *ns, DavBool encrypt); 281 int dav_namespace_is_encrypted(DavContext *context, const char *ns); 282 283 int dav_context_add_session(DavContext *context, DavSession *sn); 284 int dav_context_remove_session(DavContext *context, DavSession *sn); 285 286 DavSession* dav_session_new(DavContext *context, char *base_url); 287 DavSession* dav_session_new_auth( 288 DavContext *context, 289 char *base_url, 290 char *user, 291 char *password); 292 DavSession* dav_session_clone(DavSession *sn); 293 void dav_session_set_auth(DavSession *sn, const char *user, const char *password); 294 void dav_session_set_auth_s(DavSession *sn, cxstring user, cxstring password); 295 void dav_session_set_baseurl(DavSession *sn, char *base_url); 296 void dav_session_enable_encryption(DavSession *sn, DavKey *key, int flags); 297 298 void dav_session_set_authcallback(DavSession *sn, dav_auth_func func, void *userdata); 299 void dav_session_set_progresscallback(DavSession *sn, dav_progress_func get, dav_progress_func put, void *userdata); 300 301 void dav_session_destroy(DavSession *sn); 302 303 void dav_session_destructor(DavSession *sn); 304 305 void* dav_session_malloc(DavSession *sn, size_t size); 306 void* dav_session_calloc(DavSession *sn, size_t nelm, size_t size); 307 void* dav_session_realloc(DavSession *sn, void *ptr, size_t size); 308 void dav_session_free(DavSession *sn, void *ptr); 309 char* dav_session_strdup(DavSession *sn, const char *str); 310 311 void dav_set_effective_href(DavSession *sn, DavResource *resource); 312 DavResource* dav_get(DavSession *sn, char *path, const char *properties); 313 314 CxList* parse_properties_string(DavContext *context, cxstring str); 315 316 DavResource* dav_query(DavSession *sn, char *query, ...); 317 318 cxmutstr dav_property_key(const char *ns, const char *name); 319 void dav_get_property_namespace_str( 320 DavContext *ctx, 321 char *prefixed_name, 322 char **ns, 323 char **name); 324 DavNamespace* dav_get_property_namespace( 325 DavContext *ctx, 326 char *prefixed_name, 327 char **name); 328 329 /* ------------------------ resource functions ------------------------ */ 330 331 DavResource* dav_resource_new(DavSession *sn, const char *path); 332 DavResource* dav_resource_new_child(DavSession *sn, DavResource *parent, const char *name); 333 DavResource* dav_resource_new_href(DavSession *sn, const char *href); 334 335 void dav_resource_free(DavResource *res); 336 void dav_resource_free_all(DavResource *res); 337 338 char* dav_resource_get_href(DavResource *resource); 339 340 DavResource* dav_create_child(DavResource *parent, char *name); 341 int dav_delete(DavResource *res); 342 int dav_create(DavResource *res); 343 int dav_exists(DavResource *res); 344 345 int dav_copy(DavResource *res, char *newpath); 346 int dav_move(DavResource *res, char *newpath); 347 int dav_copy_o(DavResource *res, char *newpath, DavBool override); 348 int dav_move_o(DavResource *res, char *newpath, DavBool override); 349 int dav_copyto(DavResource *res, char *url, DavBool override); 350 int dav_moveto(DavResource *res, char *url, DavBool override); 351 352 int dav_lock(DavResource *res); 353 int dav_lock_t(DavResource *res, time_t timeout); 354 int dav_unlock(DavResource *res); 355 356 DavXmlNode* dav_get_property(DavResource *res, char *name); 357 DavXmlNode* dav_get_property_ns(DavResource *res, const char *ns, const char *name); 358 DavXmlNode* dav_get_encrypted_property_ns(DavResource *res, const char *ns, const char *name); 359 char* dav_get_string_property(DavResource *res, char *name); 360 char* dav_get_string_property_ns(DavResource *res, char *ns, char *name); 361 int dav_set_string_property(DavResource *res, char *name, char *value); 362 void dav_set_string_property_ns(DavResource *res, char *ns, char *name, char *value); 363 void dav_set_property(DavResource *res, char *name, DavXmlNode *value); 364 void dav_set_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); 365 void dav_remove_property(DavResource *res, char *name); 366 void dav_remove_property_ns(DavResource *res, char *ns, char *name); 367 void dav_set_encrypted_property_ns(DavResource *res, char *ns, char *name, DavXmlNode *value); 368 void dav_set_encrypted_string_property_ns(DavResource *res, char *ns, char *name, char *value); 369 void dav_remove_encrypted_property_ns(DavResource *res, char *ns, char *name); 370 371 DavPropName* dav_get_property_names(DavResource *res, size_t *count); 372 373 void dav_set_content(DavResource *res, void *stream, dav_read_func read_func, dav_seek_func seek_func); 374 void dav_set_content_data(DavResource *res, char *content, size_t length); 375 void dav_set_content_length(DavResource *res, size_t length); 376 377 int dav_load(DavResource *res); 378 int dav_load_prop(DavResource *res, DavPropName *properties, size_t numprop); 379 int dav_store(DavResource *res); 380 int dav_get_content(DavResource *res, void *stream, dav_write_func write_func); 381 382 DavInputStream* dav_inputstream_open(DavResource *res); 383 size_t dav_read(void *buf, size_t size, size_t nitems, DavInputStream *in); 384 void dav_inputstream_close(DavInputStream *in); 385 386 DavOutputStream* dav_outputstream_open(DavResource *res); 387 size_t dav_write(const void *buf, size_t size, size_t nitems, DavOutputStream *out); 388 int dav_outputstream_close(DavOutputStream *out); 389 390 void dav_verbose_log( 391 DavSession *sn, 392 const char *method, 393 const char *url, 394 const char *request_body, 395 size_t request_bodylen, 396 int status, 397 const char *response_body, 398 size_t response_bodylen); 399 400 // private 401 int dav_propfind(DavSession *sn, DavResource *root, CxBuffer *rqbuf); 402 403 404 /* --------------------------- DeltaV ---------------------------- */ 405 406 int dav_versioncontrol(DavResource *res); 407 int dav_checkout(DavResource *res); 408 int dav_checkin(DavResource *res); 409 int dav_uncheckout(DavResource *res); 410 DavResource* dav_versiontree(DavResource *res, char *properties); 411 412 /* ------------------------ xml functions ------------------------ */ 413 char* dav_xml_getstring(DavXmlNode *node); 414 DavBool dav_xml_isstring(DavXmlNode *node); 415 DavXmlNode* dav_xml_nextelm(DavXmlNode *node); 416 DavXmlNode* dav_text_node(DavSession *sn, const char *text); 417 DavXmlNode* dav_text_element(DavSession *sn, const char *ns, const char *name, const char *text); 418 419 DavXmlNode* dav_copy_node(DavXmlNode *node); 420 421 void dav_free_xml_node_sn(DavSession *sn, DavXmlNode *node); 422 void dav_free_xml_node(DavXmlNode *node); 423 424 DavXmlNode* dav_xml_createnode(const char *ns, const char *name); 425 DavXmlNode* dav_xml_createnode_with_text(const char *ns, const char *name, const char *text); 426 DavXmlNode* dav_xml_createtextnode(const char *text); 427 void dav_xml_add_child(DavXmlNode *node, DavXmlNode *child); 428 void dav_xml_add_attr(DavXmlNode *node, const char *name, const char *value); 429 char* dav_xml_get_attr(DavXmlNode *node, const char *name); 430 431 DavXmlNode* dav_parse_xml(DavSession *sn, const char *str, size_t len); 432 433 #ifdef __cplusplus 434 } 435 #endif 436 437 #endif /* WEBDAV_H */ 438 439