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

« back to all changes in this revision

Viewing changes to subversion/mod_dav_svn/version.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
 * version.c: mod_dav_svn versioning provider functions for Subversion
3
3
 *
4
4
 * ====================================================================
5
 
 * Copyright (c) 2000-2007 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
 
35
40
#include "private/svn_repos_private.h"
36
41
#include "private/svn_dav_protocol.h"
37
42
#include "private/svn_log.h"
 
43
#include "private/svn_fspath.h"
38
44
 
39
45
#include "dav_svn.h"
40
46
 
79
85
 
80
86
  if (! (resource->type == DAV_RESOURCE_TYPE_WORKING
81
87
         && resource->info->auto_checked_out))
82
 
    return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
83
 
                         "Set_auto_revprops called on invalid resource.");
 
88
    return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
 
89
                              "Set_auto_revprops called on invalid resource.");
84
90
 
85
91
  if ((serr = dav_svn__attach_auto_revprops(resource->info->root.txn,
86
92
                                            resource->info->repos_path,
138
144
  /* Send SVN_RA_CAPABILITY_* capabilities. */
139
145
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_DEPTH);
140
146
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_LOG_REVPROPS);
 
147
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_ATOMIC_REVPROPS);
141
148
  apr_text_append(p, phdr, SVN_DAV_NS_DAV_SVN_PARTIAL_REPLAY);
142
149
  /* Mergeinfo is a special case: here we merely say that the server
143
150
   * knows how to handle mergeinfo -- whether the repository does too
162
169
           const apr_xml_elem *elem,
163
170
           apr_text_header *option)
164
171
{
 
172
  request_rec *r = resource->info->r;
 
173
  const char *repos_root_uri =
 
174
    dav_svn__build_uri(resource->info->repos, DAV_SVN__BUILD_URI_PUBLIC,
 
175
                       SVN_IGNORED_REVNUM, "", 0, resource->pool);
 
176
 
165
177
  /* ### DAV:version-history-collection-set */
166
 
 
167
178
  if (elem->ns == APR_XML_NS_DAV_ID)
168
179
    {
169
180
      if (strcmp(elem->name, "activity-collection-set") == 0)
181
192
        }
182
193
    }
183
194
 
 
195
  if (resource->info->repos->fs)
 
196
    {
 
197
      svn_error_t *serr;
 
198
      svn_revnum_t youngest;
 
199
      const char *uuid;
 
200
 
 
201
      /* Got youngest revision? */
 
202
      if ((serr = svn_fs_youngest_rev(&youngest, resource->info->repos->fs,
 
203
                                      resource->pool)))
 
204
        {
 
205
          return dav_svn__convert_err
 
206
            (serr, HTTP_INTERNAL_SERVER_ERROR,
 
207
             "Error fetching youngest revision from repository",
 
208
             resource->pool);
 
209
        }
 
210
      if (SVN_IS_VALID_REVNUM(youngest))
 
211
        {
 
212
          apr_table_set(r->headers_out,
 
213
                        SVN_DAV_YOUNGEST_REV_HEADER,
 
214
                        apr_psprintf(resource->pool, "%ld", youngest));
 
215
        }
 
216
 
 
217
      /* Got repository UUID? */
 
218
      if ((serr = svn_fs_get_uuid(resource->info->repos->fs,
 
219
                                  &uuid, resource->pool)))
 
220
        {
 
221
          return dav_svn__convert_err
 
222
            (serr, HTTP_INTERNAL_SERVER_ERROR,
 
223
             "Error fetching repository UUID",
 
224
             resource->pool);
 
225
        }
 
226
      if (uuid)
 
227
        {
 
228
          apr_table_set(r->headers_out,
 
229
                        SVN_DAV_REPOS_UUID_HEADER, uuid);
 
230
        }
 
231
    }
 
232
 
 
233
  /* Welcome to the 2nd generation of the svn HTTP protocol, now
 
234
     DeltaV-free!  If we're configured to advise this support, do so.  */
 
