~ubuntu-branches/ubuntu/trusty/subversion/trusty-proposed

« back to all changes in this revision

Viewing changes to subversion/mod_dav_svn/liveprops.c

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft
  • Date: 2012-06-21 15:36:36 UTC
  • mfrom: (0.4.13 sid)
  • Revision ID: package-import@ubuntu.com-20120621153636-amqqmuidgwgxz1ly
Tags: 1.7.5-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - Create pot file on build.
  - Build a python-subversion-dbg package.
  - Build-depend on python-dbg.
  - Build-depend on default-jre-headless/-jdk.
  - Do not apply java-build patch.
  - debian/rules: Manually create the doxygen output directory, otherwise
    we get weird build failures when running parallel builds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * liveprops.c: mod_dav_svn live property provider functions for Subversion
3
3
 *
4
4
 * ====================================================================
5
 
 * Copyright (c) 2000-2008 CollabNet.  All rights reserved.
6
 
 *
7
 
 * This software is licensed as described in the file COPYING, which
8
 
 * you should have received as part of this distribution.  The terms
9
 
 * are also available at http://subversion.tigris.org/license-1.html.
10
 
 * If newer versions of this license are posted there, you may use a
11
 
 * newer version instead, at your option.
12
 
 *
13
 
 * This software consists of voluntary contributions made by many
14
 
 * individuals.  For exact contribution history, see the revision
15
 
 * history and logs, available at http://subversion.tigris.org/.
 
5
 *    Licensed to the Apache Software Foundation (ASF) under one
 
6
 *    or more contributor license agreements.  See the NOTICE file
 
7
 *    distributed with this work for additional information
 
8
 *    regarding copyright ownership.  The ASF licenses this file
 
9
 *    to you under the Apache License, Version 2.0 (the
 
10
 *    "License"); you may not use this file except in compliance
 
11
 *    with the License.  You may obtain a copy of the License at
 
12
 *
 
13
 *      http://www.apache.org/licenses/LICENSE-2.0
 
14
 *
 
15
 *    Unless required by applicable law or agreed to in writing,
 
16
 *    software distributed under the License is distributed on an
 
17
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
18
 *    KIND, either express or implied.  See the License for the
 
19
 *    specific language governing permissions and limitations
 
20
 *    under the License.
16
21
 * ====================================================================
17
22
 */
18
23
 
20
25
 
21
26
#include <httpd.h>
22
27
#include <http_core.h>
 
28
#include <http_log.h>
23
29
#include <util_xml.h>
24
30
#include <mod_dav.h>
25
31
 
263
269
}
264
270
 
265
271
static dav_prop_insert
266
 
insert_prop(const dav_resource *resource,
267
 
            int propid,
268
 
            dav_prop_insert what,
269
 
            apr_text_header *phdr)
 
272
insert_prop_internal(const dav_resource *resource,
 
273
                     int propid,
 
274
                     dav_prop_insert what,
 
275
                     apr_text_header *phdr,
 
276
                     apr_pool_t *scratch_pool,
 
277
                     apr_pool_t *result_pool)
270
278
{
271
279
  const char *value = NULL;
272
280
  const char *s;
273
 
  apr_pool_t *response_pool = resource->pool;
274
 
  apr_pool_t *p = resource->info->pool;
275
281
  const dav_liveprop_spec *info;
276
282
  int global_ns;
277
283
  svn_error_t *serr;
315
321
 
316
322
        /* ### for now, our global VCC has no such property. */
317
323
        if (resource->type == DAV_RESOURCE_TYPE_PRIVATE
318
 
            && resource->info->restype == DAV_SVN_RESTYPE_VCC)
 
324
            && (resource->info->restype == DAV_SVN_RESTYPE_VCC
 
325
                || resource->info->restype == DAV_SVN_RESTYPE_ME))
319
326
          {
320
327
            return DAV_PROP_INSERT_NOTSUPP;
321
328
          }
332
339
          }
333
340
 
334
341
        if (0 != get_last_modified_time(&datestring, &timeval,
335
 
                                        resource, format, p))
 
342
                                        resource, format, scratch_pool))
336
343
          {
337
344
            return DAV_PROP_INSERT_NOTDEF;
338
345
          }
339
346
 
340
 
        value = apr_xml_quote_string(p, datestring, 1);
 
347
        value = apr_xml_quote_string(scratch_pool, datestring, 1);
341
348
        break;
342
349
      }
343
350
 
348
355
 
349
356
        /* ### for now, our global VCC has no such property. */
