|
Lines 40-55
Link Here
|
| 40 |
* the value is (void *) 'U', 'A', 'D', or 'R', for modified, added, |
40 |
* the value is (void *) 'U', 'A', 'D', or 'R', for modified, added, |
| 41 |
* deleted, or replaced, respectively. |
41 |
* deleted, or replaced, respectively. |
| 42 |
* |
42 |
* |
|
|
43 |
* If optional AUTHZ_READ_FUNC is non-NULL, then use it (with |
| 44 |
* AUTHZ_READ_BATON and FS) to check whether each changed-path (and |
| 45 |
* copyfrom_path) is readable: |
| 46 |
* |
| 47 |
* - If some paths are readable and some are not, then silently |
| 48 |
* omit the unreadable paths from the CHANGED hash, and return |
| 49 |
* SVN_ERR_ENTRY_NOT_FOUND. |
| 50 |
* |
| 51 |
* - If absolutely every changed-path (and copyfrom_path) is |
| 52 |
* unreadable, then return an empty CHANGED hash and |
| 53 |
* APR_EGENERAL. (This is to distinguish a revision |
| 54 |
* which truly has no changed paths from a revision in which all |
| 55 |
* paths are unreadable.) |
| 43 |
*/ |
56 |
*/ |
| 44 |
static svn_error_t * |
57 |
static svn_error_t * |
| 45 |
detect_changed (apr_hash_t **changed, |
58 |
detect_changed (apr_hash_t **changed, |
| 46 |
svn_fs_root_t *root, |
59 |
svn_fs_root_t *root, |
|
|
60 |
svn_fs_t *fs, |
| 61 |
svn_repos_authz_func_t authz_read_func, |
| 62 |
void *authz_read_baton, |
| 47 |
apr_pool_t *pool) |
63 |
apr_pool_t *pool) |
| 48 |
{ |
64 |
{ |
| 49 |
apr_hash_t *changes; |
65 |
apr_hash_t *changes; |
| 50 |
apr_hash_index_t *hi; |
66 |
apr_hash_index_t *hi; |
| 51 |
apr_pool_t *subpool = svn_pool_create (pool); |
67 |
apr_pool_t *subpool = svn_pool_create (pool); |
| 52 |
|
68 |
svn_boolean_t found_readable = FALSE; |
|
|
69 |
svn_boolean_t found_unreadable = FALSE; |
| 70 |
|
| 53 |
*changed = apr_hash_make (pool); |
71 |
*changed = apr_hash_make (pool); |
| 54 |
SVN_ERR (svn_fs_paths_changed (&changes, root, pool)); |
72 |
SVN_ERR (svn_fs_paths_changed (&changes, root, pool)); |
| 55 |
for (hi = apr_hash_first (pool, changes); hi; hi = apr_hash_next (hi)) |
73 |
for (hi = apr_hash_first (pool, changes); hi; hi = apr_hash_next (hi)) |
|
Lines 68-73
Link Here
|
| 68 |
path = (const char *) key; |
86 |
path = (const char *) key; |
| 69 |
change = val; |
87 |
change = val; |
| 70 |
|
88 |
|
|
|
89 |
/* Skip path if unreadable. */ |
| 90 |
if (authz_read_func) |
| 91 |
{ |
| 92 |
svn_boolean_t readable; |
| 93 |
SVN_ERR (authz_read_func (&readable, |
| 94 |
root, path, |
| 95 |
authz_read_baton, subpool)); |
| 96 |
if (! readable) |
| 97 |
{ |
| 98 |
found_unreadable = TRUE; |
| 99 |
continue; |
| 100 |
} |
| 101 |
} |
| 102 |
|
| 103 |
/* At least one changed-path was readable. */ |
| 104 |
found_readable = TRUE; |
| 105 |
|
| 71 |
switch (change->change_kind) |
106 |
switch (change->change_kind) |
| 72 |
{ |
107 |
{ |
| 73 |
case svn_fs_path_change_reset: |
108 |
case svn_fs_path_change_reset: |
|
Lines 101-110
Link Here
|
| 101 |
|
136 |
|
| 102 |
SVN_ERR (svn_fs_copied_from (©from_rev, ©from_path, |
137 |
SVN_ERR (svn_fs_copied_from (©from_rev, ©from_path, |
| 103 |
root, path, subpool)); |
138 |
root, path, subpool)); |
|
|
139 |
|
| 104 |
if (copyfrom_path && SVN_IS_VALID_REVNUM (copyfrom_rev)) |
140 |
if (copyfrom_path && SVN_IS_VALID_REVNUM (copyfrom_rev)) |
| 105 |
{ |
141 |
{ |
| 106 |
item->copyfrom_path = apr_pstrdup (pool, copyfrom_path); |
142 |
svn_boolean_t readable = TRUE; |
| 107 |
item->copyfrom_rev = copyfrom_rev; |
143 |
|
|
|
144 |
if (authz_read_func) |
| 145 |
{ |
| 146 |
svn_fs_root_t *copyfrom_root; |
| 147 |
|
| 148 |
SVN_ERR (svn_fs_revision_root (©from_root, fs, |
| 149 |
copyfrom_rev, subpool)); |
| 150 |
SVN_ERR (authz_read_func (&readable, |
| 151 |
copyfrom_root, copyfrom_path, |
| 152 |
authz_read_baton, subpool)); |
| 153 |
if (! readable) |
| 154 |
found_unreadable = TRUE; |
| 155 |
} |
| 156 |
|
| 157 |
if (readable) |
| 158 |
{ |
| 159 |
item->copyfrom_path = apr_pstrdup (pool, copyfrom_path); |
| 160 |
item->copyfrom_rev = copyfrom_rev; |
| 161 |
} |
| 108 |
} |
162 |
} |
| 109 |
} |
163 |
} |
| 110 |
apr_hash_set (*changed, apr_pstrdup (pool, path), |
164 |
apr_hash_set (*changed, apr_pstrdup (pool, path), |
|
Lines 112-117
Link Here
|
| 112 |
} |
166 |
} |
| 113 |
|
167 |
|
| 114 |
svn_pool_destroy (subpool); |
168 |
svn_pool_destroy (subpool); |
|
|
169 |
|
| 170 |
if (! found_readable) |
| 171 |
/* Every changed-path was unreadable. */ |
| 172 |
return svn_error_create (APR_EGENERAL, |
| 173 |
NULL, NULL); |
| 174 |
|
| 175 |
if (found_unreadable) |
| 176 |
/* At least one changed-path was unreadable. */ |
| 177 |
return svn_error_create (SVN_ERR_ENTRY_NOT_FOUND, |
| 178 |
NULL, NULL); |
| 179 |
|
| 180 |
/* Every changed-path was readable. */ |
| 115 |
return SVN_NO_ERROR; |
181 |
return SVN_NO_ERROR; |
| 116 |
} |
182 |
} |
| 117 |
|
183 |
|
|
Lines 132-146
Link Here
|
| 132 |
|
198 |
|
| 133 |
|
199 |
|
| 134 |
svn_error_t * |
200 |
svn_error_t * |
| 135 |
svn_repos_get_logs (svn_repos_t *repos, |
201 |
svn_repos__get_logs2 (svn_repos_t *repos, |
| 136 |
const apr_array_header_t *paths, |
202 |
const apr_array_header_t *paths, |
| 137 |
svn_revnum_t start, |
203 |
svn_revnum_t start, |
| 138 |
svn_revnum_t end, |
204 |
svn_revnum_t end, |
| 139 |
svn_boolean_t discover_changed_paths, |
205 |
svn_boolean_t discover_changed_paths, |
| 140 |
svn_boolean_t strict_node_history, |
206 |
svn_boolean_t strict_node_history, |
| 141 |
svn_log_message_receiver_t receiver, |
207 |
svn_repos_authz_func_t authz_read_func, |
| 142 |
void *receiver_baton, |
208 |
void *authz_read_baton, |
| 143 |
apr_pool_t *pool) |
209 |
svn_log_message_receiver_t receiver, |
|
|
210 |
void *receiver_baton, |
| 211 |
apr_pool_t *pool) |
| 144 |
{ |
212 |
{ |
| 145 |
svn_revnum_t this_rev, head = SVN_INVALID_REVNUM; |
213 |
svn_revnum_t this_rev, head = SVN_INVALID_REVNUM; |
| 146 |
apr_pool_t *subpool = svn_pool_create (pool); |
214 |
apr_pool_t *subpool = svn_pool_create (pool); |
|
Lines 191-200
Link Here
|
| 191 |
/* Get the changed revisions for this path. */ |
259 |
/* Get the changed revisions for this path. */ |
| 192 |
const char *this_path = APR_ARRAY_IDX (paths, 0, const char *); |
260 |
const char *this_path = APR_ARRAY_IDX (paths, 0, const char *); |
| 193 |
revs = apr_array_make (pool, 64, sizeof (svn_revnum_t)); |
261 |
revs = apr_array_make (pool, 64, sizeof (svn_revnum_t)); |
| 194 |
SVN_ERR (svn_repos_history (fs, this_path, history_to_revs_array, |
262 |
SVN_ERR (svn_repos__history2 (fs, this_path, |
| 195 |
revs, start, end, |
263 |
history_to_revs_array, revs, |
| 196 |
strict_node_history ? FALSE : TRUE, |
264 |
authz_read_func, authz_read_baton, |
| 197 |
pool)); |
265 |
start, end, |
|
|
266 |
strict_node_history ? FALSE : TRUE, |
| 267 |
pool)); |
| 198 |
} |
268 |
} |
| 199 |
else |
269 |
else |
| 200 |
{ |
270 |
{ |
|
Lines 212-221
Link Here
|
| 212 |
|
282 |
|
| 213 |
/* Get the changed revisions for this path, and add them to |
283 |
/* Get the changed revisions for this path, and add them to |
| 214 |
the hash (this will eliminate duplicates). */ |
284 |
the hash (this will eliminate duplicates). */ |
| 215 |
SVN_ERR (svn_repos_history (fs, this_path, history_to_revs_array, |
285 |
SVN_ERR (svn_repos__history2 (fs, this_path, |
| 216 |
changed_revs, start, end, |
286 |
history_to_revs_array, |
| 217 |
strict_node_history ? FALSE : TRUE, |
287 |
changed_revs, |
| 218 |
pool)); |
288 |
authz_read_func, authz_read_baton, |
|
|
289 |
start, end, |
| 290 |
strict_node_history |
| 291 |
? FALSE : TRUE, |
| 292 |
pool)); |
| 219 |
for (j = 0; j < changed_revs->nelts; j++) |
293 |
for (j = 0; j < changed_revs->nelts; j++) |
| 220 |
{ |
294 |
{ |
| 221 |
/* We're re-using the memory allocated for the array |
295 |
/* We're re-using the memory allocated for the array |
|
Lines 288-298
Link Here
|
| 288 |
them (i.e., "svn log -v" means `discover_changed_paths' will |
362 |
them (i.e., "svn log -v" means `discover_changed_paths' will |
| 289 |
be non-zero here). */ |
363 |
be non-zero here). */ |
| 290 |
|
364 |
|
| 291 |
if ((this_rev > 0) && discover_changed_paths) |
365 |
|
|
|
366 |
if ((this_rev > 0) |
| 367 |
&& (authz_read_func || discover_changed_paths)) |
| 292 |
{ |
368 |
{ |
| 293 |
svn_fs_root_t *newroot; |
369 |
svn_fs_root_t *newroot; |
|
|
370 |
svn_error_t *patherr; |
| 371 |
|
| 294 |
SVN_ERR (svn_fs_revision_root (&newroot, fs, this_rev, subpool)); |
372 |
SVN_ERR (svn_fs_revision_root (&newroot, fs, this_rev, subpool)); |
| 295 |
SVN_ERR (detect_changed (&changed_paths, newroot, subpool)); |
373 |
patherr = detect_changed (&changed_paths, |
|
|
374 |
newroot, fs, |
| 375 |
authz_read_func, authz_read_baton, |
| 376 |
subpool); |
| 377 |
|
| 378 |
if (patherr |
| 379 |
&& patherr->apr_err == APR_EGENERAL) |
| 380 |
{ |
| 381 |
/* All changed-paths are unreadable, so clear all fields. */ |
| 382 |
svn_error_clear (patherr); |
| 383 |
changed_paths = NULL; |
| 384 |
author = NULL; |
| 385 |
date = NULL; |
| 386 |
message = NULL; |
| 387 |
} |
| 388 |
else if (patherr |
| 389 |
&& patherr->apr_err == SVN_ERR_ENTRY_NOT_FOUND) |
| 390 |
{ |
| 391 |
/* At least one changed-path was unreadable, so omit the |
| 392 |
log message. (The unreadable paths are already |
| 393 |
missing from the hash.) */ |
| 394 |
svn_error_clear (patherr); |
| 395 |
message = NULL; |
| 396 |
} |
| 397 |
else if (patherr) |
| 398 |
return patherr; |
| 399 |
|
| 400 |
/* It may be the case that an authz func was passed in, but |
| 401 |
the user still doesn't want to see any changed-paths. */ |
| 402 |
if (! discover_changed_paths) |
| 403 |
changed_paths = NULL; |
| 296 |
} |
404 |
} |
| 297 |
|
405 |
|
| 298 |
SVN_ERR ((*receiver) (receiver_baton, |
406 |
SVN_ERR ((*receiver) (receiver_baton, |
|
Lines 310-312
Link Here
|
| 310 |
|
418 |
|
| 311 |
return SVN_NO_ERROR; |
419 |
return SVN_NO_ERROR; |
| 312 |
} |
420 |
} |
|
|
421 |
|
| 422 |
|
| 423 |
|
| 424 |
svn_error_t * |
| 425 |
svn_repos_get_logs (svn_repos_t *repos, |
| 426 |
const apr_array_header_t *paths, |
| 427 |
svn_revnum_t start, |
| 428 |
svn_revnum_t end, |
| 429 |
svn_boolean_t discover_changed_paths, |
| 430 |
svn_boolean_t strict_node_history, |
| 431 |
svn_log_message_receiver_t receiver, |
| 432 |
void *receiver_baton, |
| 433 |
apr_pool_t *pool) |
| 434 |
{ |
| 435 |
return svn_repos__get_logs2 (repos, paths, start, end, |
| 436 |
discover_changed_paths, strict_node_history, |
| 437 |
NULL, NULL, /* no authz stuff */ |
| 438 |
receiver, receiver_baton, pool); |
| 439 |
} |