added support for where clauses

Wed, 21 Aug 2013 13:08:22 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 21 Aug 2013 13:08:22 +0200
changeset 27
e584c351b402
parent 26
146171b57e69
child 28
4e46c65711ef

added support for where clauses

dav/davql.c file | annotate | diff | comparison | revisions
dav/davql.h file | annotate | diff | comparison | revisions
dav/main.c file | annotate | diff | comparison | revisions
dav/methods.c file | annotate | diff | comparison | revisions
dav/methods.h file | annotate | diff | comparison | revisions
dav/webdav.c file | annotate | diff | comparison | revisions
dav/webdav.h file | annotate | diff | comparison | revisions
--- a/dav/davql.c	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/davql.c	Wed Aug 21 13:08:22 2013 +0200
@@ -28,10 +28,10 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "davql.h"
 #include "methods.h"
-#include "webdav.h"
 #include "utils.h"
 
 DavQuery dav_ql_parse(char *query, va_list ap) {
@@ -102,10 +102,38 @@
         }
     }
     
+    // condition
+    DavQOp *condition = NULL;
+    size_t oplen = 0;
+    if(cond.ptr) {
+        //printf("cond: {%.*s}\n", cond.length, cond.ptr);
+        UcxList *ops = NULL;
+        if(dav_parse_condition(&ops, cond, ap)) {
+            // TODO: error
+            printf("parse error\n");
+            return NULL;
+        }
+        oplen = ucx_list_size(ops);
+        condition = calloc(sizeof(DavQOp), oplen);
+        int l = 0;
+        UCX_FOREACH(elm, ops) {
+            condition[l] = *(DavQOp*)elm->data;
+            free(elm->data);
+            l++;
+        }
+        ucx_list_free(ops);
+    }
+    
     DavGetQuery *getquery = malloc(sizeof(DavGetQuery));
     getquery->properties = sstrdup(property_query);
     getquery->from = sstrn(fbuf->space, fbuf->pos);
-    // TODO: condition
+    if(condition) {
+        getquery->condition = condition;
+        getquery->condlen = oplen;
+    } else {
+        getquery->condition = NULL;
+        getquery->condlen = 0;
+    }
     return getquery;
 }
 
@@ -137,3 +165,524 @@
     
     return 0;
 }