350
357
        if (resource->type == DAV_RESOURCE_TYPE_PRIVATE
351
 
            && resource->info->restype == DAV_SVN_RESTYPE_VCC)
 
358
            && (resource->info->restype == DAV_SVN_RESTYPE_VCC
 
359
                || resource->info->restype == DAV_SVN_RESTYPE_ME))
352
360
          {
353
361
            return DAV_PROP_INSERT_NOTSUPP;
354
362
          }
366
374
               root object might be an ID root -or- a revision root. */
367
375
            serr = svn_fs_node_created_rev(&committed_rev,
368
376
                                           resource->info->root.root,
369
 
                                           resource->info->repos_path, p);
 
377
                                           resource->info->repos_path,
 
378
                                           scratch_pool);
370
379
            if (serr != NULL)
371
380
              {
372
 
                /* ### what to do? */
 
381
                ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
382
                              resource->info->r,
 
383
                              "Can't get created-rev of '%s': "
 
384
                              "%s",
 
385
                              resource->info->repos_path,
 
386
                              serr->message);
373
387
                svn_error_clear(serr);
374
388
                value = "###error###";
375
389
                break;
384
398
                                resource,
385
399
                                committed_rev,
386
400
                                SVN_PROP_REVISION_AUTHOR,
387
 
                                p);
 
401
                                scratch_pool);
388
402
        if (serr)
389
403
          {
390
 
            /* ### what to do? */
 
404
            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
405
                          resource->info->r,
 
406
                          "Can't get author of r%ld: "
 
407
                          "%s",
 
408
                          committed_rev,
 
409
                          serr->message);
391
410
            svn_error_clear(serr);
392
411
            value = "###error###";
393
412
            break;
396
415
        if (last_author == NULL)
397
416
          return DAV_PROP_INSERT_NOTDEF;
398
417
 
399
 
        value = apr_xml_quote_string(p, last_author->data, 1);
 
418
        value = apr_xml_quote_string(scratch_pool, last_author->data, 1);
400
419
        break;
401
420
      }
402
421
 
414
433
          return DAV_PROP_INSERT_NOTSUPP;
415
434
 
416
435
        serr = svn_fs_file_length(&len, resource->info->root.root,
417
 
                                  resource->info->repos_path, p);
 
436
                                  resource->info->repos_path, scratch_pool);
418
437
        if (serr != NULL)
419
438
          {
420
439
            svn_error_clear(serr);
422
441
            break;
423
442
          }
424
443
 
425
 
        value = apr_psprintf(p, "%" SVN_FILESIZE_T_FMT, len);
 
444
        value = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT, len);
426
445
        break;
427
446
      }
428
447
 
438
457
          return DAV_PROP_INSERT_NOTSUPP;
439
458
 
440
459
        if (resource->type == DAV_RESOURCE_TYPE_PRIVATE
441
 
            && resource->info->restype == DAV_SVN_RESTYPE_VCC)
 
460
            && (resource->info->restype == DAV_SVN_RESTYPE_VCC
 
461
                || resource->info->restype == DAV_SVN_RESTYPE_ME))
442
462
          {
443
463
            return DAV_PROP_INSERT_NOTSUPP;
444
464
          }
454
474
          {
455
475
            if ((serr = svn_fs_node_prop(&pval, resource->info->root.root,
456
476
                                         resource->info->repos_path,
457
 
                                         SVN_PROP_MIME_TYPE, p)))
 
477
                                         SVN_PROP_MIME_TYPE, scratch_pool)))
458
478
              {
459
479
                svn_error_clear(serr);
460
480
                pval = NULL;
468
488
            else
469
489
              mime_type = "text/plain";
470
490
 
471
 
            if ((serr = svn_mime_type_validate(mime_type, p)))
 
491
            if ((serr = svn_mime_type_validate(mime_type, scratch_pool)))
472
492
              {
473
493
                /* Probably serr->apr == SVN_ERR_BAD_MIME_TYPE, but
474
494
                   there's no point even checking.  No matter what the
485
505
 
486
506
    case DAV_PROPID_getetag:
487
507
      if (resource->type == DAV_RESOURCE_TYPE_PRIVATE
488
 
          && resource->info->restype == DAV_SVN_RESTYPE_VCC)
 
508
          && (resource->info->restype == DAV_SVN_RESTYPE_VCC
 
509
              || resource->info->restype == DAV_SVN_RESTYPE_ME))
489
510
        {
490
511
          return DAV_PROP_INSERT_NOTSUPP;
491
512
        }
492
513
 
493
 
      value = dav_svn__getetag(resource, p);
 
514
      value = dav_svn__getetag(resource, scratch_pool);
494
515
      break;
495
516
 
496
517
    case DAV_PROPID_auto_version:
510
531
        return DAV_PROP_INSERT_NOTSUPP;
511
532
      value = dav_svn__build_uri(resource->info->repos, DAV_SVN__BUILD_URI_BC,
512
533
                                 resource->info->root.rev, NULL,
513
 
                                 1 /* add_href */, p);
 
534
                                 1 /* add_href */, scratch_pool);