235
  if (resource->info->repos->v2_protocol)
 
236
    {
 
237
      apr_table_set(r->headers_out, SVN_DAV_ROOT_URI_HEADER, repos_root_uri);
 
238
      apr_table_set(r->headers_out, SVN_DAV_ME_RESOURCE_HEADER,
 
239
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
240
                                dav_svn__get_me_resource_uri(r), (char *)NULL));
 
241
      apr_table_set(r->headers_out, SVN_DAV_REV_ROOT_STUB_HEADER,
 
242
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
243
                                dav_svn__get_rev_root_stub(r), (char *)NULL));
 
244
      apr_table_set(r->headers_out, SVN_DAV_REV_STUB_HEADER,
 
245
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
246
                                dav_svn__get_rev_stub(r), (char *)NULL));
 
247
      apr_table_set(r->headers_out, SVN_DAV_TXN_ROOT_STUB_HEADER,
 
248
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
249
                                dav_svn__get_txn_root_stub(r), (char *)NULL));
 
250
      apr_table_set(r->headers_out, SVN_DAV_TXN_STUB_HEADER,
 
251
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
252
                                dav_svn__get_txn_stub(r), (char *)NULL));
 
253
      apr_table_set(r->headers_out, SVN_DAV_VTXN_ROOT_STUB_HEADER,
 
254
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
255
                                dav_svn__get_vtxn_root_stub(r), (char *)NULL));
 
256
      apr_table_set(r->headers_out, SVN_DAV_VTXN_STUB_HEADER,
 
257
                    apr_pstrcat(resource->pool, repos_root_uri, "/",
 
258
                                dav_svn__get_vtxn_stub(r), (char *)NULL));
 
259
    }
 
260
 
184
261
  return NULL;
185
262
}
186
263
 
232
309
  /* All mod_dav_svn resources are versioned objects;  so it doesn't
233
310
     make sense to call vsn_control on a resource that exists . */
234
311
  if (resource->exists)
235
 
    return dav_new_error(resource->pool, HTTP_BAD_REQUEST, 0,
236
 
                         "vsn_control called on already-versioned resource.");
 
312
    return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, 0,
 
313
                              "vsn_control called on already-versioned "
 
314
                              "resource.");
237
315
 
238
316
  /* Only allow a NULL target, which means an create an 'empty' VCR. */
239
317
  if (target != NULL)
270
348
  /* Auto-Versioning Stuff */
271
349
  if (auto_checkout)
272
350
    {
273
 
      dav_resource *res; /* ignored */
274
351
      const char *uuid_buf;
275
352
      void *data;
276
353
      const char *shared_activity, *shared_txn_name = NULL;
320
397
          uuid_buf = svn_uuid_generate(resource->info->r->pool);
321
398
          shared_activity = apr_pstrdup(resource->info->r->pool, uuid_buf);
322
399
 
323
 
          derr = dav_svn__create_activity(resource->info->repos,
324
 
                                          &shared_txn_name,
325
 
                                          resource->info->r->pool);
 
400
          derr = dav_svn__create_txn(resource->info->repos, &shared_txn_name,
 
401
                                     resource->info->r->pool);
326
402
          if (derr) return derr;
327
403
 
328
404
          derr = dav_svn__store_activity(resource->info->repos,
345
421
          shared_txn_name = dav_svn__get_txn(resource->info->repos,
346
422
                                             shared_activity);
347
423
          if (! shared_txn_name)
348
 
            return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
349
 
                                 "Cannot look up a txn_name by activity");
 
424
            return dav_svn__new_error(resource->pool,
 
425
                                      HTTP_INTERNAL_SERVER_ERROR, 0,
 
426
                                      "Cannot look up a txn_name by activity");
350
427
        }
351
428
 
352
429
      /* Tweak the VCR in-place, making it into a WR.  (Ignore the
353
430
         NULL return value.) */
