~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/libsvn_ra_serf/merge.c

  • Committer: Package Import Robot
  • Author(s): James McCoy, Peter Samuelson, James McCoy
  • Date: 2014-01-12 19:48:33 UTC
  • mfrom: (0.2.10)
  • Revision ID: package-import@ubuntu.com-20140112194833-w3axfwksn296jn5x
Tags: 1.8.5-1
[ Peter Samuelson ]
* New upstream release.  (Closes: #725787) Rediff patches:
  - Remove apr-abi1 (applied upstream), rename apr-abi2 to apr-abi
  - Remove loosen-sqlite-version-check (shouldn't be needed)
  - Remove java-osgi-metadata (applied upstream)
  - svnmucc prompts for a changelog if none is provided. (Closes: #507430)
  - Remove fix-bdb-version-detection, upstream uses "apu-config --dbm-libs"
  - Remove ruby-test-wc (applied upstream)
  - Fix “svn diff -r N file” when file has svn:mime-type set.
    (Closes: #734163)
  - Support specifying an encoding for mod_dav_svn's environment in which
    hooks are run.  (Closes: #601544)
  - Fix ordering of “svnadmin dump” paths with certain APR versions.
    (Closes: #687291)
  - Provide a better error message when authentication fails with an
    svn+ssh:// URL.  (Closes: #273874)
  - Updated Polish translations.  (Closes: #690815)

[ James McCoy ]
* Remove all traces of libneon, replaced by libserf.
* patches/sqlite_3.8.x_workaround: Upstream fix for wc-queries-test test
  failurse.
* Run configure with --with-apache-libexecdir, which allows removing part of
  patches/rpath.
* Re-enable auth-test as upstream has fixed the problem of picking up
  libraries from the environment rather than the build tree.
  (Closes: #654172)
* Point LD_LIBRARY_PATH at the built auth libraries when running the svn
  command during the build.  (Closes: #678224)
* Add a NEWS entry describing how to configure mod_dav_svn to understand
  UTF-8.  (Closes: #566148)
* Remove ancient transitional package, libsvn-ruby.
* Enable compatibility with Sqlite3 versions back to Wheezy.
* Enable hardening flags.  (Closes: #734918)
* patches/build-fixes: Enable verbose build logs.
* Build against the default ruby version.  (Closes: #722393)

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
#include <serf.h>
29
29
 
 
30
#include "svn_hash.h"
30
31
#include "svn_pools.h"
31
32
#include "svn_ra.h"
32
33
#include "svn_dav.h"
47
48
 * This enum represents the current state of our XML parsing for a MERGE.
48
49
 */
49
50
typedef enum merge_state_e {
50
 
  NONE = 0,
 
51
  INITIAL = 0,
51
52
  MERGE_RESPONSE,
52
53
  UPDATED_SET,
53
54
  RESPONSE,
55
56
  PROPSTAT,
56
57
  PROP,
57
58
  RESOURCE_TYPE,
 
59
  BASELINE,
 
60
  COLLECTION,
 
61
  SKIP_HREF,
 
62
  CHECKED_IN,
 
63
  VERSION_NAME,
 
64
  DATE,
58
65
  AUTHOR,
59
 
  NAME,
60
 
  DATE,
61
 
  IGNORE_PROP_NAME,
62
 
  NEED_PROP_NAME,
 
66
  POST_COMMIT_ERR,
 
67
 
63
68
  PROP_VAL
64
69
} merge_state_e;
65
70
 
66
 
typedef enum resource_type_e {
67
 
  UNSET,
68
 
  BASELINE,
69
 
  COLLECTION,
70
 
  CHECKED_IN
71
 
} resource_type_e;
72
 
 
73
 
typedef struct merge_info_t {
74
 
  /* Temporary allocations here please */
75
 
  apr_pool_t *pool;
76
 
 
77
 
  resource_type_e type;
78
 
 
79
 
  apr_hash_t *props;
80
 
 
81
 
  const char *prop_ns;
82
 
  const char *prop_name;
83
 
  const char *prop_val;
84
 
  apr_size_t prop_val_len;
85
 
} merge_info_t;
86
71
 
87
72
/* Structure associated with a MERGE request. */
88
 
struct svn_ra_serf__merge_context_t
 
73
typedef struct merge_context_t
89
74
{
90
75
  apr_pool_t *pool;
91
76
 
92
77
  svn_ra_serf__session_t *session;
 
78
  svn_ra_serf__handler_t *handler;
93
79
 
94
80
  apr_hash_t *lock_tokens;
95
81
  svn_boolean_t keep_locks;
97
83
  const char *merge_resource_url; /* URL of resource to be merged. */
98
84
  const char *merge_url; /* URL at which the MERGE request is aimed. */
99
85
 
100
 
  int status;
101
 
 
102
 
  svn_boolean_t done;
103
 
 
104
86
  svn_commit_info_t *commit_info;
 
87
 
 
88
} merge_context_t;
 
89
 
 
90
 
 
91
#define D_ "DAV:"
 
92
#define S_ SVN_XML_NAMESPACE
 
93
static const svn_ra_serf__xml_transition_t merge_ttable[] = {
 
94
  { INITIAL, D_, "merge-response", MERGE_RESPONSE,
 
95
    FALSE, { NULL }, FALSE },
 
96
 
 
97
  { MERGE_RESPONSE, D_, "updated-set", UPDATED_SET,
 
98
    FALSE, { NULL }, FALSE },
 
99
 
 
100
  { UPDATED_SET, D_, "response", RESPONSE,
 
101
    FALSE, { NULL }, TRUE },
 
102
 
 
103
  { RESPONSE, D_, "href", HREF,
 
104
    TRUE, { NULL }, TRUE },
 
105
 
 
106
  { RESPONSE, D_, "propstat", PROPSTAT,
 
107
    FALSE, { NULL }, FALSE },
 
108
 
 
109
#if 0
 
110
  /* Not needed.  */
 
111
  { PROPSTAT, D_, "status", STATUS,
 
112
    FALSE, { NULL }, FALSE },
 
113
#endif
 
114
 
 
115
  { PROPSTAT, D_, "prop", PROP,
 
116
    FALSE, { NULL }, FALSE },
 
117
 
 
118
  { PROP, D_, "resourcetype", RESOURCE_TYPE,
 
119
    FALSE, { NULL }, FALSE },
 
120
 
 
121
  { RESOURCE_TYPE, D_, "baseline", BASELINE,
 
122
    FALSE, { NULL }, TRUE },
 
123
 
 
124
  { RESOURCE_TYPE, D_, "collection", COLLECTION,
 
125
    FALSE, { NULL }, TRUE },
 
126
 
 
127
  { PROP, D_, "checked-in", SKIP_HREF,
 
128
    FALSE, { NULL }, FALSE },
 
129
 
 
130
  { SKIP_HREF, D_, "href", CHECKED_IN,
 
131
    TRUE, { NULL }, TRUE },
 
132
 
 
133
  { PROP, D_, SVN_DAV__VERSION_NAME, VERSION_NAME,
 
134
    TRUE, { NULL }, TRUE },
 
135
 
 
136
  { PROP, D_, SVN_DAV__CREATIONDATE, DATE,
 
137
    TRUE, { NULL }, TRUE },
 
138
 
 
139
  { PROP, D_, "creator-displayname", AUTHOR,
 
140
    TRUE, { NULL }, TRUE },
 
141
 
 
142
  { PROP, S_, "post-commit-err", POST_COMMIT_ERR,
 
143
    TRUE, { NULL }, TRUE },
 
144
 
 
145
  { 0 }
105
146
};
106
147
 
107
 
 
108
 
static merge_info_t *
109
 
push_state(svn_ra_serf__xml_parser_t *parser,
110
 
           svn_ra_serf__merge_context_t *ctx,
111
 
           merge_state_e state)
112
 
{
113
 
  merge_info_t *info;
114
 
 
115
 
  svn_ra_serf__xml_push_state(parser, state);
116
 
 
117
 
  if (state == RESPONSE)
118
 
    {
119
 
      info = apr_palloc(parser->state->pool, sizeof(*info));
120
 
      info->pool = parser->state->pool;
121
 
      info->props = apr_hash_make(info->pool);
122
 
 
123
 
      parser->state->private = info;
124
 
    }
125
 
 
126
 
  return parser->state->private;
127
 
}
128
 
 
129
 
static svn_error_t *
130
 
start_merge(svn_ra_serf__xml_parser_t *parser,
131
 
            void *userData,
132
 
            svn_ra_serf__dav_props_t name,
133
 
            const char **attrs)
134
 
{
135
 
  svn_ra_serf__merge_context_t *ctx = userData;
136
 
  merge_state_e state;
137
 
  merge_info_t *info;
138
 
 
139
 
  state = parser->state->current_state;
140
 
 
141
 
  if (state == NONE &&
142
 
      strcmp(name.name, "merge-response") == 0)
143
 
    {
144
 
      push_state(parser, ctx, MERGE_RESPONSE);
145
 
    }
146
 
  else if (state == NONE)
147
 
    {
148
 
      /* do nothing as we haven't seen our valid start tag yet. */
149
 
    }
150
 
  else if (state == MERGE_RESPONSE &&
151
 
           strcmp(name.name, "updated-set") == 0)
152
 
    {
153
 
      push_state(parser, ctx, UPDATED_SET);
154
 
    }
155
 
  else if (state == UPDATED_SET &&
156
 
           strcmp(name.name, "response") == 0)
157
 
    {
158
 
      push_state(parser, ctx, RESPONSE);
159
 
    }
160
 
  else if (state == RESPONSE &&
161
 
           strcmp(name.name, "href") == 0)
162
 
    {
163
 
      info = push_state(parser, ctx, PROP_VAL);
164
 
 
165
 
      info->prop_ns = name.namespace;
166
 
      info->prop_name = apr_pstrdup(info->pool, name.name);
167
 
      info->prop_val = NULL;
168
 
      info->prop_val_len = 0;
169
 
    }
170
 
  else if (state == RESPONSE &&
171
 
           strcmp(name.name, "propstat") == 0)
172
 
    {
173
 
      push_state(parser, ctx, PROPSTAT);
174
 
    }
175
 
  else if (state == PROPSTAT &&
176
 
           strcmp(name.name, "prop") == 0)
177
 
    {
178
 
      push_state(parser, ctx, PROP);
179
 
    }
180
 
  else if (state == PROPSTAT &&
181
 
           strcmp(name.name, "status") == 0)
182
 
    {
183
 
      /* Do nothing for now. */
184
 
    }
185
 
  else if (state == PROP &&
186
 
           strcmp(name.name, "resourcetype") == 0)
187
 
    {
188
 
      info = push_state(parser, ctx, RESOURCE_TYPE);
189
 
      info->type = UNSET;
190
 
    }
191
 
  else if (state == RESOURCE_TYPE &&
192
 
           strcmp(name.name, "baseline") == 0)
193
 
    {
194
 
      info = parser->state->private;
195
 
 
196
 
      info->type = BASELINE;
197
 
    }
198
 
  else if (state == RESOURCE_TYPE &&
199
 
           strcmp(name.name, "collection") == 0)
200
 
    {
201
 
      info = parser->state->private;
202
 
 
203
 
      info->type = COLLECTION;
204
 
    }
205
 
  else if (state == PROP &&
206
 
           strcmp(name.name, "checked-in") == 0)
207
 
    {
208
 
      info = push_state(parser, ctx, IGNORE_PROP_NAME);
209
 
 
210
 
      info->prop_ns = name.namespace;
211
 
      info->prop_name = apr_pstrdup(info->pool, name.name);
212
 
      info->prop_val = NULL;
213
 
      info->prop_val_len = 0;
214
 
    }
215
 
  else if (state == PROP)
216
 
    {
217
 
      push_state(parser, ctx, PROP_VAL);
218
 
    }
219
 
  else if (state == IGNORE_PROP_NAME)
220
 
    {
221
 
      push_state(parser, ctx, PROP_VAL);
222
 
    }
223
 
  else if (state == NEED_PROP_NAME)
224
 
    {
225
 
      info = push_state(parser, ctx, PROP_VAL);
226
 
      info->prop_ns = name.namespace;
227
 
      info->prop_name = apr_pstrdup(info->pool, name.name);
228
 
      info->prop_val = NULL;
229
 
      info->prop_val_len = 0;
230
 
    }
231
 
  else
232
 
    {
233
 
      SVN_ERR_MALFUNCTION();
234
 
    }
235
 
 
236
 
  return SVN_NO_ERROR;
237
 
}
238
 
 
239
 
static svn_error_t *
240
 
end_merge(svn_ra_serf__xml_parser_t *parser,
241
 
          void *userData,
242
 
          svn_ra_serf__dav_props_t name)
243
 
{
244
 
  svn_ra_serf__merge_context_t *ctx = userData;
245
 
  merge_state_e state;
246
 
  merge_info_t *info;
247
 
 
248
 
  state = parser->state->current_state;
249
 
  info = parser->state->private;
250
 
 
251
 
  if (state == NONE)
252
 
    {
253
 
      /* nothing to close yet. */
254
 
      return SVN_NO_ERROR;
255
 
    }
256
 
 
257
 
  if (state == RESPONSE &&
258
 
      strcmp(name.name, "response") == 0)
259
 
    {
260
 
      if (info->type == BASELINE)
 
148
 
 
149
/* Conforms to svn_ra_serf__xml_closed_t  */
 
150
static svn_error_t *
 
151
merge_closed(svn_ra_serf__xml_estate_t *xes,
 
152
             void *baton,
 
153
             int leaving_state,
 
154
             const svn_string_t *cdata,
 
155
             apr_hash_t *attrs,
 
156
             apr_pool_t *scratch_pool)
 
157
{
 
158
  merge_context_t *merge_ctx = baton;
 
159
 
 
160
  if (leaving_state == RESPONSE)
 
161
    {
 
162
      const char *rtype;
 
163
 
 
164
      rtype = svn_hash_gets(attrs, "resourcetype");
 
165
 
 
166
      /* rtype can only be "baseline" or "collection" (or NULL). We can
 
167
         keep this check simple.  */
 
168
      if (rtype && *rtype == 'b')
261
169
        {
262
 
          const char *str;
 
170
          const char *rev_str;
263
171
 
264
 
          str = apr_hash_get(info->props, SVN_DAV__VERSION_NAME,
265
 
                             APR_HASH_KEY_STRING);
266
 
          if (str)
267
 
            {
268
 
              ctx->commit_info->revision = SVN_STR_TO_REV(str);
269
 
            }
 
172
          rev_str = svn_hash_gets(attrs, "revision");
 
173
          if (rev_str)
 
174
            merge_ctx->commit_info->revision = SVN_STR_TO_REV(rev_str);
270
175
          else
271
 
            {
272
 
              ctx->commit_info->revision = SVN_INVALID_REVNUM;
273
 
            }
274
 
 
275
 
          ctx->commit_info->date =
276
 
              apr_pstrdup(ctx->pool,
277
 
                          apr_hash_get(info->props, SVN_DAV__CREATIONDATE,
278
 
                                       APR_HASH_KEY_STRING));
279
 
 
280
 
          ctx->commit_info->author =
281
 
              apr_pstrdup(ctx->pool,
282
 
                          apr_hash_get(info->props, "creator-displayname",
283
 
                                       APR_HASH_KEY_STRING));
284
 
 
285
 
          ctx->commit_info->post_commit_err =
286
 
             apr_pstrdup(ctx->pool,
287
 
                         apr_hash_get(info->props,
288
 
                                      "post-commit-err", APR_HASH_KEY_STRING));
 
176
            merge_ctx->commit_info->revision = SVN_INVALID_REVNUM;
 
177
 
 
178
          merge_ctx->commit_info->date =
 
179
              apr_pstrdup(merge_ctx->pool,
 
180
                          svn_hash_gets(attrs, "date"));
 
181
 
 
182
          merge_ctx->commit_info->author =
 
183
              apr_pstrdup(merge_ctx->pool,
 
184
                          svn_hash_gets(attrs, "author"));
 
185
 
 
186
          merge_ctx->commit_info->post_commit_err =
 
187
             apr_pstrdup(merge_ctx->pool,
 
188
                         svn_hash_gets(attrs, "post-commit-err"));
289
189
        }
290
190
      else
291
191
        {
292
192
          const char *href;
293
193
 
294
 
          href = apr_hash_get(info->props, "href", APR_HASH_KEY_STRING);
295
 
          if (! svn_urlpath__is_ancestor(ctx->merge_url, href))
296
 
            {
297
 
              return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
298
 
                                       _("A MERGE response for '%s' is not "
299
 
                                         "a child of the destination ('%s')"),
300
 
                                       href, ctx->merge_url);
301
 
            }
 
194
          href = svn_urlpath__skip_ancestor(
 
195
                   merge_ctx->merge_url,
 
196
                   svn_hash_gets(attrs, "href"));
 
197
 
 
198
          if (href == NULL)
 
199
            return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
 
200
                                     _("A MERGE response for '%s' is not "
 
201
                                       "a child of the destination ('%s')"),
 
202
                                     href, merge_ctx->merge_url);
302
203
 
303
204
          /* We now need to dive all the way into the WC to update the
304
 
           * base VCC url.
305
 
           */
306
 
          if ((! SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(ctx->session))
307
 
              && ctx->session->wc_callbacks->push_wc_prop)
 
205
             base VCC url.  */
 
206
          if (!SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(merge_ctx->session)
 
207
              && merge_ctx->session->wc_callbacks->push_wc_prop)
308
208
            {
 
209
              const char *checked_in;
309
210
              svn_string_t checked_in_str;
310
 
              const char *checked_in;
311
 
 
312
 
              /* From the above check, we know that CTX->MERGE_URL is
313
 
                 an ancestor of HREF.  All that remains is to
314
 
                 determine of HREF is the same as CTX->MERGE_URL, or --
315
 
                 if not -- is relative value as a child thereof. */
316
 
              href = svn_urlpath__is_child(ctx->merge_url, href, NULL);
317
 
              if (! href)
318
 
                href = "";
319
 
 
320
 
              checked_in = apr_hash_get(info->props, "checked-in",
321
 
                                        APR_HASH_KEY_STRING);
 
211
 
 
212
              checked_in = svn_hash_gets(attrs, "checked-in");
322
213
              checked_in_str.data = checked_in;
323
214
              checked_in_str.len = strlen(checked_in);
324
215
 
325
 
              SVN_ERR(ctx->session->wc_callbacks->push_wc_prop(
326
 
                ctx->session->wc_callback_baton, href,
327
 
                SVN_RA_SERF__WC_CHECKED_IN_URL, &checked_in_str, info->pool));
 
216
              SVN_ERR(merge_ctx->session->wc_callbacks->push_wc_prop(
 
217
                        merge_ctx->session->wc_callback_baton,
 
218
                        href,
 
219
                        SVN_RA_SERF__WC_CHECKED_IN_URL,
 
220
                        &checked_in_str,
 
221
                        scratch_pool));
328
222
            }
329
223
        }
330
 
 
331
 
      svn_ra_serf__xml_pop_state(parser);
332
 
    }
333
 
  else if (state == PROPSTAT &&
334
 
           strcmp(name.name, "propstat") == 0)
335
 
    {
336
 
      svn_ra_serf__xml_pop_state(parser);
337
 
    }
338
 
  else if (state == PROP &&
339
 
           strcmp(name.name, "prop") == 0)
340
 
    {
341
 
      svn_ra_serf__xml_pop_state(parser);
342
 
    }
343
 
  else if (state == RESOURCE_TYPE &&
344
 
           strcmp(name.name, "resourcetype") == 0)
345
 
    {
346
 
      svn_ra_serf__xml_pop_state(parser);
347
 
    }
348
 
  else if (state == IGNORE_PROP_NAME || state == NEED_PROP_NAME)
349
 
    {
350
 
      svn_ra_serf__xml_pop_state(parser);
351
 
    }
352
 
  else if (state == PROP_VAL)
353
 
    {
354
 
      if (!info->prop_name)
355
 
        {
356
 
          info->prop_name = apr_pstrdup(info->pool, name.name);
357
 
        }
358
 
      info->prop_val = apr_pstrmemdup(info->pool, info->prop_val,
359
 
                                      info->prop_val_len);
360
 
      if (strcmp(info->prop_name, "href") == 0)
361
 
        info->prop_val = svn_urlpath__canonicalize(info->prop_val,
362
 
                                                       info->pool);
363
 
 
364
 
      /* Set our property. */
365
 
      apr_hash_set(info->props, info->prop_name, APR_HASH_KEY_STRING,
366
 
                   info->prop_val);
367
 
 
368
 
      info->prop_ns = NULL;
369
 
      info->prop_name = NULL;
370
 
      info->prop_val = NULL;
371
 
      info->prop_val_len = 0;
372
 
 
373
 
      svn_ra_serf__xml_pop_state(parser);
374
 
    }
375
 
 
376
 
  return SVN_NO_ERROR;
377
 
}
378
 
 
379
 
static svn_error_t *
380
 
cdata_merge(svn_ra_serf__xml_parser_t *parser,
381
 
            void *userData,
382
 
            const char *data,
383
 
            apr_size_t len)
384
 
{
385
 
  svn_ra_serf__merge_context_t *ctx = userData;
386
 
  merge_state_e state;
387
 
  merge_info_t *info;
388
 
 
389
 
  UNUSED_CTX(ctx);
390
 
 
391
 
  state = parser->state->current_state;
392
 
  info = parser->state->private;
393
 
 
394
 
  if (state == PROP_VAL)
395
 
    {
396
 
      svn_ra_serf__expand_string(&info->prop_val, &info->prop_val_len,
397
 
                                 data, len, parser->state->pool);
398
 
    }
399
 
 
400
 
  return SVN_NO_ERROR;
401
 
}
 
224
    }
 
225
  else if (leaving_state == BASELINE)
 
226
    {
 
227
      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "baseline");
 
228
    }
 
229
  else if (leaving_state == COLLECTION)
 
230
    {
 
231
      svn_ra_serf__xml_note(xes, RESPONSE, "resourcetype", "collection");
 
232
    }
 
233
  else
 
234
    {
 
235
      const char *name;
 
236
      const char *value = cdata->data;
 
237
 
 
238
      if (leaving_state == HREF)
 
239
        {
 
240
          name = "href";
 
241
          value = svn_urlpath__canonicalize(value, scratch_pool);
 
242
        }
 
243
      else if (leaving_state == CHECKED_IN)
 
244
        {
 
245
          name = "checked-in";
 
246
          value = svn_urlpath__canonicalize(value, scratch_pool);
 
247
        }
 
248
      else if (leaving_state == VERSION_NAME)
 
249
        name = "revision";
 
250
      else if (leaving_state == DATE)
 
251
        name = "date";
 
252
      else if (leaving_state == AUTHOR)
 
253
        name = "author";
 
254
      else if (leaving_state == POST_COMMIT_ERR)
 
255
        name = "post-commit-err";
 
256
      else
 
257
        SVN_ERR_MALFUNCTION();
 
258
 
 
259
      svn_ra_serf__xml_note(xes, RESPONSE, name, value);
 
260
    }
 
261
 
 
262
  return SVN_NO_ERROR;
 
263
}
 
264
 
402
265
 
403
266
static svn_error_t *
404
267
setup_merge_headers(serf_bucket_t *headers,
405
268
                    void *baton,
406
269
                    apr_pool_t *pool)
407
270
{
408
 
  svn_ra_serf__merge_context_t *ctx = baton;
 
271
  merge_context_t *ctx = baton;
409
272
 
410
273
  if (!ctx->keep_locks)
411
274
    {
447
310
      path.data = key;
448
311
      path.len = klen;
449
312
 
450
 
      if (parent && !svn_relpath__is_ancestor(parent, key))
 
313
      if (parent && !svn_relpath_skip_ancestor(parent, key))
451
314
        continue;
452
315
 
453
316
      svn_ra_serf__add_open_tag_buckets(body, alloc, "S:lock", NULL);
470
333
                  serf_bucket_alloc_t *alloc,
471
334
                  apr_pool_t *pool)
472
335
{
473
 
  svn_ra_serf__merge_context_t *ctx = baton;
 
336
  merge_context_t *ctx = baton;
474
337
  serf_bucket_t *body_bkt;
475
338
 
476
339
  body_bkt = serf_bucket_aggregate_create(alloc);
512
375
 
513
376
 
514
377
svn_error_t *
515
 
svn_ra_serf__merge_create_req(svn_ra_serf__merge_context_t **ret_ctx,
516
 
                              svn_ra_serf__session_t *session,
517
 
                              svn_ra_serf__connection_t *conn,
518
 
                              const char *merge_resource_url,
519
 
                              apr_hash_t *lock_tokens,
520
 
                              svn_boolean_t keep_locks,
521
 
                              apr_pool_t *pool)
 
378
svn_ra_serf__run_merge(const svn_commit_info_t **commit_info,
 
379
                       int *response_code,
 
380
                       svn_ra_serf__session_t *session,
 
381
                       svn_ra_serf__connection_t *conn,
 
382
                       const char *merge_resource_url,
 
383
                       apr_hash_t *lock_tokens,
 
384
                       svn_boolean_t keep_locks,
 
385
                       apr_pool_t *result_pool,
 
386
                       apr_pool_t *scratch_pool)
522
387
{
523
 
  svn_ra_serf__merge_context_t *merge_ctx;
 
388
  merge_context_t *merge_ctx;
524
389
  svn_ra_serf__handler_t *handler;
525
 
  svn_ra_serf__xml_parser_t *parser_ctx;
526
 
 
527
 
  merge_ctx = apr_pcalloc(pool, sizeof(*merge_ctx));
528
 
 
529
 
  merge_ctx->pool = pool;
 
390
  svn_ra_serf__xml_context_t *xmlctx;
 
391
 
 
392
  merge_ctx = apr_pcalloc(scratch_pool, sizeof(*merge_ctx));
 
393
 
 
394
  merge_ctx->pool = result_pool;
530
395
  merge_ctx->session = session;
531
396
 
532
397
  merge_ctx->merge_resource_url = merge_resource_url;
534
399
  merge_ctx->lock_tokens = lock_tokens;
535
400
  merge_ctx->keep_locks = keep_locks;
536
401
 
537
 
  merge_ctx->commit_info = svn_create_commit_info(pool);
 
402
  merge_ctx->commit_info = svn_create_commit_info(result_pool);
538
403
 
539
404
  merge_ctx->merge_url = session->session_url.path;
540
405
 
541
 
  handler = apr_pcalloc(pool, sizeof(*handler));
 
406
  xmlctx = svn_ra_serf__xml_context_create(merge_ttable,
 
407
                                           NULL, merge_closed, NULL,
 
408
                                           merge_ctx,
 
409
                                           scratch_pool);
 
410
  handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
542
411
 
543
412
  handler->method = "MERGE";
544
413
  handler->path = merge_ctx->merge_url;
547
416
  handler->conn = conn;
548
417
  handler->session = session;
549
418
 
550
 
  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
551
 
 
552
 
  parser_ctx->pool = pool;
553
 
  parser_ctx->user_data = merge_ctx;
554
 
  parser_ctx->start = start_merge;
555
 
  parser_ctx->end = end_merge;
556
 
  parser_ctx->cdata = cdata_merge;
557
 
  parser_ctx->done = &merge_ctx->done;
558
 
  parser_ctx->status_code = &merge_ctx->status;
559
 
 
560
419
  handler->header_delegate = setup_merge_headers;
561
420
  handler->header_delegate_baton = merge_ctx;
562
421
 
563
 
  handler->response_handler = svn_ra_serf__handle_xml_parser;
564
 
  handler->response_baton = parser_ctx;
565
 
 
566
 
  svn_ra_serf__request_create(handler);
567
 
 
568
 
  *ret_ctx = merge_ctx;
 
422
  merge_ctx->handler = handler;
 
423
 
 
424
  SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
 
425
 
 
426
  *commit_info = merge_ctx->commit_info;
 
427
  *response_code = handler->sline.code;
569
428
 
570
429
  return SVN_NO_ERROR;
571
430
}
572
 
 
573
 
svn_boolean_t*
574
 
svn_ra_serf__merge_get_done_ptr(svn_ra_serf__merge_context_t *ctx)
575
 
{
576
 
  return &ctx->done;
577
 
}
578
 
 
579
 
svn_commit_info_t*
580
 
svn_ra_serf__merge_get_commit_info(svn_ra_serf__merge_context_t *ctx)
581
 
{
582
 
  return ctx->commit_info;
583
 
}
584
 
 
585
 
int
586
 
svn_ra_serf__merge_get_status(svn_ra_serf__merge_context_t *ctx)
587
 
{
588
 
  return ctx->status;
589
 
}