514
535
      break;
515
536
 
516
537
    case DAV_PROPID_checked_in:
517
538
      /* only defined for VCRs (in the public space and in a BC space) */
518
539
      /* ### note that a VCC (a special VCR) is defined as _PRIVATE for now */
519
540
      if (resource->type == DAV_RESOURCE_TYPE_PRIVATE
520
 
          && resource->info->restype == DAV_SVN_RESTYPE_VCC)
 
541
          && (resource->info->restype == DAV_SVN_RESTYPE_VCC
 
542
              || resource->info->restype == DAV_SVN_RESTYPE_ME))
521
543
        {
522
544
          svn_revnum_t revnum;
523
545
 
524
 
          serr = svn_fs_youngest_rev(&revnum, resource->info->repos->fs, p);
 
546
          serr = svn_fs_youngest_rev(&revnum, resource->info->repos->fs,
 
547
                                     scratch_pool);
525
548
          if (serr != NULL)
526
549
            {
527
 
              /* ### what to do? */
 
550
              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
551
                            resource->info->r,
 
552
                            "Can't get youngest revision in '%s': "
 
553
                            "%s",
 
554
                            svn_fs_path(resource->info->repos->fs,
 
555
                                        scratch_pool),
 
556
                            serr->message);
528
557
              svn_error_clear(serr);
529
558
              value = "###error###";
530
559
              break;
531
560
            }
532
561
          s = dav_svn__build_uri(resource->info->repos,
533
562
                                 DAV_SVN__BUILD_URI_BASELINE,
534
 
                                 revnum, NULL, 0 /* add_href */, p);
535
 
          value = apr_psprintf(p, "<D:href>%s</D:href>",
536
 
                               apr_xml_quote_string(p, s, 1));
 
563
                                 revnum, NULL, 0 /* add_href */, scratch_pool);
 
564
          value = apr_psprintf(scratch_pool, "<D:href>%s</D:href>",
 
565
                               apr_xml_quote_string(scratch_pool, s, 1));
537
566
        }
538
567
      else if (resource->type != DAV_RESOURCE_TYPE_REGULAR)
539
568
        {
544
573
        {
545
574
          svn_revnum_t rev_to_use =
546
575
            dav_svn__get_safe_cr(resource->info->root.root,
547
 
                                 resource->info->repos_path, p);
 
576
                                 resource->info->repos_path, scratch_pool);
548
577
 
549
578
          s = dav_svn__build_uri(resource->info->repos,
550
579
                                 DAV_SVN__BUILD_URI_VERSION,
551
580
                                 rev_to_use, resource->info->repos_path,
552
 
                                0 /* add_href */, p);
553
 
          value = apr_psprintf(p, "<D:href>%s</D:href>",
554
 
                               apr_xml_quote_string(p, s, 1));
 
581
                                0 /* add_href */, scratch_pool);
 
582
          value = apr_psprintf(scratch_pool, "<D:href>%s</D:href>",
 
583
                               apr_xml_quote_string(scratch_pool, s, 1));
555
584
        }
556
585
      break;
557
586
 
563
592
        return DAV_PROP_INSERT_NOTSUPP;
564
593
      value = dav_svn__build_uri(resource->info->repos, DAV_SVN__BUILD_URI_VCC,
565
594
                                 SVN_IGNORED_REVNUM, NULL,
566
 
                                 1 /* add_href */, p);
 
595
                                 1 /* add_href */, scratch_pool);
567
596
      break;
568
597
 
569
598
    case DAV_PROPID_version_name:
574
603
        return DAV_PROP_INSERT_NOTSUPP;
575
604
 
576
605
      if (resource->type == DAV_RESOURCE_TYPE_PRIVATE
577
 
          && resource->info->restype == DAV_SVN_RESTYPE_VCC)
 
606
          && (resource->info->restype == DAV_SVN_RESTYPE_VCC
 
607
              || resource->info->restype == DAV_SVN_RESTYPE_ME))
578
608
        {
579
609
          return DAV_PROP_INSERT_NOTSUPP;
580
610
        }