354
 
      res = dav_svn__create_working_resource(resource,
355
 
                                             shared_activity, shared_txn_name,
356
 
                                             TRUE /* tweak in place */);
 
431
      dav_svn__create_working_resource(resource,
 
432
                                       shared_activity, shared_txn_name,
 
433
                                       TRUE /* tweak in place */);
357
434
 
358
435
      /* Remember that this resource was auto-checked-out, so that
359
436
         auto_versionable allows us to do an auto-checkin and
394
471
    {
395
472
      return dav_svn__new_error_tag(resource->pool, HTTP_NOT_IMPLEMENTED,
396
473
                                    SVN_ERR_UNSUPPORTED_FEATURE,
397
 
                                    "CHECKOUT can not create an activity at "
 
474
                                    "CHECKOUT cannot create an activity at "
398
475
                                    "this time. Use MKACTIVITY first.",
399
476
                                    SVN_DAV_ERROR_NAMESPACE,
400
477
                                    SVN_DAV_ERROR_TAG);
720
797
     subpool, then destroy it before exiting. */
721
798
  apr_pool_t *subpool = svn_pool_create(cdb->pool);
722
799
 
723
 
  err = svn_repos_open(&repos, cdb->repos_path, subpool);
 
800
  err = svn_repos_open2(&repos, cdb->repos_path, NULL, subpool);
724
801
  if (err)
725
802
    {
726
803
      ap_log_perror(APLOG_MARK, APLOG_ERR, err->apr_err, cdb->pool,
821
898
      shared_txn_name = dav_svn__get_txn(resource->info->repos,
822
899
                                         shared_activity);
823
900
      if (! shared_txn_name)
824
 
        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
825
 
                             "Cannot look up a txn_name by activity");
 
901
        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
 
902
                                  "Cannot look up a txn_name by activity");
826
903
 
827
904
      /* Sanity checks */
828
905
      if (resource->info->root.txn_name
829
906
          && (strcmp(shared_txn_name, resource->info->root.txn_name) != 0))
830
 
        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
831
 
                             "Internal txn_name doesn't match"
832
 
                             " autoversioning transaction.");
 
907
        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
 
908
                                  "Internal txn_name doesn't match "
 
909
                                  "autoversioning transaction.");
833
910
 
834
911
      if (! resource->info->root.txn)
835
912
        /* should already be open by checkout */
836
 
        return dav_new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
837
 
                             "Autoversioning txn isn't open "
838
 
                             "when it should be.");
 
913
        return dav_svn__new_error(resource->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
 
914
                                  "Autoversioning txn isn't open "
 
915
                                  "when it should be.");
839
916
 
840
917
      err = set_auto_revprops(resource);
841
918
      if (err)
892
969
            }
893
970
          else
