|
Lines 138-144
Link Here
|
| 138 |
|
138 |
|
| 139 |
|
139 |
|
| 140 |
|
140 |
|
| 141 |
/*** Property change wrappers ***/ |
141 |
/*** Property wrappers ***/ |
| 142 |
|
142 |
|
| 143 |
/* Validate that property NAME is valid for use in a Subversion |
143 |
/* Validate that property NAME is valid for use in a Subversion |
| 144 |
repository. */ |
144 |
repository. */ |
|
Lines 182-188
Link Here
|
| 182 |
} |
182 |
} |
| 183 |
|
183 |
|
| 184 |
|
184 |
|
|
|
185 |
/* A revision's changed paths are either all readable, all unreadable, |
| 186 |
or a mixture of the two. */ |
| 187 |
enum rev_readability_level |
| 188 |
{ |
| 189 |
rev_readable = 1, |
| 190 |
rev_partially_readable, |
| 191 |
rev_unreadable |
| 192 |
}; |
| 193 |
|
| 194 |
|
| 195 |
/* Helper func: examine the changed-paths of REV in FS using |
| 196 |
AUTHZ_READ_FUNC. Set *CAN_READ to one of the three |
| 197 |
readability_level enum values. Use POOL for invoking the authz func. */ |
| 198 |
static svn_error_t * |
| 199 |
get_readability (int *can_read, |
| 200 |
svn_fs_t *fs, |
| 201 |
svn_revnum_t rev, |
| 202 |
svn_repos_authz_func_t authz_read_func, |
| 203 |
void *authz_read_baton, |
| 204 |
apr_pool_t *pool) |
| 205 |
{ |
| 206 |
svn_fs_root_t *root; |
| 207 |
apr_hash_t *changes; |
| 208 |
apr_hash_index_t *hi; |
| 209 |
apr_pool_t *subpool = svn_pool_create (pool); |
| 210 |
svn_boolean_t found_readable = FALSE, found_unreadable = FALSE; |
| 211 |
|
| 212 |
SVN_ERR (svn_fs_revision_root (&root, fs, rev, pool)); |
| 213 |
SVN_ERR (svn_fs_paths_changed (&changes, root, pool)); |
| 214 |
|
| 215 |
if (apr_hash_count (changes) == 0) |
| 216 |
{ |
| 217 |
/* No paths changed in this revision? Uh, sure, I guess the |
| 218 |
revision is readable, then. */ |
| 219 |
*can_read = rev_readable; |
| 220 |
return SVN_NO_ERROR; |
| 221 |
} |
| 222 |
|
| 223 |
for (hi = apr_hash_first (pool, changes); hi; hi = apr_hash_next (hi)) |
| 224 |
{ |
| 225 |
const void *key; |
| 226 |
const char *path; |
| 227 |
svn_boolean_t readable; |
| 228 |
|
| 229 |
svn_pool_clear (subpool); |
| 230 |
|
| 231 |
apr_hash_this (hi, &key, NULL, NULL); |
| 232 |
path = (const char *) key; |
| 233 |
|
| 234 |
SVN_ERR (authz_read_func (&readable, root, path, |
| 235 |
authz_read_baton, subpool)); |
| 236 |
if (readable) |
| 237 |
found_readable = TRUE; |
| 238 |
else |
| 239 |
found_unreadable = TRUE; |
| 240 |
} |
| 241 |
|
| 242 |
svn_pool_destroy (subpool); |
| 243 |
|
| 244 |
if (found_unreadable && (! found_readable)) |
| 245 |
*can_read = rev_unreadable; |
| 246 |
else if (found_readable && (! found_unreadable)) |
| 247 |
*can_read = rev_readable; |
| 248 |
else /* found both readable and unreadable */ |
| 249 |
*can_read = rev_partially_readable; |
| 250 |
|
| 251 |
return SVN_NO_ERROR; |
| 252 |
} |
| 253 |
|
| 254 |
|
| 185 |
svn_error_t * |
255 |
svn_error_t * |
|
|
256 |
svn_repos__fs_change_rev_prop2 (svn_repos_t *repos, |
| 257 |
svn_revnum_t rev, |
| 258 |
const char *author, |
| 259 |
const char *name, |
| 260 |
const svn_string_t *new_value, |
| 261 |
svn_repos_authz_func_t authz_read_func, |
| 262 |
void *authz_read_baton, |
| 263 |
apr_pool_t *pool) |
| 264 |
{ |
| 265 |
svn_string_t *old_value; |
| 266 |
int readability = rev_readable; |
| 267 |
|
| 268 |
if (authz_read_func) |
| 269 |
SVN_ERR (get_readability (&readability, repos->fs, rev, |
| 270 |
authz_read_func, authz_read_baton, pool)); |
| 271 |
if (readability == rev_readable) |
| 272 |
{ |
| 273 |
SVN_ERR (validate_prop (name, pool)); |
| 274 |
SVN_ERR (svn_fs_revision_prop (&old_value, repos->fs, rev, name, pool)); |
| 275 |
SVN_ERR (svn_repos__hooks_pre_revprop_change (repos, rev, author, name, |
| 276 |
new_value, pool)); |
| 277 |
SVN_ERR (svn_fs_change_rev_prop (repos->fs, rev, name, new_value, pool)); |
| 278 |
SVN_ERR (svn_repos__hooks_post_revprop_change (repos, rev, author, |
| 279 |
name, old_value, pool)); |
| 280 |
} |
| 281 |
else /* rev is either unreadable or only partially readable */ |
| 282 |
{ |
| 283 |
return svn_error_createf |
| 284 |
(APR_EGENERAL, NULL, |
| 285 |
"Write denied: not authorized to read all of revision %ld.", rev); |
| 286 |
} |
| 287 |
|
| 288 |
return SVN_NO_ERROR; |
| 289 |
} |
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
svn_error_t * |
| 186 |
svn_repos_fs_change_rev_prop (svn_repos_t *repos, |
294 |
svn_repos_fs_change_rev_prop (svn_repos_t *repos, |
| 187 |
svn_revnum_t rev, |
295 |
svn_revnum_t rev, |
| 188 |
const char *author, |
296 |
const char *author, |
|
Lines 190-212
Link Here
|
| 190 |
const svn_string_t *new_value, |
298 |
const svn_string_t *new_value, |
| 191 |
apr_pool_t *pool) |
299 |
apr_pool_t *pool) |
| 192 |
{ |
300 |
{ |
| 193 |
svn_string_t *old_value; |
301 |
return svn_repos__fs_change_rev_prop2 (repos, rev, author, name, new_value, |
|
|
302 |
NULL, NULL, pool); |
| 303 |
} |
| 194 |
|
304 |
|
| 195 |
SVN_ERR (validate_prop (name, pool)); |
|
|
| 196 |
SVN_ERR (svn_fs_revision_prop (&old_value, repos->fs, rev, name, pool)); |
| 197 |
SVN_ERR (svn_repos__hooks_pre_revprop_change (repos, rev, author, name, |
| 198 |
new_value, pool)); |
| 199 |
SVN_ERR (svn_fs_change_rev_prop (repos->fs, rev, name, new_value, pool)); |
| 200 |
SVN_ERR (svn_repos__hooks_post_revprop_change (repos, rev, author, |
| 201 |
name, old_value, pool)); |
| 202 |
|
305 |
|
|
|
306 |
|
| 307 |
svn_error_t * |
| 308 |
svn_repos__fs_revision_prop (svn_string_t **value_p, |
| 309 |
svn_repos_t *repos, |
| 310 |
svn_revnum_t rev, |
| 311 |
const char *propname, |
| 312 |
svn_repos_authz_func_t authz_read_func, |
| 313 |
void *authz_read_baton, |
| 314 |
apr_pool_t *pool) |
| 315 |
{ |
| 316 |
int readability = rev_readable; |
| 317 |
|
| 318 |
if (authz_read_func) |
| 319 |
SVN_ERR (get_readability (&readability, repos->fs, rev, |
| 320 |
authz_read_func, authz_read_baton, pool)); |
| 321 |
|
| 322 |
if (readability == rev_unreadable) |
| 323 |
{ |
| 324 |
/* Property? What property? */ |
| 325 |
*value_p = NULL; |
| 326 |
} |
| 327 |
else if (readability == rev_partially_readable) |
| 328 |
{ |
| 329 |
/* Only svn:author and svn:date are fetchable. */ |
| 330 |
if ((strncmp (propname, SVN_PROP_REVISION_AUTHOR, |
| 331 |
strlen(SVN_PROP_REVISION_AUTHOR)) != 0) |
| 332 |
&& (strncmp (propname, SVN_PROP_REVISION_DATE, |
| 333 |
strlen(SVN_PROP_REVISION_DATE)) != 0)) |
| 334 |
*value_p = NULL; |
| 335 |
|
| 336 |
else |
| 337 |
SVN_ERR (svn_fs_revision_prop (value_p, repos->fs, |
| 338 |
rev, propname, pool)); |
| 339 |
} |
| 340 |
else /* wholly readable revision */ |
| 341 |
{ |
| 342 |
SVN_ERR (svn_fs_revision_prop (value_p, repos->fs, rev, propname, pool)); |
| 343 |
} |
| 344 |
|
| 203 |
return SVN_NO_ERROR; |
345 |
return SVN_NO_ERROR; |
| 204 |
} |
346 |
} |
| 205 |
|
347 |
|
| 206 |
|
348 |
|
| 207 |
|
349 |
|
|
|
350 |
svn_error_t * |
| 351 |
svn_repos__fs_revision_proplist (apr_hash_t **table_p, |
| 352 |
svn_repos_t *repos, |
| 353 |
svn_revnum_t rev, |
| 354 |
svn_repos_authz_func_t authz_read_func, |
| 355 |
void *authz_read_baton, |
| 356 |
apr_pool_t *pool) |
| 357 |
{ |
| 358 |
int readability = rev_readable; |
| 208 |
|
359 |
|
|
|
360 |
if (authz_read_func) |
| 361 |
SVN_ERR (get_readability (&readability, repos->fs, rev, |
| 362 |
authz_read_func, authz_read_baton, pool)); |
| 209 |
|
363 |
|
|
|
364 |
if (readability == rev_unreadable) |
| 365 |
{ |
| 366 |
/* Return an empty hash. */ |
| 367 |
*table_p = apr_hash_make (pool); |
| 368 |
} |
| 369 |
else if (readability == rev_partially_readable) |
| 370 |
{ |
| 371 |
apr_hash_t *tmphash; |
| 372 |
svn_string_t *value; |
| 373 |
|
| 374 |
/* Produce two property hashtables, both in POOL. */ |
| 375 |
SVN_ERR (svn_fs_revision_proplist (&tmphash, repos->fs, rev, pool)); |
| 376 |
*table_p = apr_hash_make (pool); |
| 377 |
|
| 378 |
/* If they exist, we only copy svn:author and svn:date into the |
| 379 |
'real' hashtable being returned. */ |
| 380 |
value = apr_hash_get (tmphash, SVN_PROP_REVISION_AUTHOR, |
| 381 |
APR_HASH_KEY_STRING); |
| 382 |
if (value) |
| 383 |
apr_hash_set (*table_p, SVN_PROP_REVISION_AUTHOR, |
| 384 |
APR_HASH_KEY_STRING, value); |
| 385 |
|
| 386 |
value = apr_hash_get (tmphash, SVN_PROP_REVISION_DATE, |
| 387 |
APR_HASH_KEY_STRING); |
| 388 |
if (value) |
| 389 |
apr_hash_set (*table_p, SVN_PROP_REVISION_DATE, |
| 390 |
APR_HASH_KEY_STRING, value); |
| 391 |
} |
| 392 |
else /* wholly readable revision */ |
| 393 |
{ |
| 394 |
SVN_ERR (svn_fs_revision_proplist (table_p, repos->fs, rev, pool)); |
| 395 |
} |
| 396 |
|
| 397 |
return SVN_NO_ERROR; |
| 398 |
} |
| 399 |
|
| 400 |
|
| 210 |
|
401 |
|
| 211 |
/* |
402 |
/* |
| 212 |
* vim:ts=4:sw=4:expandtab:tw=80:fo=tcroq |
403 |
* vim:ts=4:sw=4:expandtab:tw=80:fo=tcroq |