582
612
      if (resource->baselined)
583
613
        {
584
614
          /* just the revision number for baselines */
585
 
          value = apr_psprintf(p, "%ld",
 
615
          value = apr_psprintf(scratch_pool, "%ld",
586
616
                               resource->info->root.rev);
587
617
        }
588
618
      else
593
623
             root object might be an ID root -or- a revision root. */
594
624
          serr = svn_fs_node_created_rev(&committed_rev,
595
625
                                         resource->info->root.root,
596
 
                                         resource->info->repos_path, p);
 
626
                                         resource->info->repos_path,
 
627
                                         scratch_pool);
597
628
          if (serr != NULL)
598
629
            {
599
 
              /* ### what to do? */
 
630
              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
631
                            resource->info->r,
 
632
                            "Can't get created-rev of '%s': "
 
633
                            "%s",
 
634
                            resource->info->repos_path,
 
635
                            serr->message);
600
636
              svn_error_clear(serr);
601
637
              value = "###error###";
602
638
              break;
603
639
            }
604
640
 
605
641
          /* Convert the revision into a quoted string */
606
 
          s = apr_psprintf(p, "%ld", committed_rev);
607
 
          value = apr_xml_quote_string(p, s, 1);
 
642
          s = apr_psprintf(scratch_pool, "%ld", committed_rev);
 
643
          value = apr_xml_quote_string(scratch_pool, s, 1);
608
644
        }
609
645
      break;
610
646
 
617
653
 
618
654
      /* drop the leading slash, so it is relative */
619
655
      s = resource->info->repos_path + 1;
620
 
      value = apr_xml_quote_string(p, s, 1);
 
656
      value = apr_xml_quote_string(scratch_pool, s, 1);
621
657
      break;
622
658
 
623
659
    case SVN_PROPID_md5_checksum:
627
663
              || resource->type == DAV_RESOURCE_TYPE_WORKING
628
664
              || resource->type == DAV_RESOURCE_TYPE_VERSION))
629
665
        {
 
666
          svn_node_kind_t kind;
630
667
          svn_checksum_t *checksum;
631
668
 
632
 
          serr = svn_fs_file_checksum(&checksum, svn_checksum_md5,
633
 
                                      resource->info->root.root,
634
 
                                      resource->info->repos_path, TRUE, p);
 
669
          serr = svn_fs_check_path(&kind, resource->info->root.root,
 
670
                                   resource->info->repos_path, scratch_pool);
 
671
          if (!serr && kind == svn_node_file)
 
672
            serr = svn_fs_file_checksum(&checksum, svn_checksum_md5,
 
673
                                        resource->info->root.root,
 
674
                                        resource->info->repos_path, TRUE,
 
675
                                        scratch_pool);
635
676
          if (serr != NULL)
636
677
            {
637
 
              /* ### what to do? */
 
678
              ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
679
                            resource->info->r,
 
680
                            "Can't fetch or compute MD5 checksum of '%s': "
 
681
                            "%s",
 
682
                            resource->info->repos_path,
 
683
                            serr->message);
638
684
              svn_error_clear(serr);
639
685
              value = "###error###";
640
686
              break;
641
687
            }
642
688
 
643
 
          value = svn_checksum_to_cstring(checksum, p);
 
689
          if (kind != svn_node_file)
 
690
            return DAV_PROP_INSERT_NOTSUPP;
 
691
 
 
692
          value = svn_checksum_to_cstring(checksum, scratch_pool);
644
693
 
645
694
          if (! value)
646
695
            return DAV_PROP_INSERT_NOTSUPP;
651
700
      break;
652
701
 
653
702
    case SVN_PROPID_repository_uuid:
654
 
      serr = svn_fs_get_uuid(resource->info->repos->fs, &value, p);
 
703
      serr = svn_fs_get_uuid(resource->info->repos->fs, &value, scratch_pool);
655
704
      if (serr != NULL)
656
705
        {
657
 
          /* ### what to do? */
 
706
          ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
707
                        resource->info->r,
 
708
                        "Can't fetch UUID of '%s': "
 
709
                        "%s",
 
710
                        svn_fs_path(resource->info->repos->fs, scratch_pool),
 
711
                        serr->message);
658
712
          svn_error_clear(serr);
659
713
          value = "###error###";
660
714
          break;
671
725
 
672
726
        serr = svn_fs_node_proplist(&proplist,
673
727
                                    resource->info->root.root,
674
 
                                    resource->info->repos_path, p);
 
728
                                    resource->info->repos_path, scratch_pool);
