src/server/webdav/xattrbackend.c

changeset 484
c036a8b242a8
parent 483
f69d88f86b9c
child 490
d218607f5a7e
equal deleted inserted replaced
483:f69d88f86b9c 484:c036a8b242a8
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;
532 cxstring xmlns; 554 cxstring xmlns;
533 cxstring lang; 555 cxstring lang;
534 if(webdav_xattr_parse_elm(line, &name, &prefix, &xmlns, &lang)) { 556 if(webdav_xattr_parse_elm(line, &name, &prefix, &xmlns, &lang)) {
535 log_ereport( 557 log_ereport(
536 LOG_FAILURE, 558 LOG_FAILURE,
537 "webdav xattr backend: %file %s: invalid xattr format[%d]: cannot parse elm line", 559 "webdav xattr backend: file %s: invalid xattr format[%d]: cannot parse elm line",
538 path, 560 path,
539 elmno); 561 elmno);
540 error = 1; 562 error = 1;
541 break; 563 break;
542 } 564 }
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 }
592 // get data 648 // get data
593 if(data_len > 0) { 649 if(data_len > 0) {
594 if(data_len > dat.length - pos) { 650 if(data_len > dat.length - pos) {
595 log_ereport( 651 log_ereport(
596 LOG_FAILURE, 652 LOG_FAILURE,
597 "webdav xattr backend: %file %s: invalid data length %" PRId64 " in prop %d", 653 "webdav xattr backend: file %s: invalid data length %" PRId64 " in prop %d",
598 path, 654 path,
599 data_len, 655 data_len,
600 elmno); 656 elmno);
601 error = 1; 657 error = 1;
602 break; 658 break;
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)) {
646 if(error) { 699 if(error) {
647 // TODO: free pmap content 700 // TODO: free pmap content
648 cxMapDestroy(pmap); 701 cxMapDestroy(pmap);
649 pmap = NULL; 702 pmap = NULL;
650 } 703 }
651
652 //printf("\n\n");
653 //fflush(stdout);
654
655 704
656 return pmap; 705 return pmap;
657 } 706 }
658 707
659 cxmutstr webdav_xattr_serialze_map(CxAllocator *a, CxMap *pmap) { 708 cxmutstr webdav_xattr_serialze_map(CxAllocator *a, CxMap *pmap) {
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;

mercurial