+
+int dav_parse_condition(UcxList **ops, sstr_t cond, va_list ap) {
+    sstr_t token;
+    DavQOp *op1 = NULL; // level 1 operator
+    DavQOp *op2 = NULL; // level 2 operator
+    DavQOp *op3 = NULL; // level 3 operator
+    while((token = condition_parser_next_token(&cond)).length > 0) {
+        //printf("token: {%.*s}[%d]\n", token.length, token.ptr, token.length);
+        int64_t type = 0;
+        int tkop = condition_operator_type(token, &type);
+        DavQOp *operation = malloc(sizeof(DavQOp));
+        if(tkop > 0) {
+            // operator token
+            operation->type = DAVQOP_OPERATOR;
+            operation->val = NULL;
+            operation->intval = type;
+            switch(tkop) {
+                case 1: {
+                    // operators: + - / * not
+                    // add operation after next non operator token
+                    op1 = operation;
+                    break;
+                }
+                case 2: {
+                    // operators: < > == != <= >=
+                    if(op2) {
+                        *ops = ucx_list_append(*ops, op2);
+                    }
+                    op2 = operation;
+                    break;
+                }
+                case 3: {
+                    // operators: and or xor
+                    if(op2) {
+                        *ops = ucx_list_append(*ops, op2);
+                        op2 = NULL;
+                    }
+                    if(op3) {
+                        *ops = ucx_list_append(*ops, op3);
+                    }
+                    op3 = operation;
+                    break;
+                }
+            }
+        } else {
+            if(token.ptr[0] == '"' || token.ptr[0] == '\'') {
+                operation->type = DAVQOP_STRING;
+                operation->val = token.ptr+1;
+                operation->intval = token.length-2;
+            } else if(!sstrcmp(token, S("true")) ||
+                    !sstrcmp(token, S("false")))
+            {
+                operation->type = DAVQOP_INTEGER;
+                operation->val = NULL;
+                operation->intval = util_getboolean(token.ptr);
+            } else if(token.length == 2 && token.ptr[0] == '%') {
+                switch(token.ptr[1]) {
+                    case 's': {
+                        char *arg = va_arg(ap, char*);
+                        operation->type = DAVQOP_STRING;
+                        operation->val = arg;
+                        operation->intval = strlen(arg);
+                        break;
+                    }
+                    case 'd': {
+                        operation->type = DAVQOP_INTEGER;
+                        operation->val = NULL;
+                        operation->intval = va_arg(ap, int);
+                        break;
+                    }
+                    case 't': {
+                        operation->type = DAVQOP_INTEGER;
+                        operation->val = NULL;
+                        operation->intval = va_arg(ap, time_t);
+                        break;
+                    }
+                    default: {
+                        operation->type = DAVQOP_STRING;
+                        operation->val = token.ptr;
+                        operation->intval = token.length;
+                    }
+                }
+            } else {
+                sstr_t d = sstrdup(token);
+                char *end;
+                int64_t val = strtoll(d.ptr, &end, 0);
+                int intval = strlen(end) == 0 ? 1 : 0;
+                free(d.ptr);
+                if(intval) {
+                    operation->type = DAVQOP_INTEGER;
+                    operation->val = NULL;
+                    operation->intval = val;
+                } else {
+                    if(!sstrcmp(token, S("contentlength"))) {
+                        operation->type = DAVQOP_RESPROP;
+                    } else if(!sstrcmp(token, S("lastmodified"))) {
+                        operation->type = DAVQOP_RESPROP;
+                    } else if(!sstrcmp(token, S("creationdate"))) {
+                        operation->type = DAVQOP_RESPROP;
+                    } else if(!sstrcmp(token, S("name"))) {
+                        operation->type = DAVQOP_RESPROP;
+                    } else if(!sstrcmp(token, S("path"))) {
+                        operation->type = DAVQOP_RESPROP;
+                    } else {
+                        operation->type = DAVQOP_PROPERTY;
+                    }
+                    operation->val = token.ptr;
+                    operation->intval = token.length;
+                }
+            }
+            
+            // add operation
+            *ops = ucx_list_append(*ops, operation);
+            if(op1) {
+                // add level 1 operator
+                *ops = ucx_list_append(*ops, op1);
+                op1 = NULL;
+            }
+        }
+    }
+    if(op1) {
+        *ops = ucx_list_append(*ops, op1);
+    }
+    if(op2) {
+        *ops = ucx_list_append(*ops, op2);
+    }
+    if(op3) {
+        *ops = ucx_list_append(*ops, op3);
+    }
+    return 0;
+}
+
+sstr_t condition_parser_next_token(sstr_t *str) {
+    sstr_t s = *str;
+    sstr_t t;
+    t.ptr = NULL;
+    t.length = 0;
+    // remove leading space
+    int i;
+    for(i=0;i<s.length;i++) {
+        if(s.ptr[i] > 32) {
+            break;
+        }
+    }
+    s.length -= i;
+    s.ptr += i;
+    
+    if(s.length == 0) {
+        *str = s;
+        return t;
+    }
+    
+    // check for single char operators
+    switch(s.ptr[0]) {
+        case '<':
+        case '>':
+        case '+':
+        case '-':
+        case '*':
+        case '/': {
+            t.ptr = s.ptr;
+            t.length = 1;
+            str->ptr = s.ptr + 1;
+            str->length = s.length - 1;
+            return t;
+        }
+    }
+    
+    if(s.length > 1) {
+        // check for double char operators
+        int16_t op = *(int16_t*)s.ptr;
+        if(op == '==' || op == '!=' || op == '>=' || op == '=<') {
+            t.ptr = s.ptr;
+            t.length = 2;
+            str->ptr = s.ptr + 2;
+            str->length = s.length - 2;
+            return t;
+        }
+    } else {
+        t.ptr = s.ptr;
+        t.length = 1;
+        str->ptr = s.ptr + 1;
+        str->length = s.length - 1;
+        return t;
+    }
+    
+    // TODO: brackets
+    
+    // check for string literal
+    if(s.ptr[0] == '\'' || s.ptr[0] == '"') {
+        for(i=1;i<s.length;i++) {
+            if(s.ptr[0] == s.ptr[i]) {
+                i++;
+                break;
+            }
+        }
+        t.ptr = s.ptr;
+        t.length = i;
+        str->ptr = s.ptr + i;
+        str->length = s.length - i;
+        return t;
+    }
+    
+    for(i=0;i<s.length;i++) {
+        char c = s.ptr[i];
+        if((c < 33) || (c > 41 && c < 48) || (c > 59 && c < 63)) {
+            break;
+        }
+    }
+    t.ptr = s.ptr;
+    t.length = i;
+    str->ptr = s.ptr + i;
+    str->length = s.length - i;
+    return t;
+}
+
+int condition_operator_type(sstr_t token, int64_t *type) {
+    // returns the operator level and sets the type
+    
+    if(token.ptr[0] == '"' || token.ptr[0] == '\'' || token.ptr[0] == '(') {
+        return 0;
+    }
+    
+    if(token.length == 1) {
+        switch(token.ptr[0]) {
+            case '+': *type = 1; return 1;
+            case '-': *type = 2; return 1;
+            case '*': *type = 3; return 1;
+            case '/': *type = 4; return 1;
+            case '<': *type = 5; return 2;
+            case '>': *type = 6; return 2;
+        }
+    }
+    if(!sstrcmp(token, S("not"))) {
+        *type = 0;
+        return 1;
+    }
+    
+    if(!sstrcmp(token, S("=="))) {
+        *type = 7;
+        return 2;
+    }
+    if(!sstrcmp(token, S("!="))) {
+        *type = 8;
+        return 2;
+    }
+    if(!sstrcmp(token, S("<="))) {
+        *type = 9;
+        return 2;
+    }
+    if(!sstrcmp(token, S(">="))) {
+        *type = 10;
+        return 2;
+    }
+    
+    if(!sstrcmp(token, S("and"))) {
+        *type = 11;
+        return 3;
+    }
+    if(!sstrcmp(token, S("or"))) {
+        *type = 12;
+        return 3;
+    }
+    if(!sstrcmp(token, S("xor"))) {
+        *type = 13;
+        return 3;
+    }
+    
+    return 0;
+}
+
+int condition_eval(DavResource *res, DavQOp *cond, size_t len) {
+    DavQOp stack[128];
+    int stackpos = 0;
+    for(int i=0;i<len;i++) {
+        DavQOp op = cond[i];
+        switch(op.type) {
+            case DAVQOP_OPERATOR: {
+                if(op.intval == 0) {
+                    // not operator
+                    if(stackpos < 1) {
+                        // error
+                        printf("no data on stack\n");
+                        return NULL;
+                    }
+                    int pos = stackpos-1;
+                    if(stack[pos].type == DAVQOP_INTEGER) {
+                        printf("not %" PRId64 "\n", stack[pos].intval);
+                        stack[pos].intval = !stack[pos].intval;
+                    } else {
+                        // error
+                        printf("wrong value for 'not' operator\n");
+                        return NULL;
+                    }
+                } else {
+                    DavQOp val1 = stack[stackpos-2];
+                    DavQOp val2 = stack[stackpos-1];
+                    DavQOp result;
+                    if(val1.type == DAVQOP_INTEGER) {
+                        if(val2.type == DAVQOP_INTEGER) {
+                            result = compare_intint(
+                                    op.intval,
+                                    val1.intval,
+                                    val2.intval);
+                        } else {
+                            result = compare_intstr(op.intval, val1, val2);
+                        }
+                    } else {
+                        if(val2.type == DAVQOP_INTEGER) {
+                            result = compare_strint(op.intval, val1, val2);
+                        } else {
+                            result = compare_strstr(op.intval, val1, val2);
+                        }
+                    } 
+                    stack[stackpos-2] = result;
+                    stackpos--;
+                }
+                break;
+            }
+            case DAVQOP_STRING:
+            case DAVQOP_INTEGER:
+            case DAVQOP_TIME: {
+                if(op.type == DAVQOP_STRING) {
+                    printf("put on stack: '%s'\n", op.val);
+                } else {
+                    printf("put on stack[%d]: %" PRId64 "\n", stackpos, op.intval);
+                }
+                stack[stackpos++] = op;
+                break;
+            }
+            case DAVQOP_PROPERTY: {
+                sstr_t pname = sstrn(op.val, op.intval);
+                pname = sstrdup(pname);
+                char *property_value = dav_get_property(res, pname.ptr);
+                free(pname.ptr);
+                DavQOp value;
+                value.type = DAVQOP_STRING;
+                if(property_value) {
+                    printf("put on stack: \"%s\"\n", property_value);
+                    value.val = property_value;
+                    value.intval = strlen(property_value);
+                } else {
+                    printf("put on stack: null string\n");
+                    value.val = NULL;
+                    value.intval = 0;
+                }
+                stack[stackpos++] = value;
+                break;
+            }
+            case DAVQOP_RESPROP: {
+                sstr_t name = sstrn(op.val, op.intval);
+                DavQOp value;
+                value.type = DAVQOP_INTEGER;
+                value.val = NULL;
+                if(!sstrcmp(name, S("contentlength"))) {
+                    printf("put contentlength\n");
+                    value.intval = res->contentlength;
+                } else if(!sstrcmp(name, S("lastmodified"))) {
+                    printf("put getlastmodified\n");
+                    value.intval = res->lastmodified;
+                } else if(!sstrcmp(name, S("creationdate"))) {
+                    value.intval = res->creationdate;
+                } else if(!sstrcmp(name, S("name"))) {
+                    value.type = DAVQOP_STRING;
+                    value.val = res->name;
+                    value.intval = strlen(res->name);
+                } else if(!sstrcmp(name, S("path"))) {
+                    value.type = DAVQOP_STRING;
+                    value.val = res->path;
+                    value.intval = strlen(res->path);
+                }
+                stack[stackpos++] = value;
+                break;
+            }
+        }
+    }
+    if(stackpos != 1) {
+        return 0;
+    }
+    DavQOp result = stack[0];
+    printf("result: %" PRId64 "\n", result.intval);
+    return (int)result.intval;
+}
+
+DavQOp compare_intint(int op, int64_t v1, int64_t v2) {
+    DavQOp res;
+    res.type = DAVQOP_INTEGER;
+    res.val = NULL;
+    res.intval = 0;
+    switch(op) {
+        case 5: {
+            // <
+            printf("compare: %" PRId64 " < %" PRId64 "\n", v1, v2);
+            res.intval = v1 < v2;
+            break;
+        }
+        case 6: {
+            // >
+            printf("compare: %" PRId64 " > %" PRId64 "\n", v1, v2);
+            res.intval = v1 > v2;
+            break;
+        }
+        case 7: {
+            // ==
+            printf("compare: %" PRId64 " == %" PRId64 "\n", v1, v2);
+            res.intval = v1 == v2;
+            break;
+        }
+        case 8: {
+            // !=
+            printf("compare: %" PRId64 " != %" PRId64 "\n", v1, v2);
+            res.intval = v1 != v2;
+            break;
+        }
+        case 9: {
+            // <=
+            printf("compare: %" PRId64 " <= %" PRId64 "\n", v1, v2);
+            res.intval = v1 <= v2;
+            break;
+        }
+        case 10: {
+            // >=
+            printf("compare: %" PRId64 " >= %" PRId64 "\n", v1, v2);
+            res.intval = v1 >= v2;
+            break;
+        }
+        case 11: {
+            // and
+            printf("compare: %" PRId64 " and %" PRId64 "\n", v1, v2);
+            res.intval = v1 && v2;
+            break;
+        }
+        case 12: {
+            // or
+            printf("compare: %" PRId64 " or %" PRId64 "\n", v1, v2);
+            res.intval = v1 || v2;
+            break;
+        }
+        case 13: {
+            // xor
+            printf("compare: %" PRId64 " xor %" PRId64 "\n", v1, v2);
+            res.intval = v1 ^ v2;
+            break;
+        }
+    }
+    return res;
+}
+
+DavQOp compare_strint(int op, DavQOp v1, DavQOp v2) {
+    // TODO
+}
+
+DavQOp compare_intstr(int op, DavQOp v1, DavQOp v2) {
+    // TODO
+}
+
+DavQOp compare_strstr(int op, DavQOp v1, DavQOp v2) {
+    DavQOp res;
+    res.type = DAVQOP_INTEGER;
+    res.val = NULL;
+    res.intval = 0;
+    sstr_t s1 = sstrn(v1.val, v1.intval);
+    sstr_t s2 = sstrn(v2.val, v2.intval);
+    switch(op) {
+        case 5: {
+            // <
+            printf("str compare: %.*s < %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = s1.length < s2.length;
+            break;
+        }
+        case 6: {
+            // >
+            printf("str compare: %.*s > %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = s1.length > s2.length;
+            break;
+        }
+        case 7: {
+            // ==
+            printf("str compare: %.*s == %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = sstrcmp(s1, s2) == 0;
+            break;
+        }
+        case 8: {
+            // !=
+            printf("str compare: %.*s != %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = sstrcmp(s1, s2) != 0;
+            break;
+        }
+        case 9: {
+            // <=
+            printf("str compare: %.*s <= %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = s1.length <= s2.length;
+            break;
+        }
+        case 10: {
+            // >=
+            printf("str compare: %.*s >= %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = s1.length >= s2.length;
+            break;
+        }
+        case 11: {
+            // and
+            printf("str compare: %.*s and %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = s1.ptr && s2.ptr;
+            break;
+        }
+        case 12: {
+            // or
+            printf("str compare: %.*s or %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = s1.ptr || s2.ptr;
+            break;
+        }
+        case 13: {
+            // xor
+            printf("str compare: %.*s xor %.*s\n", s1.length, s1.ptr, s2.length, s2.ptr);
+            res.intval = (int)s1.ptr ^ (int)s2.ptr;
+            break;
+        }
+    }
+    return res;
+}
--- a/dav/davql.h	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/davql.h	Wed Aug 21 13:08:22 2013 +0200
@@ -26,10 +26,14 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "webdav.h"
+
 #ifndef DAVQL_H
 #define	DAVQL_H
 
 #include <ucx/string.h>
+#include <ucx/list.h>
+#include <inttypes.h>
 #include <stdarg.h>
 
 #ifdef	__cplusplus
@@ -41,6 +45,19 @@
     DAV_QUERY_GET
 };
 typedef enum DavQueryType DavQueryType;
+
+#define DAVQOP_OPERATOR    0
+#define DAVQOP_STRING      1
+#define DAVQOP_INTEGER     2
+#define DAVQOP_TIME        3
+#define DAVQOP_PROPERTY    4
+#define DAVQOP_RESPROP     5
+
+typedef struct {
+    int      type;
+    void     *val;
+    int64_t intval;
+} DavQOp;
     
 typedef struct {
     DavQueryType command;
@@ -50,7 +67,8 @@
 typedef struct {
     sstr_t properties;
     sstr_t from;
-    // TODO: condition
+    DavQOp *condition;
+    size_t condlen;
 } DavGetQuery;
     
 DavQuery dav_ql_parse(char *query, va_list ap);
@@ -59,6 +77,15 @@
 
 int parse_path_query(sstr_t query, char **path, int *depth);
 
+int dav_parse_condition(UcxList **ops, sstr_t cond, va_list ap);
+sstr_t condition_parser_next_token(sstr_t *str);
+int condition_operator_type(sstr_t token, int64_t *type);
+
+int condition_eval(DavResource *res, DavQOp *cond, size_t len);
+DavQOp compare_intint(int op, int64_t v1, int64_t v2);
+DavQOp compare_strint(int op, DavQOp v1, DavQOp v2);
+DavQOp compare_intstr(int op, DavQOp v1, DavQOp v2);
+DavQOp compare_strstr(int op, DavQOp v1, DavQOp v2);
 
 #ifdef	__cplusplus
 }
--- a/dav/main.c	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/main.c	Wed Aug 21 13:08:22 2013 +0200
@@ -531,7 +531,7 @@
                     char *res_url = util_concat_path(
                             res->session->base_url,
                             res->path);
-                    printf("Skip resource: %s\n", res_url);
+                    printf("Skipping resource: %s\n", res_url);
                     free(res_url);
                     return 0;
                 } else {
--- a/dav/methods.c	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/methods.c	Wed Aug 21 13:08:22 2013 +0200
@@ -32,6 +32,7 @@
 
 #include "utils.h"
 #include "methods.h"
+#include "davql.h"
 
 #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
 
@@ -150,7 +151,7 @@
     return buf;
 }
 
-DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response) {
+DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len) {
     char *url = NULL;
     curl_easy_getinfo(sn->handle, CURLINFO_EFFECTIVE_URL, &url);
     if(!root) {
@@ -169,7 +170,7 @@
     while(node) {
         if(node->type == XML_ELEMENT_NODE) {
             if(xstreq(node->name, "response")) {
-                parse_response_tag(root, node);
+                parse_response_tag(root, node, cond, len);
             }
         }
         
@@ -179,7 +180,7 @@
     return root;
 }
 
-int parse_response_tag(DavResource *resource, xmlNode *node) {
+int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t clen) {
     DavResource *res = resource;
     node = node->children;
     while(node) {
@@ -195,7 +196,7 @@
                     res = resource;
                 } else {
                     res = resource_new_href(resource->session, (char*)href_content->content);
-                    resource_add_child(resource, res);
+                    res->parent = resource;
                 }
             } else if(xstreq(node->name, "propstat")) {
                 xmlNode *n = node->children;
@@ -258,6 +259,15 @@
     }
     
     set_davprops(res);
+    if(res != resource) {
+        if(clen > 0) {
+            if(!condition_eval(res, cond, clen)) {
+                // skip resource
+                return 0;
+            }
+        }
+        resource_add_child(resource, res);
+    }
     
     return 0;
 }
--- a/dav/methods.h	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/methods.h	Wed Aug 21 13:08:22 2013 +0200
@@ -53,8 +53,8 @@
 
 UcxBuffer* create_allprop_propfind_request();
 UcxBuffer* create_propfind_request(UcxList *properties);
-DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response);
-int parse_response_tag(DavResource *resource, xmlNode *node);
+DavResource* parse_propfind_response(DavSession *sn, DavResource *root, UcxBuffer *response, DavQOp *cond, size_t len);
+int parse_response_tag(DavResource *resource, xmlNode *node, DavQOp *cond, size_t len);
 void set_davprops(DavResource *res);
 
 UcxBuffer* create_proppatch_request(DavNodeData *data);
--- a/dav/webdav.c	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/webdav.c	Wed Aug 21 13:08:22 2013 +0200
@@ -237,7 +237,7 @@
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && status == 207) {
         //printf("response\n%s\n", rpbuf->space); 
-        resource = parse_propfind_response(sn, NULL, rpbuf);
+        resource = parse_propfind_response(sn, NULL, rpbuf, NULL, 0);
         sn->error = DAV_OK;
     } else  {
         session_set_error(sn, ret, status);
@@ -245,7 +245,7 @@
     return resource;
 }
 
-DavResource* dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, char *path) {
+DavResource* dav_propfind(DavSession *sn, DavResource *root, UcxBuffer *rqbuf, char *path, DavQOp *cond, size_t len) {
     char *url = util_concat_path(sn->base_url, path);  
     CURL *handle = sn->handle;
     curl_easy_setopt(handle, CURLOPT_URL, url);
@@ -258,7 +258,7 @@
     curl_easy_getinfo (handle, CURLINFO_RESPONSE_CODE, &status);
     if(ret == CURLE_OK && status == 207) {
         //printf("response\n%s\n", rpbuf->space); 
-        resource = parse_propfind_response(sn, resource, rpbuf);
+        resource = parse_propfind_response(sn, resource, rpbuf, cond, len);
         sn->error = DAV_OK;
     } else  {
         session_set_error(sn, ret, status);
@@ -300,7 +300,7 @@
     //fwrite(rqbuf->space, 1, rqbuf->size, stdout);
     //printf("\n");
     
-    DavResource *resource = dav_propfind(sn, NULL, rqbuf, path);
+    DavResource *resource = dav_propfind(sn, NULL, rqbuf, path, query->condition, query->condlen);
     free(path);
     int error = 0;
     if(resource && depth == -1) {
@@ -310,7 +310,7 @@
             DavResource *sr = stack->data; // get first element from the stack
             stack = ucx_list_remove(stack, stack); // remove first element
             // do propfind request for sr
-            sr = dav_propfind(sn, sr, rqbuf, sr->path);
+            sr = dav_propfind(sn, sr, rqbuf, sr->path, query->condition, query->condlen);
             if(!sr) {
                 error = 1;
                 printf("subrequest failed\n");
@@ -507,7 +507,7 @@
         while(node) {
             if(node->type == XML_ELEMENT_NODE) {
                 if(xstreq(node->name, "response")) {
-                    parse_response_tag(res, node);
+                    parse_response_tag(res, node, NULL, 0);
                 }
             }
             node = node->next;
@@ -798,7 +798,7 @@
         while(node) {
             if(node->type == XML_ELEMENT_NODE) {
                 if(xstreq(node->name, "response")) {
-                    parse_response_tag(res, node);
+                    parse_response_tag(res, node, NULL, 0);
                 }
             }
             node = node->next;
--- a/dav/webdav.h	Tue Aug 20 11:34:44 2013 +0200
+++ b/dav/webdav.h	Wed Aug 21 13:08:22 2013 +0200
@@ -26,8 +26,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef NODE_H
-#define	NODE_H
+#ifndef WEBDAV_H
+#define	WEBDAV_H
 
 #include <inttypes.h>
 #include <ucx/map.h>
@@ -36,7 +36,6 @@
 #include <ucx/buffer.h>
 #include <curl/curl.h>
 #include <libxml/tree.h>
-#include "davql.h"
 
 #ifdef	__cplusplus
 extern "C" {
@@ -50,6 +49,8 @@
 typedef struct DavNodeData   DavNodeData;
 typedef struct DavProperty   DavProperty;
 
+#include "davql.h"
+
 typedef size_t(*dav_read_func)(void*, size_t, size_t, void*);
 typedef size_t(*dav_write_func)(const void*, size_t, size_t, void*);
 
@@ -199,5 +200,5 @@
 }
 #endif
 
-#endif	/* NODE_H */
+#endif	/* WEBDAV_H */
 

mercurial