2
* atomic-ra-revprop-change.c : wrapper around svn_ra_change_rev_prop2()
4
* ====================================================================
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
13
* http://www.apache.org/licenses/LICENSE-2.0
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
21
* ====================================================================
27
#include <apr_pools.h>
28
#include <apr_general.h>
30
#include "svn_types.h"
31
#include "svn_pools.h"
32
#include "svn_dirent_uri.h"
35
#include "private/svn_skel.h"
37
#include "svn_private_config.h"
40
#define KEY_OLD_PROPVAL "old_value_p"
41
#define KEY_NEW_PROPVAL "value"
44
"Usage: %s URL REVISION PROPNAME VALUES_SKEL HTTP_LIBRARY WANT_ERROR\n" \
46
"VALUES_SKEL is a proplist skel containing pseudo-properties '%s' \n" \
47
"and '%s'. A pseudo-property missing from the skel is interpreted \n" \
50
"WANT_ERROR is 1 if the propchange is expected to fail due to the atomicity,"\
51
"and 0 if it is expected to succeed. If the expectation matches reality," \
52
"the exit code shall be zero.\n"
56
/* implements svn_auth_simple_prompt_func_t */
58
aborting_simple_prompt_func(svn_auth_cred_simple_t **cred,
62
svn_boolean_t may_save,
65
/* Oops, the jrandom:rayjandom we passed for SVN_AUTH_PARAM_DEFAULT_* failed,
66
and the prompt provider has retried.
68
SVN_ERR_MALFUNCTION();
71
/* implements svn_auth_username_prompt_func_t */
73
aborting_username_prompt_func(svn_auth_cred_username_t **cred,
76
svn_boolean_t may_save,
79
/* Oops, the jrandom:rayjandom we passed for SVN_AUTH_PARAM_DEFAULT_* failed,
80
and the prompt provider has retried.
82
SVN_ERR_MALFUNCTION();
86
construct_auth_baton(svn_auth_baton_t **auth_baton_p,
89
apr_array_header_t *providers;
90
svn_auth_provider_object_t *simple_provider;
91
svn_auth_baton_t *auth_baton;
93
/* A bit of dancing just to pass jrandom:rayjandom. */
94
providers = apr_array_make(pool, 2, sizeof(svn_auth_provider_object_t *)),
95
svn_auth_get_simple_prompt_provider(&simple_provider,
96
aborting_simple_prompt_func, NULL,
98
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = simple_provider;
99
svn_auth_get_username_prompt_provider(&simple_provider,
100
aborting_username_prompt_func, NULL,
102
APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = simple_provider;
103
svn_auth_open(&auth_baton, providers, pool);
104
svn_auth_set_parameter(auth_baton,
105
SVN_AUTH_PARAM_DEFAULT_USERNAME, "jrandom");
106
svn_auth_set_parameter(auth_baton,
107
SVN_AUTH_PARAM_DEFAULT_PASSWORD, "rayjandom");
109
*auth_baton_p = auth_baton;
114
construct_config(apr_hash_t **config_p,
115
const char *http_library,
119
svn_config_t *servers;
121
/* Populate SERVERS. */
122
SVN_ERR(svn_config_create(&servers, FALSE, pool));
123
svn_config_set(servers, SVN_CONFIG_SECTION_GLOBAL,
124
SVN_CONFIG_OPTION_HTTP_LIBRARY, http_library);
126
/* Populate CONFIG. */
127
config = apr_hash_make(pool);
128
apr_hash_set(config, SVN_CONFIG_CATEGORY_SERVERS,
129
APR_HASH_KEY_STRING, servers);
136
change_rev_prop(const char *url,
137
svn_revnum_t revision,
138
const char *propname,
139
const svn_string_t *propval,
140
const svn_string_t *old_value,
141
const char *http_library,
142
svn_boolean_t want_error,
145
svn_ra_callbacks2_t *callbacks;
146
svn_ra_session_t *sess;
148
svn_boolean_t capable;
151
SVN_ERR(svn_ra_create_callbacks(&callbacks, pool));
152
SVN_ERR(construct_auth_baton(&callbacks->auth_baton, pool));
153
SVN_ERR(construct_config(&config, http_library, pool));
155
SVN_ERR(svn_ra_open4(&sess, NULL, url, NULL, callbacks, NULL /* baton */,
158
SVN_ERR(svn_ra_has_capability(sess, &capable,
159
SVN_RA_CAPABILITY_ATOMIC_REVPROPS,
163
err = svn_ra_change_rev_prop2(sess, revision, propname,
164
&old_value, propval, pool);
166
if (want_error && err
167
&& svn_error_find_cause(err, SVN_ERR_FS_PROP_BASEVALUE_MISMATCH))
169
/* Expectation was matched. Get out. */
170
svn_error_clear(err);
173
else if (! want_error && ! err)
174
/* Expectation was matched. Get out. */
176
else if (want_error && ! err)
177
return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
178
"An error was expected but not seen");
180
/* A real (non-SVN_ERR_FS_PROP_BASEVALUE_MISMATCH) error. */
181
return svn_error_trace(err);
184
/* Running under --server-minor-version? */
185
return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
186
"Server doesn't advertise "
187
"SVN_RA_CAPABILITY_ATOMIC_REVPROPS");
190
/* Parse SKEL_CSTR according to the description in USAGE_MSG. */
192
extract_values_from_skel(svn_string_t **old_propval_p,
193
svn_string_t **propval_p,
194
const char *skel_cstr,
197
apr_hash_t *proplist;
200
skel = svn_skel__parse(skel_cstr, strlen(skel_cstr), pool);
201
SVN_ERR(svn_skel__parse_proplist(&proplist, skel, pool));
202
*old_propval_p = apr_hash_get(proplist, KEY_OLD_PROPVAL, APR_HASH_KEY_STRING);
203
*propval_p = apr_hash_get(proplist, KEY_NEW_PROPVAL, APR_HASH_KEY_STRING);
209
main(int argc, const char *argv[])
212
int exit_code = EXIT_SUCCESS;
215
svn_revnum_t revision;
216
const char *propname;
217
svn_string_t *propval;
218
svn_string_t *old_propval;
219
const char *http_library;
220
char *digits_end = NULL;
221
svn_boolean_t want_error;
225
fprintf(stderr, USAGE_MSG, argv[0], KEY_OLD_PROPVAL, KEY_NEW_PROPVAL);
229
if (apr_initialize() != APR_SUCCESS)
231
fprintf(stderr, "apr_initialize() failed.\n");
235
/* set up the global pool */
236
pool = svn_pool_create(NULL);
239
url = svn_uri_canonicalize(argv[1], pool);
240
revision = strtol(argv[2], &digits_end, 10);
242
SVN_INT_ERR(extract_values_from_skel(&old_propval, &propval, argv[4], pool));
243
http_library = argv[5];
244
want_error = !strcmp(argv[6], "1");
246
if ((! SVN_IS_VALID_REVNUM(revision)) || (! digits_end) || *digits_end)
247
SVN_INT_ERR(svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
248
_("Invalid revision number supplied")));
251
err = change_rev_prop(url, revision, propname, propval, old_propval,
252
http_library, want_error, pool);
255
svn_handle_error2(err, stderr, FALSE, "atomic-ra-revprop-change: ");
256
svn_error_clear(err);
257
exit_code = EXIT_FAILURE;
260
/* Clean up, and get outta here */
261
svn_pool_destroy(pool);