480 } |
480 } |
481 |
481 |
482 return 0; |
482 return 0; |
483 } |
483 } |
484 |
484 |
|
485 static int webdav_xattr_parse_ns(cxstring line, cxstring *prefix, cxstring *href) { |
|
486 size_t i = 0; |
|
487 for(i=1;i<line.length;i++) { |
|
488 if(line.ptr[i] == ':') { |
|
489 break; |
|
490 } |
|
491 } |
|
492 if(i == 0 || i+1 >= line.length) { |
|
493 // error: ':' not found or ':' is the last character |
|
494 return 1; |
|
495 } |
|
496 |
|
497 cxstring pre; |
|
498 pre.ptr = line.ptr; |
|
499 pre.length = i; |
|
500 *prefix = pre; |
|
501 |
|
502 *href = cx_strsubs(line, i+1); |
|
503 |
|
504 return 0; |
|
505 } |
|
506 |
485 int webdav_xattr_put_prop(CxMap *pmap, WebdavProperty *prop) { |
507 int webdav_xattr_put_prop(CxMap *pmap, WebdavProperty *prop) { |
486 CxHashKey key = webdav_property_key_a( |
508 CxHashKey key = webdav_property_key_a( |
487 pmap->allocator, |
509 pmap->allocator, |
488 (const char*)prop->namespace->href, |
510 (const char*)prop->namespace->href, |
489 (const char*)prop->name); |
511 (const char*)prop->name); |
500 if(!pmap) { |
522 if(!pmap) { |
501 return NULL; |
523 return NULL; |
502 } |
524 } |
503 cxstring dat = cx_strn(data, len); |
525 cxstring dat = cx_strn(data, len); |
504 |
526 |
505 printf("\n\n"); |
|
506 |
|
507 cxstring s_elm = CX_STR("prop "); |
527 cxstring s_elm = CX_STR("prop "); |
508 cxstring s_ns = CX_STR("ns "); |
528 cxstring s_ns = CX_STR("ns "); |
509 cxstring s_data = CX_STR("data "); |
529 cxstring s_data = CX_STR("data "); |
510 |
530 |
511 WebdavProperty *prop = NULL; |
531 WebdavProperty *prop = NULL; |
|
532 WebdavNSList *ns_begin = NULL; |
|
533 WebdavNSList *ns_end = NULL; |
512 |
534 |
513 int error = 0; |
535 int error = 0; |
514 |
536 |
515 size_t elmno = 0; |
537 size_t elmno = 0; |
516 cxstring line; |
538 cxstring line; |
546 if(!prop) { |
568 if(!prop) { |
547 error = 1; |
569 error = 1; |
548 break; |
570 break; |
549 } |
571 } |
550 ZERO(prop, sizeof(WebdavProperty)); |
572 ZERO(prop, sizeof(WebdavProperty)); |
|
573 ns_begin = NULL; |
|
574 ns_end = NULL; |
551 |
575 |
552 WSNamespace *ns = cxMalloc(a, sizeof(WSNamespace)); |
576 WSNamespace *ns = cxMalloc(a, sizeof(WSNamespace)); |
553 if(!ns) { |
577 if(!ns) { |
554 error = 1; |
578 error = 1; |
555 break; |
579 break; |
556 } |
580 } |
|
581 ZERO(ns, sizeof(WSNamespace)); |
557 |
582 |
558 char *name_str = cx_strdup_a(a, name).ptr; |
583 char *name_str = cx_strdup_a(a, name).ptr; |
559 char *prefix_str = cx_strdup_a(a, prefix).ptr; |
584 char *prefix_str = cx_strdup_a(a, prefix).ptr; |
560 char *xmlns_str = cx_strdup_a(a, xmlns).ptr; |
585 char *xmlns_str = cx_strdup_a(a, xmlns).ptr; |
561 if(!(name_str && prefix_str && xmlns_str)) { |
586 if(!(name_str && prefix_str && xmlns_str)) { |
570 prop->namespace = ns; |
595 prop->namespace = ns; |
571 |
596 |
572 elmno++; |
597 elmno++; |
573 } else if(prop) { |
598 } else if(prop) { |
574 if(cx_strprefix(line, s_ns)) { |
599 if(cx_strprefix(line, s_ns)) { |
575 // TODO |
600 line = cx_strsubs(line, 3); |
|
601 |
|
602 cxstring prefix; |
|
603 cxstring href; |
|
604 if(webdav_xattr_parse_ns(line, &prefix, &href)) { |
|
605 log_ereport( |
|
606 LOG_FAILURE, |
|
607 "webdav xattr backend: file %s: invalid xattr format[%d]: cannot parse ns", |
|
608 path, |
|
609 elmno); |
|
610 error = 1; |
|
611 break; |
|
612 } |
|
613 |
|
614 WSNamespace *ns_decl = cxMalloc(a, sizeof(WSNamespace)); |
|
615 if(!ns_decl) { |
|
616 error = 1; |
|
617 break; |
|
618 } |
|
619 ZERO(ns_decl, sizeof(WSNamespace)); |
|
620 |
|
621 ns_decl->prefix = (const xmlChar*)cx_strdup_a(a, prefix).ptr; |
|
622 ns_decl->href = (const xmlChar*)cx_strdup_a(a, href).ptr; |
|
623 if(!(ns_decl->prefix && ns_decl->href)) { |
|
624 error = 1; |
|
625 break; |
|
626 } |
|
627 |
|
628 if(webdav_nslist_add(a->data, &ns_begin, &ns_end, ns_decl)) { |
|
629 error = 1; |
|
630 break; |
|
631 } |
576 } else if(cx_strprefix(line, s_data)) { |
632 } else if(cx_strprefix(line, s_data)) { |
577 line = cx_strsubs(line, 5); |
633 line = cx_strsubs(line, 5); |
578 |
634 |
579 // util_strtoint just works here, because the line ends with \n |
635 // util_strtoint just works here, because the line ends with \n |
580 // the xattr content data is also garanteed to be 0-terminated |
636 // the xattr content data is also garanteed to be 0-terminated |
581 int64_t data_len = 0; |
637 int64_t data_len = 0; |
582 if(!util_strtoint(line.ptr, &data_len)) { |
638 if(!util_strtoint(line.ptr, &data_len)) { |
583 log_ereport( |
639 log_ereport( |
584 LOG_FAILURE, |
640 LOG_FAILURE, |
585 "webdav xattr backend: %file %s: invalid xattr format[%d]: number expected after data", |
641 "webdav xattr backend: file %s: invalid xattr format[%d]: number expected after data", |
586 path, |
642 path, |
587 elmno); |
643 elmno); |
588 error = 1; |
644 error = 1; |
589 break; |
645 break; |
590 } |
646 } |
611 if(!propdata_cp.ptr) { |
667 if(!propdata_cp.ptr) { |
612 error = 1; |
668 error = 1; |
613 break; |
669 break; |
614 } |
670 } |
615 prop->vtype = WS_VALUE_XML_DATA; |
671 prop->vtype = WS_VALUE_XML_DATA; |
616 prop->value.data.namespaces = NULL; |
672 prop->value.data.namespaces = ns_begin; |
617 prop->value.data.data = propdata_cp.ptr; |
673 prop->value.data.data = propdata_cp.ptr; |
618 prop->value.data.length = propdata_cp.length; |
674 prop->value.data.length = propdata_cp.length; |
619 |
675 |
620 if(pos < dat.length && dat.ptr[pos] == '\n') { |
676 if(pos < dat.length && dat.ptr[pos] == '\n') { |
621 pos++; |
677 pos++; |
622 } |
678 } |
623 } |
679 } |
624 } else { |
680 } else { |
625 log_ereport( |
681 log_ereport( |
626 LOG_FAILURE, |
682 LOG_FAILURE, |
627 "webdav xattr backend: %file %s: invalid xattr format[%d]: unknown element", |
683 "webdav xattr backend: file %s: invalid xattr format[%d]: unknown element", |
628 path, |
684 path, |
629 elmno); |
685 elmno); |
630 error = 1; |
686 error = 1; |
631 break; |
687 break; |
632 } |
688 } |
633 } |
689 } |
634 |
|
635 //printf("line: {%.*s}\n", (int)line.length, line.ptr); |
|
636 //fflush(stdout); |
|
637 } |
690 } |
638 |
691 |
639 // add last property |
692 // add last property |
640 if(prop) { |
693 if(prop) { |
641 if(webdav_xattr_put_prop(pmap, prop)) { |
694 if(webdav_xattr_put_prop(pmap, prop)) { |
679 return (cxmutstr){NULL,0}; |
728 return (cxmutstr){NULL,0}; |
680 } |
729 } |
681 if(property_value) { |
730 if(property_value) { |
682 WebdavNSList *ns = property_value->namespaces; |
731 WebdavNSList *ns = property_value->namespaces; |
683 while(ns) { |
732 while(ns) { |
684 ret = cx_bprintf(&buf, "ns %s:%s\n", prop->namespace->prefix, prop->namespace->href); |
733 ret = cx_bprintf(&buf, "ns %s:%s\n", ns->namespace->prefix, ns->namespace->href); |
685 if(ret <= 0) { |
734 if(ret <= 0) { |
686 pool_free(pool, buf.space); |
735 pool_free(pool, buf.space); |
687 return (cxmutstr){NULL,0}; |
736 return (cxmutstr){NULL,0}; |
688 } |
737 } |
689 ns = ns->next; |
738 ns = ns->next; |