894
971
            {
895
 
              return dav_new_error(resource->pool,
 
972
              return dav_svn__new_error(resource->pool,
896
973
                                        HTTP_INTERNAL_SERVER_ERROR,
897
974
                                        0,
898
975
                                        "Commit failed but there was no error "
1037
1114
   * be an activity URL.  Otherwise, it must be a real activity URL that
1038
1115
   * doesn't already exist.
1039
1116
   */
1040
 
  return (resource->info->auto_checked_out == TRUE ||
 
1117
  return (resource->info->auto_checked_out ||
1041
1118
          (resource->type == DAV_RESOURCE_TYPE_ACTIVITY &&
1042
1119
           !resource->exists));
1043
1120
}
1061
1138
                                  SVN_DAV_ERROR_NAMESPACE,
1062
1139
                                  SVN_DAV_ERROR_TAG);
1063
1140
 
1064
 
  err = dav_svn__create_activity(resource->info->repos, &txn_name,
1065
 
                                 resource->pool);
 
1141
  err = dav_svn__create_txn(resource->info->repos, &txn_name, resource->pool);
1066
1142
  if (err != NULL)
1067
1143
    return err;
1068
1144
 
1164
1240
                return derr;
1165
1241
 
1166
1242
              /* Create an absolute fs-path */
1167
 
              lockpath = svn_path_join(path_prefix, cdata, pool);
 
1243
              lockpath = svn_fspath__join(path_prefix, cdata, pool);
1168
1244
              if (lockpath && locktoken)
1169
1245
                {
1170
1246
                  apr_hash_set(hash, lockpath, APR_HASH_KEY_STRING, locktoken);
1294
1370
  /* ### what to verify on the target? */
1295
1371
 
1296
1372
  /* ### anything else for the source? */
1297
 
  if (source->type != DAV_RESOURCE_TYPE_ACTIVITY)
 
1373
  if (! (source->type == DAV_RESOURCE_TYPE_ACTIVITY
 
1374
         || (source->type == DAV_RESOURCE_TYPE_PRIVATE
 
1375
             && source->info->restype == DAV_SVN_RESTYPE_TXN_COLLECTION)))
1298
1376
    {
1299
1377
      return dav_svn__new_error_tag(pool, HTTP_METHOD_NOT_ALLOWED,
1300
1378
                                    SVN_ERR_INCORRECT_PARAMS,
1301
1379
                                    "MERGE can only be performed using an "
1302
 
                                    "activity as the source [at this time].",
 
1380
                                    "activity or transaction resource as the "
 
1381
                                    "source.",
 
1382
                                    SVN_DAV_ERROR_NAMESPACE,
 
1383
                                    SVN_DAV_ERROR_TAG);
 
1384
    }
 
1385
  if (! source->exists)
 
1386
    {
 
1387
      return dav_svn__new_error_tag(pool, HTTP_METHOD_NOT_ALLOWED,
 
1388
                                    SVN_ERR_INCORRECT_PARAMS,
 
1389
                                    "MERGE activity or transaction resource "
 
1390
                                    "does not exist.",
1303
1391
                                    SVN_DAV_ERROR_NAMESPACE,
1304
1392
                                    SVN_DAV_ERROR_TAG);
1305
1393
    }
1353
1441
          svn_error_clear(serr);
1354
1442
          serr = SVN_NO_ERROR;
1355
1443
        }
 
1444
 
 
1445
      /* HTTPv2 doesn't send DELETE after a successful MERGE so if
 
1446
         using the optional vtxn name mapping then delete it here. */
 
1447
      if (source->info->root.vtxn_name)
 
1448
        dav_svn__delete_activity(source->info->repos,
 
1449
                                 source->info->root.vtxn_name);
1356
1450
    }
1357
1451
  else
1358
1452
    {
1377
1471
        }
1378
1472
      else
1379
1473
        {
1380
 
          return dav_new_error(pool,
 
1474
          return dav_svn__new_error(pool,
1381
1475
                                    HTTP_INTERNAL_SERVER_ERROR,
1382
1476
                                    0,
1383
1477
                                    "Commit failed but there was no error "
1394
1488
                           svn_log__commit(new_rev, target->info->r->pool));
1395
1489
 
1396
1490
  /* Since the commit was successful, the txn ID is no longer valid.
1397
 
     Store an empty txn ID in the activity database so that when the
1398
 
     client deletes the activity, we don't try to open and abort the
1399
 
     transaction. */
1400
 
  err = dav_svn__store_activity(source->info->repos,
1401
 
                                source->info->root.activity_id, "");
1402
 
  if (err != NULL)
1403
 
    return err;
 
1491
     If we're using activities, store an empty txn ID in the activity
 
1492
     database so that when the client deletes the activity, we don't
 
1493
     try to open and abort the transaction. */
 
1494
  if (source->type == DAV_RESOURCE_TYPE_ACTIVITY)
 
1495
    {
 
1496
      err = dav_svn__store_activity(source->info->repos,
 
1497
                                    source->info->root.activity_id, "");
 
1498
      if (err != NULL)
 
1499
        return err;
 
1500
    }
1404
1501
 
1405
1502
  /* Check the dav_resource->info area for information about the
1406
1503
     special X-SVN-Options: header that may have come in the http