675
729
        if (serr != NULL)
676
730
          {
677
 
            /* ### what to do? */
 
731
            ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err, 
 
732
                          resource->info->r,
 
733
                          "Can't fetch proplist of '%s': "
 
734
                          "%s",
 
735
                          resource->info->repos_path,
 
736
                          serr->message);
678
737
            svn_error_clear(serr);
679
738
            value = "###error###";
680
739
            break;
681
740
          }
682
741
 
683
742
        propcount = apr_hash_count(proplist);
684
 
        value = apr_psprintf(p, "%u", propcount);
 
743
        value = apr_psprintf(scratch_pool, "%u", propcount);
685
744
        break;
686
745
      }
687
746
 
699
758
 
700
759
  if (what == DAV_PROP_INSERT_NAME
701
760
      || (what == DAV_PROP_INSERT_VALUE && *value == '\0')) {
702
 
    s = apr_psprintf(response_pool, "<lp%d:%s/>" DEBUG_CR, global_ns,
 
761
    s = apr_psprintf(result_pool, "<lp%d:%s/>" DEBUG_CR, global_ns,
703
762
                     info->name);
704
763
  }
705
764
  else if (what == DAV_PROP_INSERT_VALUE) {
706
 
    s = apr_psprintf(response_pool, "<lp%d:%s>%s</lp%d:%s>" DEBUG_CR,
 
765
    s = apr_psprintf(result_pool, "<lp%d:%s>%s</lp%d:%s>" DEBUG_CR,
707
766
                     global_ns, info->name, value, global_ns, info->name);
708
767
  }
709
768
  else {
710
769
    /* assert: what == DAV_PROP_INSERT_SUPPORTED */
711
 
    s = apr_psprintf(response_pool,
 
770
    s = apr_psprintf(result_pool,
712
771
                     "<D:supported-live-property D:name=\"%s\" "
713
772
                     "D:namespace=\"%s\"/>" DEBUG_CR,
714
773
                     info->name, namespace_uris[info->ns]);
715
774
  }
716
 
  apr_text_append(response_pool, phdr, s);
 
775
  apr_text_append(result_pool, phdr, s);
717
776
 
718
777
  /* we inserted whatever was asked for */
719
778
  return what;
720
779
}
721
780
 
 
781
static dav_prop_insert
 
782
insert_prop(const dav_resource *resource,
 
783
            int propid,
 
784
            dav_prop_insert what,
 
785
            apr_text_header *phdr)
 
786
{
 
787
  apr_pool_t *result_pool = resource->pool;
 
788
  apr_pool_t *scratch_pool;
 
789
  dav_prop_insert rv;
 
790
 
 
791
  /* Create subpool and destroy on return, because mod_dav doesn't provide
 
792
     scratch pool for insert_prop() callback. */
 
793
  scratch_pool = svn_pool_create(result_pool);
 
794
 
 
795
  rv = insert_prop_internal(resource, propid, what, phdr,
 
796
                              scratch_pool, result_pool);
 
797
 
 
798
  svn_pool_destroy(scratch_pool);
 
799
  return rv;
 
800
}
722
801
 
723
802
static int
724
803
is_writable(const dav_resource *resource, int propid)
830
909
                              apr_text_header *phdr)
831
910
{
832
911
  const dav_liveprop_spec *spec;
833
 
  apr_pool_t *pool;
834
 
  apr_pool_t *subpool;
 
912
  apr_pool_t *iterpool;
835
913
 
836
914
  /* don't insert any liveprops if this isn't "our" resource */
837
915
  if (resource->hooks != &dav_svn__hooks_repository)
848
926
      return;
849
927
    }
850
928
 
851
 
  pool = resource->info->pool;
852
 
  subpool = svn_pool_create(pool);
853
 
  resource->info->pool = subpool;
854
 
 
 
929
  iterpool = svn_pool_create(resource->pool);
855
930
  for (spec = props; spec->name != NULL; ++spec)
856
931
    {
857
 
      svn_pool_clear(subpool);
858
 
      (void) insert_prop(resource, spec->propid, what, phdr);
 
932
      svn_pool_clear(iterpool);
 
933
      (void) insert_prop_internal(resource, spec->propid, what, phdr,
 
934
                                  iterpool, resource->pool);
859
935
    }
860
 
 
861
 
  resource->info->pool = pool;
862
 
  svn_pool_destroy(subpool);
 
936
  svn_pool_destroy(iterpool);
863
937
 
864
938
  /* ### we know the others aren't defined as liveprops */
865
939
}