00001 /**
00002 * @copyright
00003 * ====================================================================
00004 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
00005 *
00006 * This software is licensed as described in the file COPYING, which
00007 * you should have received as part of this distribution. The terms
00008 * are also available at http://subversion.tigris.org/license-1.html.
00009 * If newer versions of this license are posted there, you may use a
00010 * newer version instead, at your option.
00011 *
00012 * This software consists of voluntary contributions made by many
00013 * individuals. For exact contribution history, see the revision
00014 * history and logs, available at http://subversion.tigris.org/.
00015 * ====================================================================
00016 * @endcopyright
00017 *
00018 * @file svn_repos.h
00019 * @brief tools built on top of the filesystem.
00020 */
00021
00022
00023 #ifndef SVN_REPOS_H
00024 #define SVN_REPOS_H
00025
00026 #include <apr_pools.h>
00027 #include <apr_hash.h>
00028 #include "svn_fs.h"
00029 #include "svn_delta.h"
00030 #include "svn_types.h"
00031 #include "svn_error.h"
00032 #include "svn_version.h"
00033
00034
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #endif /* __cplusplus */
00038
00039 /* ---------------------------------------------------------------*/
00040
00041 /**
00042 * Get libsvn_repos version information.
00043 *
00044 * @since New in 1.1.
00045 */
00046 const svn_version_t *svn_repos_version (void);
00047
00048
00049
00050 /** Callback type for checking authorization on paths produced by (at
00051 * least) svn_repos_dir_delta().
00052 *
00053 * Set @a *allowed to TRUE to indicate that some operation is
00054 * authorized for @a path in @a root, or set it to FALSE to indicate
00055 * unauthorized (presumably according to state stored in @a baton).
00056 *
00057 * Do not assume @a pool has any lifetime beyond this call.
00058 *
00059 * The exact operation being authorized depends on the callback
00060 * implementation. For read authorization, for example, the caller
00061 * would implement an instance that does read checking, and pass it as
00062 * a parameter named [perhaps] 'authz_read_func'. The receiver of
00063 * that parameter might also take another parameter named
00064 * 'authz_write_func', which although sharing this type, would be a
00065 * different implementation.
00066 *
00067 * @note If someday we want more sophisticated authorization states
00068 * than just yes/no, @a allowed can become an enum type.
00069 */
00070 typedef svn_error_t *(*svn_repos_authz_func_t) (svn_boolean_t *allowed,
00071 svn_fs_root_t *root,
00072 const char *path,
00073 void *baton,
00074 apr_pool_t *pool);
00075
00076
00077 /** An enum defining the kinds of access authz looks up.
00078 *
00079 * @since New in 1.3.
00080 */
00081 typedef enum
00082 {
00083 /** No access. */
00084 svn_authz_none = 0,
00085
00086 /** Path can be read. */
00087 svn_authz_read = 1,
00088
00089 /** Path can be altered. */
00090 svn_authz_write = 2,
00091
00092 /** The other access credentials are recursive. */
00093 svn_authz_recursive = 4
00094 } svn_repos_authz_access_t;
00095
00096
00097 /** Callback type for checking authorization on paths produced by
00098 * the repository commit editor.
00099 *
00100 * Set @a *allowed to TRUE to indicate that the @a required access on
00101 * @a path in @a root is authorized, or set it to FALSE to indicate
00102 * unauthorized (presumable according to state stored in @a baton).
00103 *
00104 * If @a path is NULL, the callback should perform a global authz
00105 * lookup for the @a required access. That is, the lookup should
00106 * check if the @a required access is granted for at least one path of
00107 * the repository, and set @a *allowed to TRUE if so. @a root may
00108 * also be NULL if @a path is NULL.
00109 *
00110 * This callback is very similar to svn_repos_authz_func_t, with the
00111 * exception of the addition of the @a required parameter.
00112 * This is due to historical reasons: when authz was first implemented
00113 * for svn_repos_dir_delta(), it seemed there would need only checks
00114 * for read and write operations, hence the svn_repos_authz_func_t
00115 * callback prototype and usage scenario. But it was then realized
00116 * that lookups due to copying needed to be recursive, and that
00117 * brute-force recursive lookups didn't square with the O(1)
00118 * performances a copy operation should have.
00119 *
00120 * So a special way to ask for a recursive lookup was introduced. The
00121 * commit editor needs this capability to retain acceptable
00122 * performance. Instead of revving the existing callback, causing
00123 * unnecessary revving of functions that don't actually need the
00124 * extended functionality, this second, more complete callback was
00125 * introduced, for use by the commit editor.
00126 *
00127 * Some day, it would be nice to reunite these two callbacks and do
00128 * the necessary revving anyway, but for the time being, this dual
00129 * callback mechanism will do.
00130 */
00131 typedef svn_error_t *(*svn_repos_authz_callback_t)
00132 (svn_repos_authz_access_t required,
00133 svn_boolean_t *allowed,
00134 svn_fs_root_t *root,
00135 const char *path,
00136 void *baton,
00137 apr_pool_t *pool);
00138
00139 /**
00140 * A callback function type for use in svn_repos_get_file_revs().
00141 * @a baton is provided by the caller, @a path is the pathname of the file
00142 * in revision @a rev and @a rev_props are the revision properties.
00143 * If @a delta_handler and @a delta_baton are non-NULL, they may be set to a
00144 * handler/baton which will be called with the delta between the previous
00145 * revision and this one after the return of this callback. They may be
00146 * left as NULL/NULL.
00147 * @a prop_diffs is an array of svn_prop_t elements indicating the property
00148 * delta for this and the previous revision.
00149 * @a pool may be used for temporary allocations, but you can't rely
00150 * on objects allocated to live outside of this particular call and the
00151 * immediately following calls to @a *delta_handler if any.
00152 *
00153 * @since New in 1.1.
00154 */
00155 typedef svn_error_t *(*svn_repos_file_rev_handler_t)
00156 (void *baton,
00157 const char *path,
00158 svn_revnum_t rev,
00159 apr_hash_t *rev_props,
00160 svn_txdelta_window_handler_t *delta_handler,
00161 void **delta_baton,
00162 apr_array_header_t *prop_diffs,
00163 apr_pool_t *pool);
00164
00165
00166 /** The repository object. */
00167 typedef struct svn_repos_t svn_repos_t;
00168
00169 /* Opening and creating repositories. */
00170
00171
00172 /** Find the root path of the repository that contains @a path.
00173 *
00174 * If a repository was found, the path to the root of the repository
00175 * is returned, else @c NULL. The pointer to the returned path may be
00176 * equal to @a path argument.
00177 */
00178 const char *svn_repos_find_root_path (const char *path,
00179 apr_pool_t *pool);
00180
00181 /** Set @a *repos_p to a repository object for the repository at @a path.
00182 *
00183 * Allocate @a *repos_p in @a pool.
00184 *
00185 * Acquires a shared lock on the repository, and attaches a cleanup
00186 * function to @a pool to remove the lock. If no lock can be acquired,
00187 * returns error, with undefined effect on @a *repos_p. If an exclusive
00188 * lock is present, this blocks until it's gone.
00189 */
00190 svn_error_t *svn_repos_open (svn_repos_t **repos_p,
00191 const char *path,
00192 apr_pool_t *pool);
00193
00194 /** Create a new Subversion repository at @a path, building the necessary
00195 * directory structure, creating the Berkeley DB filesystem environment,
00196 * and so on. Return the (open) repository object in @a *repos_p,
00197 * allocated in @a pool.
00198 *
00199 * @a config is a client configuration hash of @c svn_config_t * items
00200 * keyed on config category names, and may be NULL.
00201 *
00202 * @a fs_config is passed to the filesystem, and may be NULL.
00203 *
00204 * @a unused_1 and @a unused_2 are not used and should be NULL.
00205 */
00206 svn_error_t *svn_repos_create (svn_repos_t **repos_p,
00207 const char *path,
00208 const char *unused_1,
00209 const char *unused_2,
00210 apr_hash_t *config,
00211 apr_hash_t *fs_config,
00212 apr_pool_t *pool);
00213
00214 /** Destroy the Subversion repository found at @a path, using @a pool for any
00215 * necessary allocations.
00216 */
00217 svn_error_t *svn_repos_delete (const char *path, apr_pool_t *pool);
00218
00219 /** Return the filesystem associated with repository object @a repos. */
00220 svn_fs_t *svn_repos_fs (svn_repos_t *repos);
00221
00222
00223 /** Make a hot copy of the Subversion repository found at @a src_path
00224 * to @a dst_path.
00225 *
00226 * Copy a possibly live Subversion repository from @a src_path to
00227 * @a dst_path. If @a clean_logs is @c TRUE, perform cleanup on the
00228 * source filesystem as part of the copy operation; currently, this
00229 * means deleting copied, unused logfiles for a Berkeley DB source
00230 * repository.
00231 */
00232 svn_error_t * svn_repos_hotcopy (const char *src_path,
00233 const char *dst_path,
00234 svn_boolean_t clean_logs,
00235 apr_pool_t *pool);
00236
00237 /**
00238 * Run database recovery procedures on the repository at @a path,
00239 * returning the database to a consistent state. Use @a pool for all
00240 * allocation.
00241 *
00242 * Acquires an @a exclusive lock on the repository, recovers the
00243 * database, and releases the lock. If an exclusive lock can't be
00244 * acquired, returns error.
00245 *
00246 * @deprecated Provided for backward compatibility with the 1.0 API.
00247 */
00248 svn_error_t *svn_repos_recover (const char *path, apr_pool_t *pool);
00249
00250 /**
00251 * Run database recovery procedures on the repository at @a path,
00252 * returning the database to a consistent state. Use @a pool for all
00253 * allocation.
00254 *
00255 * Acquires an @a exclusive lock on the repository, recovers the
00256 * database, and releases the lock. If an exclusive lock can't be
00257 * acquired, returns error.
00258 *
00259 * If @a nonblocking is TRUE, an error of type EWOULDBLOCK is
00260 * returned if the lock is not immediately available.
00261 *
00262 * If @a start_callback is not NULL, it will be called with @a
00263 * start_callback_baton as argument before the recovery starts, but
00264 * after the exclusive lock has been acquired.
00265 *
00266 * @since New in 1.1.
00267 */
00268 svn_error_t *svn_repos_recover2 (const char *path,
00269 svn_boolean_t nonblocking,
00270 svn_error_t *(*start_callback) (void *baton),
00271 void *start_callback_baton,
00272 apr_pool_t *pool);
00273
00274 /** This function is a wrapper around svn_fs_berkeley_logfiles(),
00275 * returning log file paths relative to the root of the repository.
00276 *
00277 * @copydoc svn_fs_berkeley_logfiles()
00278 */
00279 svn_error_t *svn_repos_db_logfiles (apr_array_header_t **logfiles,
00280 const char *path,
00281 svn_boolean_t only_unused,
00282 apr_pool_t *pool);
00283
00284
00285
00286 /* Repository Paths */
00287
00288 /** Return the top-level repository path allocated in @a pool. */
00289 const char *svn_repos_path (svn_repos_t *repos, apr_pool_t *pool);
00290
00291 /** Return the path to @a repos's Berkeley DB environment, allocated in
00292 * @a pool.
00293 */
00294 const char *svn_repos_db_env (svn_repos_t *repos, apr_pool_t *pool);
00295
00296 /** Return path to @a repos's config directory, allocated in @a pool. */
00297 const char *svn_repos_conf_dir (svn_repos_t *repos, apr_pool_t *pool);
00298
00299 /** Return path to @a repos's svnserve.conf, allocated in @a pool. */
00300 const char *svn_repos_svnserve_conf (svn_repos_t *repos, apr_pool_t *pool);
00301
00302 /** Return path to @a repos's lock directory, allocated in @a pool. */
00303 const char *svn_repos_lock_dir (svn_repos_t *repos, apr_pool_t *pool);
00304
00305 /** Return path to @a repos's db lockfile, allocated in @a pool. */
00306 const char *svn_repos_db_lockfile (svn_repos_t *repos, apr_pool_t *pool);
00307
00308 /** Return path to @a repos's db logs lockfile, allocated in @a pool. */
00309 const char *svn_repos_db_logs_lockfile (svn_repos_t *repos, apr_pool_t *pool);
00310
00311 /** Return the path to @a repos's hook directory, allocated in @a pool. */
00312 const char *svn_repos_hook_dir (svn_repos_t *repos, apr_pool_t *pool);
00313
00314 /** Return the path to @a repos's start-commit hook, allocated in @a pool. */
00315 const char *svn_repos_start_commit_hook (svn_repos_t *repos, apr_pool_t *pool);
00316
00317 /** Return the path to @a repos's pre-commit hook, allocated in @a pool. */
00318 const char *svn_repos_pre_commit_hook (svn_repos_t *repos, apr_pool_t *pool);
00319
00320 /** Return the path to @a repos's post-commit hook, allocated in @a pool. */
00321 const char *svn_repos_post_commit_hook (svn_repos_t *repos, apr_pool_t *pool);
00322
00323 /** Return the path to @a repos's pre-revprop-change hook, allocated in
00324 * @a pool.
00325 */
00326 const char *svn_repos_pre_revprop_change_hook (svn_repos_t *repos,
00327 apr_pool_t *pool);
00328
00329 /** Return the path to @a repos's post-revprop-change hook, allocated in
00330 * @a pool.
00331 */
00332 const char *svn_repos_post_revprop_change_hook (svn_repos_t *repos,
00333 apr_pool_t *pool);
00334
00335
00336 /** @defgroup svn_repos_lock_hooks paths to lock hooks
00337 * @{
00338 * @since New in 1.2. */
00339
00340 /** Return the path to @a repos's pre-lock hook, allocated in @a pool. */
00341 const char *svn_repos_pre_lock_hook (svn_repos_t *repos, apr_pool_t *pool);
00342
00343 /** Return the path to @a repos's post-lock hook, allocated in @a pool. */
00344 const char *svn_repos_post_lock_hook (svn_repos_t *repos, apr_pool_t *pool);
00345
00346 /** Return the path to @a repos's pre-unlock hook, allocated in @a pool. */
00347 const char *svn_repos_pre_unlock_hook (svn_repos_t *repos, apr_pool_t *pool);
00348
00349 /** Return the path to @a repos's post-unlock hook, allocated in @a pool. */
00350 const char *svn_repos_post_unlock_hook (svn_repos_t *repos, apr_pool_t *pool);
00351
00352 /** @} */
00353
00354 /* ---------------------------------------------------------------*/
00355
00356 /* Reporting the state of a working copy, for updates. */
00357
00358
00359 /**
00360 * Construct and return a @a report_baton that will be paired with some
00361 * @c svn_ra_reporter_t table. The table and baton are used to build a
00362 * transaction in the system; when the report is finished,
00363 * svn_repos_dir_delta() is called on the transaction, driving
00364 * @a editor/@a edit_baton.
00365 *
00366 * Specifically, the report will create a transaction
00367 * relative to @a fs_base in the filesystem. @a target is a single path
00368 * component, used to limit the scope of the report to a single entry of
00369 * @a fs_base, or "" if all of @a fs_base itself is the main subject of
00370 * the report.
00371 *
00372 * @a tgt_path and @a revnum is the fs path/revision pair that is the
00373 * "target" of @c dir_delta. In other words, a tree delta will be
00374 * returned that transforms the transaction into @a tgt_path/@a revnum.
00375 * @a tgt_path may (indeed, should) be @c NULL when the source and target
00376 * paths of the report are the same. That is, @a tgt_path should *only*
00377 * be specified when specifying that the resultant editor drive be one
00378 * that transforms the reported hierarchy into a pristine tree of
00379 * @a tgt_path at revision @a revnum. Else, a @c NULL value for @a tgt_path
00380 * will indicate that the editor should be driven in such a way as to
00381 * transform the reported hierarchy to revision @a revnum, preserving the
00382 * reported hierarchy.
00383 *
00384 * @a text_deltas instructs the driver of the @a editor to enable
00385 * the generation of text deltas.
00386 *
00387 * @a recurse instructs the driver of the @a editor to send a recursive
00388 * delta (or not.)
00389 *
00390 * @a ignore_ancestry instructs the driver to ignore node ancestry
00391 * when determining how to transmit differences.
00392 *
00393 * Locks that are reported by the caller and that are not valid in the
00394 * repository will be deleted during the following edit.
00395 *
00396 * The @a authz_read_func and @a authz_read_baton are passed along to
00397 * svn_repos_dir_delta(); see that function for how they are used.
00398 *
00399 * All allocation for the context and collected state will occur in
00400 * @a pool.
00401 *
00402 * @note @a username isn't used and should be removed if this function is
00403 * revised.
00404 */
00405 svn_error_t *
00406 svn_repos_begin_report (void **report_baton,
00407 svn_revnum_t revnum,
00408 const char *username,
00409 svn_repos_t *repos,
00410 const char *fs_base,
00411 const char *target,
00412 const char *tgt_path,
00413 svn_boolean_t text_deltas,
00414 svn_boolean_t recurse,
00415 svn_boolean_t ignore_ancestry,
00416 const svn_delta_editor_t *editor,
00417 void *edit_baton,
00418 svn_repos_authz_func_t authz_read_func,
00419 void *authz_read_baton,
00420 apr_pool_t *pool);
00421
00422 /**
00423 * Given a @a report_baton constructed by svn_repos_begin_report(), this
00424 * routine will build @a revision:@a path into the current transaction.
00425 * This routine is called multiple times to create a transaction that
00426 * is a "mirror" of a working copy.
00427 *
00428 * The first call of this in a given report usually passes an empty
00429 * @a path; that allows the reporter to set up the correct root revision
00430 * (useful when creating a txn, for example).
00431 *
00432 * If @a start_empty is set and @a path is a directory, then remove
00433 * all children and props of the freshly-linked directory. This is
00434 * for 'low confidence' client reporting.
00435 *
00436 * If the caller has a lock token for @a path, then @a lock_token should
00437 * be set to that token. Else, @a lock_token should be NULL.
00438 *
00439 * All temporary allocations are done in @a pool.
00440 *
00441 * @since New in 1.2.
00442 */
00443 svn_error_t *svn_repos_set_path2 (void *report_baton,
00444 const char *path,
00445 svn_revnum_t revision,
00446 svn_boolean_t start_empty,
00447 const char *lock_token,
00448 apr_pool_t *pool);
00449
00450 /**
00451 * Similar to svn_repos_set_path2(), but with @a lock_token set to @c NULL.
00452 *
00453 * @deprecated Provided for backward compatibility with the 1.1 API.
00454 */
00455 svn_error_t *svn_repos_set_path (void *report_baton,
00456 const char *path,
00457 svn_revnum_t revision,
00458 svn_boolean_t start_empty,
00459 apr_pool_t *pool);
00460
00461 /**
00462 * Given a @a report_baton constructed by svn_repos_begin_report(),
00463 * this routine will build @a revision:@a link_path into the current
00464 * transaction at @a path. Note that while @a path is relative to the
00465 * anchor/target used in the creation of the @a report_baton, @a link_path
00466 * is an absolute filesystem path!
00467 *
00468 * If @a start_empty is set and @a path is a directory, then remove
00469 * all children and props of the freshly-linked directory. This is
00470 * for 'low confidence' client reporting.
00471 *
00472 * If the caller has a lock token for @a link_path, then @a lock_token
00473 * should be set to that token. Else, @a lock_token should be NULL.
00474 *
00475 * All temporary allocations are done in @a pool.
00476 *
00477 * @since New in 1.2.
00478 */
00479 svn_error_t *svn_repos_link_path2 (void *report_baton,
00480 const char *path,
00481 const char *link_path,
00482 svn_revnum_t revision,
00483 svn_boolean_t start_empty,
00484 const char *lock_token,
00485 apr_pool_t *pool);
00486
00487 /**
00488 * Similar to svn_repos_link_path2(), but with @a lock_token set to @c NULL.
00489 *
00490 * @deprecated Provided for backward compatibility with the 1.1 API.
00491 */
00492 svn_error_t *svn_repos_link_path (void *report_baton,
00493 const char *path,
00494 const char *link_path,
00495 svn_revnum_t revision,
00496 svn_boolean_t start_empty,
00497 apr_pool_t *pool);
00498
00499 /** Given a @a report_baton constructed by svn_repos_begin_report(),
00500 * this routine will remove @a path from the current fs transaction.
00501 *
00502 * (This allows the reporter's driver to describe missing pieces of a
00503 * working copy, so that 'svn up' can recreate them.)
00504 *
00505 * All temporary allocations are done in @a pool.
00506 */
00507 svn_error_t *svn_repos_delete_path (void *report_baton,
00508 const char *path,
00509 apr_pool_t *pool);
00510
00511 /** Make the filesystem compare the transaction to a revision and have
00512 * it drive an update editor (using svn_repos_delta_dirs()), then
00513 * abort the transaction. If an error occurs during the driving of
00514 * the editor, we do NOT abort the edit; that responsibility belongs
00515 * to the caller, if it happens at all. The fs transaction will be
00516 * aborted even if the editor drive fails, so the caller does not need
00517 * to clean up. No other reporting functions, including
00518 * svn_repos_abort_report, should be called after calling this function.
00519 */
00520 svn_error_t *svn_repos_finish_report (void *report_baton,
00521 apr_pool_t *pool);
00522
00523
00524 /** The report-driver is bailing, so abort the fs transaction. This
00525 * function can be called anytime before svn_repos_finish_report() is
00526 * called. No other reporting functions should be called after calling
00527 * this function.
00528 */
00529 svn_error_t *svn_repos_abort_report (void *report_baton,
00530 apr_pool_t *pool);
00531
00532
00533 /* ---------------------------------------------------------------*/
00534
00535 /* The magical dir_delta update routines. */
00536
00537 /** Use the provided @a editor and @a edit_baton to describe the changes
00538 * necessary for making a given node (and its descendants, if it is a
00539 * directory) under @a src_root look exactly like @a tgt_path under
00540 * @a tgt_root. @a src_entry is the node to update. If @a src_entry
00541 * is empty, then compute the difference between the entire tree
00542 * anchored at @a src_parent_dir under @a src_root and @a tgt_path
00543 * under @a target_root. Else, describe the changes needed to update
00544 * only that entry in @a src_parent_dir. Typically, callers of this
00545 * function will use a @a tgt_path that is the concatenation of @a
00546 * src_parent_dir and @a src_entry.
00547 *
00548 * @a src_root and @a tgt_root can both be either revision or transaction
00549 * roots. If @a tgt_root is a revision, @a editor's set_target_revision()
00550 * will be called with the @a tgt_root's revision number, else it will
00551 * not be called at all.
00552 *
00553 * If @a authz_read_func is non-null, invoke it before any call to
00554 *
00555 * @a editor->open_root
00556 * @a editor->add_directory
00557 * @a editor->open_directory
00558 * @a editor->add_file
00559 * @a editor->open_file
00560 *
00561 * passing @a tgt_root, the same path that would be passed to the
00562 * editor function in question, and @a authz_read_baton. If the
00563 * @a *allowed parameter comes back TRUE, then proceed with the planned
00564 * editor call; else if FALSE, then invoke @a editor->absent_file or
00565 * @a editor->absent_directory as appropriate, except if the planned
00566 * editor call was open_root, throw SVN_ERR_AUTHZ_ROOT_UNREADABLE.
00567 *
00568 * If @a text_deltas is @c FALSE, send a single @c NULL txdelta window to
00569 * the window handler returned by @a editor->apply_textdelta().
00570 *
00571 * If @a entry_props is @c TRUE, accompany each opened/added entry with
00572 * propchange editor calls that relay special "entry props" (this
00573 * is typically used only for working copy updates).
00574 *
00575 * @a ignore_ancestry instructs the function to ignore node ancestry
00576 * when determining how to transmit differences.
00577 *
00578 * Before completing successfully, this function calls @a editor's
00579 * close_edit(), so the caller should expect its @a edit_baton to be
00580 * invalid after its use with this function.
00581 *
00582 * Do any allocation necessary for the delta computation in @a pool.
00583 * This function's maximum memory consumption is at most roughly
00584 * proportional to the greatest depth of the tree under @a tgt_root, not
00585 * the total size of the delta.
00586 */
00587 svn_error_t *
00588 svn_repos_dir_delta (svn_fs_root_t *src_root,
00589 const char *src_parent_dir,
00590 const char *src_entry,
00591 svn_fs_root_t *tgt_root,
00592 const char *tgt_path,
00593 const svn_delta_editor_t *editor,
00594 void *edit_baton,
00595 svn_repos_authz_func_t authz_read_func,
00596 void *authz_read_baton,
00597 svn_boolean_t text_deltas,
00598 svn_boolean_t recurse,
00599 svn_boolean_t entry_props,
00600 svn_boolean_t ignore_ancestry,
00601 apr_pool_t *pool);
00602
00603 /** Use the provided @a editor and @a edit_baton to describe the
00604 * skeletal changes made in a particular filesystem @a root
00605 * (revision or transaction).
00606 *
00607 * The @a editor passed to this function should be aware of the fact
00608 * that calls to its change_dir_prop(), change_file_prop(), and
00609 * apply_textdelta() functions will not contain meaningful data, and
00610 * merely serve as indications that properties or textual contents
00611 * were changed.
00612 *
00613 * @note This editor driver passes SVN_INVALID_REVNUM for all
00614 * revision parameters in the editor interface except the copyfrom
00615 * parameter of the add_file() and add_directory() editor functions.
00616 *
00617 * ### TODO: This ought to take an svn_repos_authz_func_t too.
00618 * The only reason it doesn't yet is the difficulty of implementing
00619 * that correctly, plus lack of strong present need -- it's currently
00620 * only used in creating a DAV MERGE response, in 'svnadmin dump', and
00621 * in svnlook.
00622 */
00623 svn_error_t *
00624 svn_repos_replay (svn_fs_root_t *root,
00625 const svn_delta_editor_t *editor,
00626 void *edit_baton,
00627 apr_pool_t *pool);
00628
00629
00630 /* ---------------------------------------------------------------*/
00631
00632 /* Making commits. */
00633
00634 /**
00635 * Return an @a editor and @a edit_baton to commit changes to @a session->fs,
00636 * beginning at location 'rev:@a base_path', where "rev" is the argument
00637 * given to open_root().
00638 *
00639 * @a repos is a previously opened repository. @a repos_url is the
00640 * decoded URL to the base of the repository, and is used to check
00641 * copyfrom paths. @a txn is a filesystem transaction object to use
00642 * during the commit, or @c NULL to indicate that this function should
00643 * create (and fully manage) a new transaction.
00644 *
00645 * Iff @a user is not @c NULL, store it as the author of the commit
00646 * transaction.
00647 *
00648 * Iff @a log_msg is not @c NULL, store it as the log message
00649 * associated with the commit transaction.
00650 *
00651 * Iff @a authz_callback is provided, check read/write authorizations
00652 * on paths accessed by editor operations. An operation which fails
00653 * due to authz will return SVN_ERR_AUTHZ_UNREADABLE or
00654 * SVN_ERR_AUTHZ_UNWRITABLE.
00655 *
00656 * Calling @a (*editor)->close_edit completes the commit. Before
00657 * @c close_edit returns, but after the commit has succeeded, it will
00658 * invoke @a callback with the new revision number, the commit date (as a
00659 * <tt>const char *</tt>), commit author (as a <tt>const char *</tt>), and
00660 * @a callback_baton as arguments. If @a callback returns an error, that
00661 * error will be returned from @c close_edit, otherwise if there was a
00662 * post-commit hook failure, then that error will be returned and will
00663 * have code SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED.
00664 *
00665 * Calling @a (*editor)->abort_edit aborts the commit, and will also
00666 * abort the commit transaction unless @a txn was supplied (not @c
00667 * NULL). Callers who supply their own transactions are responsible
00668 * for cleaning them up (either by committing them, or aborting them).
00669 *
00670 * @since New in 1.3.
00671 */
00672 svn_error_t *
00673 svn_repos_get_commit_editor3 (const svn_delta_editor_t **editor,
00674 void **edit_baton,
00675 svn_repos_t *repos,
00676 svn_fs_txn_t *txn,
00677 const char *repos_url,
00678 const char *base_path,
00679 const char *user,
00680 const char *log_msg,
00681 svn_commit_callback_t callback,
00682 void *callback_baton,
00683 svn_repos_authz_callback_t authz_callback,
00684 void *authz_baton,
00685 apr_pool_t *pool);
00686
00687 /**
00688 * Similar to svn_repos_get_commit_editor3(), but with @a
00689 * authz_callback and @a authz_baton set to @c NULL.
00690 *
00691 * @deprecated Provided for backward compatibility with the 1.2 API.
00692 */
00693 svn_error_t *svn_repos_get_commit_editor2 (const svn_delta_editor_t **editor,
00694 void **edit_baton,
00695 svn_repos_t *repos,
00696 svn_fs_txn_t *txn,
00697 const char *repos_url,
00698 const char *base_path,
00699 const char *user,
00700 const char *log_msg,
00701 svn_commit_callback_t callback,
00702 void *callback_baton,
00703 apr_pool_t *pool);
00704
00705
00706 /**
00707 * Similar to svn_repos_get_commit_editor2(), but with @a txn always
00708 * set to @c NULL.
00709 *
00710 * @deprecated Provided for backward compatibility with the 1.1 API.
00711 */
00712 svn_error_t *svn_repos_get_commit_editor (const svn_delta_editor_t **editor,
00713 void **edit_baton,
00714 svn_repos_t *repos,
00715 const char *repos_url,
00716 const char *base_path,
00717 const char *user,
00718 const char *log_msg,
00719 svn_commit_callback_t callback,
00720 void *callback_baton,
00721 apr_pool_t *pool);
00722
00723 /* ---------------------------------------------------------------*/
00724
00725 /* Finding particular revisions. */
00726
00727 /** Set @a *revision to the revision number in @a repos's filesystem that was
00728 * youngest at time @a tm.
00729 */
00730 svn_error_t *
00731 svn_repos_dated_revision (svn_revnum_t *revision,
00732 svn_repos_t *repos,
00733 apr_time_t tm,
00734 apr_pool_t *pool);
00735
00736
00737 /** Given a @a root/@a path within some filesystem, return three pieces of
00738 * information allocated in @a pool:
00739 *
00740 * - set @a *committed_rev to the revision in which the object was
00741 * last modified. (In fs parlance, this is the revision in which
00742 * the particular node-rev-id was 'created'.)
00743 *
00744 * - set @a *committed_date to the date of said revision, or @c NULL
00745 * if not available.
00746 *
00747 * - set @a *last_author to the author of said revision, or @c NULL
00748 * if not available.
00749 */
00750 svn_error_t *
00751 svn_repos_get_committed_info (svn_revnum_t *committed_rev,
00752 const char **committed_date,
00753 const char **last_author,
00754 svn_fs_root_t *root,
00755 const char *path,
00756 apr_pool_t *pool);
00757
00758
00759 /**
00760 * Set @a *dirent to an @c svn_dirent_t associated with @a path in @a
00761 * root. If @a path does not exist in @a root, set @a *dirent to
00762 * NULL. Use @a pool for memory allocation.
00763 *
00764 * @since New in 1.2.
00765 */
00766 svn_error_t *
00767 svn_repos_stat (svn_dirent_t **dirent,
00768 svn_fs_root_t *root,
00769 const char *path,
00770 apr_pool_t *pool);
00771
00772
00773 /** Callback type for use with svn_repos_history(). @a path and @a
00774 * revision represent interesting history locations in the lifetime
00775 * of the path passed to svn_repos_history(). @a baton is the same
00776 * baton given to svn_repos_history(). @a pool is provided for the
00777 * convenience of the implementor, who should not expect it to live
00778 * longer than a single callback call.
00779 */
00780 typedef svn_error_t *(*svn_repos_history_func_t) (void *baton,
00781 const char *path,
00782 svn_revnum_t revision,
00783 apr_pool_t *pool);
00784
00785 /**
00786 * Call @a history_func (with @a history_baton) for each interesting
00787 * history location in the lifetime of @a path in @a fs, from the
00788 * youngest of @a end and @ start to the oldest. Only cross
00789 * filesystem copy history if @a cross_copies is @c TRUE. And do all
00790 * of this in @a pool.
00791 *
00792 * If @a authz_read_func is non-NULL, then use it (and @a
00793 * authz_read_baton) to verify that @a path in @a end is readable; if
00794 * not, return SVN_ERR_AUTHZ_UNREADABLE. Also verify the readability
00795 * of every ancestral path/revision pair before pushing them at @a
00796 * history_func. If a pair is deemed unreadable, then do not send
00797 * them; instead, immediately stop traversing history and return
00798 * SVN_NO_ERROR.
00799 *
00800 * @since New in 1.1.
00801 */
00802 svn_error_t *
00803 svn_repos_history2 (svn_fs_t *fs,
00804 const char *path,
00805 svn_repos_history_func_t history_func,
00806 void *history_baton,
00807 svn_repos_authz_func_t authz_read_func,
00808 void *authz_read_baton,
00809 svn_revnum_t start,
00810 svn_revnum_t end,
00811 svn_boolean_t cross_copies,
00812 apr_pool_t *pool);
00813
00814 /**
00815 * Similar to svn_repos_history2(), but with @a authz_read_func
00816 * and @a authz_read_baton always set to NULL.
00817 *
00818 * @deprecated Provided for backward compatibility with the 1.0 API.
00819 */
00820 svn_error_t *
00821 svn_repos_history (svn_fs_t *fs,
00822 const char *path,
00823 svn_repos_history_func_t history_func,
00824 void *history_baton,
00825 svn_revnum_t start,
00826 svn_revnum_t end,
00827 svn_boolean_t cross_copies,
00828 apr_pool_t *pool);
00829
00830
00831 /**
00832 * Set @a *locations to be a mapping of the revisions to the paths of
00833 * the file @a fs_path present at the repository in revision
00834 * @a peg_revision, where the revisions are taken out of the array
00835 * @a location_revisions.
00836 *
00837 * @a location_revisions is an array of svn_revnum_t's and @a *locations
00838 * maps 'svn_revnum_t *' to 'const char *'.
00839 *
00840 * If optional @a authz_read_func is non-NULL, then use it (and @a
00841 * authz_read_baton) to verify that the peg-object is readable. If not,
00842 * return SVN_ERR_AUTHZ_UNREADABLE. Also use the @a authz_read_func
00843 * to check that every path returned in the hash is readable. If an
00844 * unreadable path is encountered, stop tracing and return
00845 * SVN_NO_ERROR.
00846 *
00847 * @a pool is used for all allocations.
00848 *
00849 * @since New in 1.1.
00850 */
00851 svn_error_t *
00852 svn_repos_trace_node_locations (svn_fs_t *fs,
00853 apr_hash_t **locations,
00854 const char *fs_path,
00855 svn_revnum_t peg_revision,
00856 apr_array_header_t *location_revisions,
00857 svn_repos_authz_func_t authz_read_func,
00858 void *authz_read_baton,
00859 apr_pool_t *pool);
00860
00861 /* ### other queries we can do someday --
00862
00863 * fetch the last revision created by <user>
00864 (once usernames become revision properties!)
00865 * fetch the last revision where <path> was modified
00866
00867 */
00868
00869
00870
00871 /* ---------------------------------------------------------------*/
00872
00873 /* Retrieving log messages. */
00874
00875
00876 /**
00877 * Invoke @a receiver with @a receiver_baton on each log message from
00878 * @a start to @a end in @a repos's filesystem. @a start may be greater
00879 * or less than @a end; this just controls whether the log messages are
00880 * processed in descending or ascending revision number order.
00881 *
00882 * If @a start or @a end is @c SVN_INVALID_REVNUM, it defaults to youngest.
00883 *
00884 * If @a paths is non-null and has one or more elements, then only show
00885 * revisions in which at least one of @a paths was changed (i.e., if
00886 * file, text or props changed; if dir, props or entries changed or any node
00887 * changed below it). Each path is a <tt>const char *</tt> representing
00888 * an absolute path in the repository.
00889 *
00890 * If @a limit is non-zero then only invoke @a receiver on the first
00891 * @a limit logs.
00892 *
00893 * If @a discover_changed_paths, then each call to @a receiver passes a
00894 * hash mapping paths committed in that revision to information about them
00895 * as the receiver's @a changed_paths argument.
00896 * Otherwise, each call to @a receiver passes null for @a changed_paths.
00897 *
00898 * If @a strict_node_history is set, copy history (if any exists) will
00899 * not be traversed while harvesting revision logs for each path.
00900 *
00901 * If any invocation of @a receiver returns error, return that error
00902 * immediately and without wrapping it.
00903 *
00904 * If @a start or @a end is a non-existent revision, return the error
00905 * @c SVN_ERR_FS_NO_SUCH_REVISION, without ever invoking @a receiver.
00906 *
00907 * If optional @a authz_read_func is non-NULL, then use this function
00908 * (along with optional @a authz_read_baton) to check the readability
00909 * of each changed-path in each revision about to be "pushed" at
00910 * @a receiver. If a revision has all unreadable changed-paths, then
00911 * don't push the revision at all. If a revision has a mixture of
00912 * readable and unreadable changed-paths, then silently omit the
00913 * unreadable changed-paths when pushing the revision.
00914 *
00915 * See also the documentation for @c svn_log_message_receiver_t.
00916 *
00917 * Use @a pool for temporary allocations.
00918 *
00919 * @since New in 1.2.
00920 */
00921 svn_error_t *
00922 svn_repos_get_logs3 (svn_repos_t *repos,
00923 const apr_array_header_t *paths,
00924 svn_revnum_t start,
00925 svn_revnum_t end,
00926 int limit,
00927 svn_boolean_t discover_changed_paths,
00928 svn_boolean_t strict_node_history,
00929 svn_repos_authz_func_t authz_read_func,
00930 void *authz_read_baton,
00931 svn_log_message_receiver_t receiver,
00932 void *receiver_baton,
00933 apr_pool_t *pool);
00934
00935
00936 /**
00937 * Same as svn_repos_get_logs3(), but with @a limit always set to 0.
00938 *
00939 * @deprecated Provided for backward compatibility with the 1.1 API.
00940 */
00941 svn_error_t *
00942 svn_repos_get_logs2 (svn_repos_t *repos,
00943 const apr_array_header_t *paths,
00944 svn_revnum_t start,
00945 svn_revnum_t end,
00946 svn_boolean_t discover_changed_paths,
00947 svn_boolean_t strict_node_history,
00948 svn_repos_authz_func_t authz_read_func,
00949 void *authz_read_baton,
00950 svn_log_message_receiver_t receiver,
00951 void *receiver_baton,
00952 apr_pool_t *pool);
00953
00954 /**
00955 * Same as svn_repos_get_logs2(), but with @a authz_read_func and
00956 * @a authz_read_baton always set to NULL.
00957 *
00958 * @deprecated Provided for backward compatibility with the 1.0 API.
00959 */
00960 svn_error_t *
00961 svn_repos_get_logs (svn_repos_t *repos,
00962 const apr_array_header_t *paths,
00963 svn_revnum_t start,
00964 svn_revnum_t end,
00965 svn_boolean_t discover_changed_paths,
00966 svn_boolean_t strict_node_history,
00967 svn_log_message_receiver_t receiver,
00968 void *receiver_baton,
00969 apr_pool_t *pool);
00970
00971
00972
00973 /* ---------------------------------------------------------------*/
00974
00975 /* Retreiving multiple revisions of a file. */
00976
00977 /**
00978 * Retrieve a subset of the interesting revisions of a file @a path in
00979 * @a repos as seen in revision @a end. Invoke @a handler with
00980 * @a handler_baton as its first argument for each such revision.
00981 * @a pool is used for all allocations. See svn_fs_history_prev() for
00982 * a discussion of interesting revisions.
00983 *
00984 * If optional @a authz_read_func is non-NULL, then use this function
00985 * (along with optional @a authz_read_baton) to check the readability
00986 * of the rev-path in each interesting revision encountered.
00987 *
00988 * Revision discovery happens from @a end to @a start, and if an
00989 * unreadable revision is encountered before @a start is reached, then
00990 * revision discovery stops and only the revisions from @a end to the
00991 * oldest readable revision are returned (So it will appear that @a
00992 * path was added without history in the latter revision).
00993 *
00994 * If there is an interesting revision of the file that is less than or
00995 * equal to start, the iteration will start at that revision. Else, the
00996 * iteration will start at the first revision of the file in the repository,
00997 * which has to be less than or equal to end. Note that if the function
00998 * succeeds, @a handler will have been called at least once.
00999 *
01000 * In a series of calls, the file contents for the first interesting revision
01001 * will be provided as a text delta against the empty file. In the following
01002 * calls, the delta will be against the contents for the previous call.
01003 *
01004 * @since New in 1.1.
01005 */
01006 svn_error_t *svn_repos_get_file_revs (svn_repos_t *repos,
01007 const char *path,
01008 svn_revnum_t start,
01009 svn_revnum_t end,
01010 svn_repos_authz_func_t authz_read_func,
01011 void *authz_read_baton,
01012 svn_repos_file_rev_handler_t handler,
01013 void *handler_baton,
01014 apr_pool_t *pool);
01015
01016
01017 /* ---------------------------------------------------------------*/
01018
01019 /**
01020 * @defgroup svn_repos_hook_wrappers Hook-sensitive wrappers for libsvn_fs
01021 * routines.
01022 * @{
01023 */
01024
01025 /** Like svn_fs_commit_txn(), but invoke the @a repos's pre- and
01026 * post-commit hooks around the commit. Use @a pool for any necessary
01027 * allocations.
01028 *
01029 * If the pre-commit hook or svn_fs_commit_txn() fails, throw the
01030 * original error to caller. If an error occurs when running the
01031 * post-commit hook, return the original error wrapped with
01032 * SVN_ERR_REPOS_POST_COMMIT_HOOK_FAILED. If the caller sees this
01033 * error, it knows that the commit succeeded anyway.
01034 *
01035 * @a conflict_p, @a new_rev, and @a txn are as in svn_fs_commit_txn().
01036 */
01037 svn_error_t *svn_repos_fs_commit_txn (const char **conflict_p,
01038 svn_repos_t *repos,
01039 svn_revnum_t *new_rev,
01040 svn_fs_txn_t *txn,
01041 apr_pool_t *pool);
01042
01043 /** Like svn_fs_begin_txn(), but use @a author and @a log_msg to set the
01044 * corresponding properties on transaction @a *txn_p. @a repos is the
01045 * repository object which contains the filesystem. @a rev, @a *txn_p, and
01046 * @a pool are as in svn_fs_begin_txn().
01047 *
01048 * Before a txn is created, the repository's start-commit hooks are
01049 * run; if any of them fail, no txn is created, @a *txn_p is unaffected,
01050 * and @c SVN_ERR_REPOS_HOOK_FAILURE is returned.
01051 *
01052 * @a log_msg may be @c NULL to indicate the message is not (yet) available.
01053 * The caller will need to attach it to the transaction at a later time.
01054 */
01055 svn_error_t *svn_repos_fs_begin_txn_for_commit (svn_fs_txn_t **txn_p,
01056 svn_repos_t *repos,
01057 svn_revnum_t rev,
01058 const char *author,
01059 const char *log_msg,
01060 apr_pool_t *pool);
01061
01062
01063 /** Like svn_fs_begin_txn(), but use @a author to set the corresponding
01064 * property on transaction @a *txn_p. @a repos is the repository object
01065 * which contains the filesystem. @a rev, @a *txn_p, and @a pool are as in
01066 * svn_fs_begin_txn().
01067 *
01068 * ### Someday: before a txn is created, some kind of read-hook could
01069 * be called here.
01070 */
01071 svn_error_t *svn_repos_fs_begin_txn_for_update (svn_fs_txn_t **txn_p,
01072 svn_repos_t *repos,
01073 svn_revnum_t rev,
01074 const char *author,
01075 apr_pool_t *pool);
01076
01077
01078 /** @defgroup svn_repos_fs_locks repository lock wrappers
01079 * @{
01080 * @since New in 1.2. */
01081
01082 /** Like svn_fs_lock(), but invoke the @a repos's pre- and
01083 * post-lock hooks before and after the locking action. Use @a pool
01084 * for any necessary allocations.
01085 *
01086 * If the pre-lock hook or svn_fs_lock() fails, throw the original
01087 * error to caller. If an error occurs when running the post-lock
01088 * hook, return the original error wrapped with
01089 * SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED. If the caller sees this
01090 * error, it knows that the lock succeeded anyway.
01091 */
01092 svn_error_t *svn_repos_fs_lock (svn_lock_t **lock,
01093 svn_repos_t *repos,
01094 const char *path,
01095 const char *token,
01096 const char *comment,
01097 svn_boolean_t is_dav_comment,
01098 apr_time_t expiration_date,
01099 svn_revnum_t current_rev,
01100 svn_boolean_t steal_lock,
01101 apr_pool_t *pool);
01102
01103
01104 /** Like svn_fs_unlock(), but invoke the @a repos's pre- and
01105 * post-unlock hooks before and after the unlocking action. Use @a
01106 * pool for any necessary allocations.
01107 *
01108 * If the pre-unlock hook or svn_fs_unlock() fails, throw the original
01109 * error to caller. If an error occurs when running the post-unlock
01110 * hook, return the original error wrapped with
01111 * SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED. If the caller sees this
01112 * error, it knows that the unlock succeeded anyway.
01113 */
01114 svn_error_t *svn_repos_fs_unlock (svn_repos_t *repos,
01115 const char *path,
01116 const char *token,
01117 svn_boolean_t break_lock,
01118 apr_pool_t *pool);
01119
01120
01121
01122 /** Look up all the locks in and under @a path in @a repos, setting @a
01123 * *locks to a hash which maps <tt>const char *</tt> paths to the @c
01124 * svn_lock_t locks associated with those paths. Use @a
01125 * authz_read_func and @a authz_read_baton to "screen" all returned
01126 * locks. That is: do not return any locks on any paths that are
01127 * unreadable in HEAD, just silently omit them.
01128 */
01129 svn_error_t *svn_repos_fs_get_locks (apr_hash_t **locks,
01130 svn_repos_t *repos,
01131 const char *path,
01132 svn_repos_authz_func_t authz_read_func,
01133 void *authz_read_baton,
01134 apr_pool_t *pool);
01135
01136 /** @} */
01137
01138 /**
01139 * Like svn_fs_change_rev_prop(), but invoke the @a repos's pre- and
01140 * post-revprop-change hooks around the change. Use @a pool for
01141 * temporary allocations.
01142 *
01143 * @a rev is the revision whose property to change, @a name is the
01144 * name of the property, and @a new_value is the new value of the
01145 * property. @a author is the authenticated username of the person
01146 * changing the property value, or null if not available.
01147 *
01148 * If @a authz_read_func is non-NULL, then use it (with @a
01149 * authz_read_baton) to validate the changed-paths associated with @a
01150 * rev. If the revision contains any unreadable changed paths, then
01151 * return SVN_ERR_AUTHZ_UNREADABLE.
01152 *
01153 * @since New in 1.1.
01154 */
01155 svn_error_t *svn_repos_fs_change_rev_prop2 (svn_repos_t *repos,
01156 svn_revnum_t rev,
01157 const char *author,
01158 const char *name,
01159 const svn_string_t *new_value,
01160 svn_repos_authz_func_t
01161 authz_read_func,
01162 void *authz_read_baton,
01163 apr_pool_t *pool);
01164
01165 /**
01166 * Similar to svn_repos_fs_change_rev_prop2(), but with the
01167 * @a authz_read_func parameter always NULL.
01168 *
01169 * @deprecated Provided for backward compatibility with the 1.0 API.
01170 */
01171 svn_error_t *svn_repos_fs_change_rev_prop (svn_repos_t *repos,
01172 svn_revnum_t rev,
01173 const char *author,
01174 const char *name,
01175 const svn_string_t *new_value,
01176 apr_pool_t *pool);
01177
01178
01179
01180 /**
01181 * Set @a *value_p to the value of the property named @a propname on
01182 * revision @a rev in the filesystem opened in @a repos. If @a rev
01183 * has no property by that name, set @a *value_p to zero. Allocate
01184 * the result in @a pool.
01185 *
01186 * If @a authz_read_func is non-NULL, then use it (with @a
01187 * authz_read_baton) to validate the changed-paths associated with @a
01188 * rev. If the changed-paths are all unreadable, then set @a *value_p
01189 * to zero unconditionally. If only some of the changed-paths are
01190 * unreadable, then allow 'svn:author' and 'svn:date' propvalues to be
01191 * fetched, but return 0 for any other property.
01192 *
01193 * @since New in 1.1.
01194 */
01195 svn_error_t *svn_repos_fs_revision_prop (svn_string_t **value_p,
01196 svn_repos_t *repos,
01197 svn_revnum_t rev,
01198 const char *propname,
01199 svn_repos_authz_func_t
01200 authz_read_func,
01201 void *authz_read_baton,
01202 apr_pool_t *pool);
01203
01204
01205 /**
01206 * Set @a *table_p to the entire property list of revision @a rev in
01207 * filesystem opened in @a repos, as a hash table allocated in @a
01208 * pool. The table maps <tt>char *</tt> property names to @c
01209 * svn_string_t * values; the names and values are allocated in @a
01210 * pool.
01211 *
01212 * If @a authz_read_func is non-NULL, then use it (with @a
01213 * authz_read_baton) to validate the changed-paths associated with @a
01214 * rev. If the changed-paths are all unreadable, then return an empty
01215 * hash. If only some of the changed-paths are unreadable, then return
01216 * an empty hash, except for 'svn:author' and 'svn:date' properties
01217 * (assuming those properties exist).
01218 *
01219 * @since New in 1.1.
01220 */
01221 svn_error_t *svn_repos_fs_revision_proplist (apr_hash_t **table_p,
01222 svn_repos_t *repos,
01223 svn_revnum_t rev,
01224 svn_repos_authz_func_t
01225 authz_read_func,
01226 void *authz_read_baton,
01227 apr_pool_t *pool);
01228
01229
01230
01231 /* ---------------------------------------------------------------*/
01232
01233 /* Prop-changing wrappers for libsvn_fs routines. */
01234
01235 /* NOTE: svn_repos_fs_change_rev_prop() also exists, but is located
01236 above with the hook-related functions. */
01237
01238
01239 /** Validating wrapper for svn_fs_change_node_prop() (which see for
01240 * argument descriptions).
01241 */
01242 svn_error_t *svn_repos_fs_change_node_prop (svn_fs_root_t *root,
01243 const char *path,
01244 const char *name,
01245 const svn_string_t *value,
01246 apr_pool_t *pool);
01247
01248 /** Validating wrapper for svn_fs_change_txn_prop() (which see for
01249 * argument descriptions).
01250 */
01251 svn_error_t *svn_repos_fs_change_txn_prop (svn_fs_txn_t *txn,
01252 const char *name,
01253 const svn_string_t *value,
01254 apr_pool_t *pool);
01255
01256 /** @} */
01257
01258 /* ---------------------------------------------------------------*/
01259
01260 /**
01261 * @defgroup svn_repos_inspection Data structures and editor things for
01262 * repository inspection.
01263 * @{
01264 *
01265 * As it turns out, the svn_repos_dir_delta() interface can be
01266 * extremely useful for examining the repository, or more exactly,
01267 * changes to the repository. svn_repos_dir_delta() allows for
01268 * differences between two trees to be described using an editor.
01269 *
01270 * By using the editor obtained from svn_repos_node_editor() with
01271 * svn_repos_dir_delta(), the description of how to transform one tree
01272 * into another can be used to build an in-memory linked-list tree,
01273 * which each node representing a repository node that was changed as a
01274 * result of having svn_repos_dir_delta() drive that editor.
01275 */
01276
01277 /** A node in the repository. */
01278 typedef struct svn_repos_node_t
01279 {
01280 /** Node type (file, dir, etc.) */
01281 svn_node_kind_t kind;
01282
01283 /** How this node entered the node tree: 'A'dd, 'D'elete, 'R'eplace */
01284 char action;
01285
01286 /** Were there any textual mods? (files only) */
01287 svn_boolean_t text_mod;
01288
01289 /** Where there any property mods? */
01290 svn_boolean_t prop_mod;
01291
01292 /** The name of this node as it appears in its parent's entries list */
01293 const char *name;
01294
01295 /** The filesystem revision where this was copied from (if any) */
01296 svn_revnum_t copyfrom_rev;
01297
01298 /** The filesystem path where this was copied from (if any) */
01299 const char *copyfrom_path;
01300
01301 /** Pointer to the next sibling of this node */
01302 struct svn_repos_node_t *sibling;
01303
01304 /** Pointer to the first child of this node */
01305 struct svn_repos_node_t *child;
01306
01307 /** Pointer to the parent of this node */
01308 struct svn_repos_node_t *parent;
01309
01310 } svn_repos_node_t;
01311
01312
01313 /** Set @a *editor and @a *edit_baton to an editor that, when driven by
01314 * svn_repos_dir_delta(), builds an <tt>svn_repos_node_t *</tt> tree
01315 * representing the delta from @a base_root to @a root in @a repos's
01316 * filesystem.
01317 *
01318 * Invoke svn_repos_node_from_baton() on @a edit_baton to obtain the root
01319 * node afterwards.
01320 *
01321 * Note that the delta includes "bubbled-up" directories; that is,
01322 * many of the directory nodes will have no prop_mods.
01323 *
01324 * Allocate the tree and its contents in @a node_pool; do all other
01325 * allocation in @a pool.
01326 */
01327 svn_error_t *svn_repos_node_editor (const svn_delta_editor_t **editor,
01328 void **edit_baton,
01329 svn_repos_t *repos,
01330 svn_fs_root_t *base_root,
01331 svn_fs_root_t *root,
01332 apr_pool_t *node_pool,
01333 apr_pool_t *pool);
01334
01335 /** Return the root node of the linked-list tree generated by driving
01336 * the editor created by svn_repos_node_editor() with
01337 * svn_repos_dir_delta(), which is stored in @a edit_baton. This is
01338 * only really useful if used *after* the editor drive is completed.
01339 */
01340 svn_repos_node_t *svn_repos_node_from_baton (void *edit_baton);
01341
01342 /** @} */
01343
01344 /* ---------------------------------------------------------------*/
01345
01346 /**
01347 * @defgroup svn_repos_dump_load Dumping and loading filesystem data
01348 * @{
01349 *
01350 * The filesystem 'dump' format contains nothing but the abstract
01351 * structure of the filesystem -- independent of any internal node-id
01352 * schema or database back-end. All of the data in the dumpfile is
01353 * acquired by public function calls into svn_fs.h. Similarly, the
01354 * parser which reads the dumpfile is able to reconstruct the
01355 * filesystem using only public svn_fs.h routines.
01356 *
01357 * Thus the dump/load feature's main purpose is for *migrating* data
01358 * from one svn filesystem to another -- presumably two filesystems
01359 * which have different internal implementations.
01360 *
01361 * If you simply want to backup your filesystem, you're probably
01362 * better off using the built-in facilities of the DB backend (using
01363 * Berkeley DB's hot-backup feature, for example.)
01364 *
01365 * For a description of the dumpfile format, see
01366 * /trunk/notes/fs_dumprestore.txt.
01367 */
01368
01369 /* The RFC822-style headers in our dumpfile format. */
01370 #define SVN_REPOS_DUMPFILE_MAGIC_HEADER "SVN-fs-dump-format-version"
01371 #define SVN_REPOS_DUMPFILE_FORMAT_VERSION 3
01372 #define SVN_REPOS_DUMPFILE_UUID "UUID"
01373 #define SVN_REPOS_DUMPFILE_CONTENT_LENGTH "Content-length"
01374
01375 #define SVN_REPOS_DUMPFILE_REVISION_NUMBER "Revision-number"
01376
01377 #define SVN_REPOS_DUMPFILE_NODE_PATH "Node-path"
01378 #define SVN_REPOS_DUMPFILE_NODE_KIND "Node-kind"
01379 #define SVN_REPOS_DUMPFILE_NODE_ACTION "Node-action"
01380 #define SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH "Node-copyfrom-path"
01381 #define SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV "Node-copyfrom-rev"
01382 #define SVN_REPOS_DUMPFILE_TEXT_COPY_SOURCE_CHECKSUM "Text-copy-source-md5"
01383 #define SVN_REPOS_DUMPFILE_TEXT_CONTENT_CHECKSUM "Text-content-md5"
01384
01385 #define SVN_REPOS_DUMPFILE_PROP_CONTENT_LENGTH "Prop-content-length"
01386 #define SVN_REPOS_DUMPFILE_TEXT_CONTENT_LENGTH "Text-content-length"
01387
01388 /* @since New in 1.1. */
01389 #define SVN_REPOS_DUMPFILE_PROP_DELTA "Prop-delta"
01390 /* @since New in 1.1. */
01391 #define SVN_REPOS_DUMPFILE_TEXT_DELTA "Text-delta"
01392
01393 /** The different "actions" attached to nodes in the dumpfile. */
01394 enum svn_node_action
01395 {
01396 svn_node_action_change,
01397 svn_node_action_add,
01398 svn_node_action_delete,
01399 svn_node_action_replace
01400 };
01401
01402 /** The different policies for processing the UUID in the dumpfile. */
01403 enum svn_repos_load_uuid
01404 {
01405 svn_repos_load_uuid_default,
01406 svn_repos_load_uuid_ignore,
01407 svn_repos_load_uuid_force
01408 };
01409
01410 /**
01411 * Dump the contents of the filesystem within already-open @a repos into
01412 * writable @a dumpstream. Begin at revision @a start_rev, and dump every
01413 * revision up through @a end_rev. Use @a pool for all allocation. If
01414 * non-@c NULL, send feedback to @a feedback_stream. @a dumpstream can be
01415 * @c NULL for the purpose of verifying the repository.
01416 *
01417 * If @a start_rev is @c SVN_INVALID_REVNUM, then start dumping at revision
01418 * 0. If @a end_rev is @c SVN_INVALID_REVNUM, then dump through the @c HEAD
01419 * revision.
01420 *
01421 * If @a incremental is @c TRUE, the first revision dumped will be a diff
01422 * against the previous revision (usually it looks like a full dump of
01423 * the tree).
01424 *
01425 * If @a use_deltas is @c TRUE, output only node properties which have
01426 * changed relative to the previous contents, and output text contents
01427 * as svndiff data against the previous contents. Regardless of how
01428 * this flag is set, the first revision of a non-incremental dump will
01429 * be done with full plain text. A dump with @a use_deltas set cannot
01430 * be loaded by Subversion 1.0.x.
01431 *
01432 * If @a cancel_func is not @c NULL, it is called periodically with
01433 * @a cancel_baton as argument to see if the client wishes to cancel
01434 * the dump.
01435 *
01436 * @since New in 1.1.
01437 */
01438 svn_error_t *svn_repos_dump_fs2 (svn_repos_t *repos,
01439 svn_stream_t *dumpstream,
01440 svn_stream_t *feedback_stream,
01441 svn_revnum_t start_rev,
01442 svn_revnum_t end_rev,
01443 svn_boolean_t incremental,
01444 svn_boolean_t use_deltas,
01445 svn_cancel_func_t cancel_func,
01446 void *cancel_baton,
01447 apr_pool_t *pool);
01448
01449
01450 /**
01451 * Similar to svn_repos_dump_fs2(), but with the @a use_deltas
01452 * parameter always set to @c FALSE.
01453 *
01454 * @deprecated Provided for backward compatibility with the 1.0 API.
01455 */
01456 svn_error_t *svn_repos_dump_fs (svn_repos_t *repos,
01457 svn_stream_t *dumpstream,
01458 svn_stream_t *feedback_stream,
01459 svn_revnum_t start_rev,
01460 svn_revnum_t end_rev,
01461 svn_boolean_t incremental,
01462 svn_cancel_func_t cancel_func,
01463 void *cancel_baton,
01464 apr_pool_t *pool);
01465
01466
01467 /**
01468 * Read and parse dumpfile-formatted @a dumpstream, reconstructing
01469 * filesystem revisions in already-open @a repos, handling uuids
01470 * in accordance with @a uuid_action.
01471 *
01472 * Read and parse dumpfile-formatted @a dumpstream, reconstructing
01473 * filesystem revisions in already-open @a repos. Use @a pool for all
01474 * allocation. If non-@c NULL, send feedback to @a feedback_stream.
01475 *
01476 * If the dumpstream contains copy history that is unavailable in the
01477 * repository, an error will be thrown.
01478 *
01479 * The repository's UUID will be updated iff
01480 * the dumpstream contains a UUID and
01481 * @a uuid_action is not equal to @c svn_repos_load_uuid_ignore and
01482 * either the repository contains no revisions or
01483 * @a uuid_action is equal to @c svn_repos_load_uuid_force.
01484 *
01485 * If the dumpstream contains no UUID, then @a uuid_action is
01486 * ignored and the repository UUID is not touched.
01487 *
01488 * If @a parent_dir is not null, then the parser will reparent all the
01489 * loaded nodes, from root to @a parent_dir. The directory @a parent_dir
01490 * must be an existing directory in the repository.
01491 *
01492 * If @a use_pre_commit_hook is set, call the repository's pre-commit
01493 * hook before committing each loaded revision.
01494 *
01495 * If @a use_post_commit_hook is set, call the repository's
01496 * post-commit hook after committing each loaded revision.
01497 *
01498 * If @a cancel_func is not @c NULL, it is called periodically with
01499 * @a cancel_baton as argument to see if the client wishes to cancel
01500 * the load.
01501 *
01502 * @since New in 1.2.
01503 */
01504 svn_error_t *svn_repos_load_fs2 (svn_repos_t *repos,
01505 svn_stream_t *dumpstream,
01506 svn_stream_t *feedback_stream,
01507 enum svn_repos_load_uuid uuid_action,
01508 const char *parent_dir,
01509 svn_boolean_t use_pre_commit_hook,
01510 svn_boolean_t use_post_commit_hook,
01511 svn_cancel_func_t cancel_func,
01512 void *cancel_baton,
01513 apr_pool_t *pool);
01514
01515 /**
01516 * Similar to svn_repos_load_fs2(), but with @a use_pre_commit_hook and
01517 * @a use_post_commit_hook always @c FALSE.
01518 *
01519 * @deprecated Provided for backward compatibility with the 1.0 API.
01520 */
01521 svn_error_t *svn_repos_load_fs (svn_repos_t *repos,
01522 svn_stream_t *dumpstream,
01523 svn_stream_t *feedback_stream,
01524 enum svn_repos_load_uuid uuid_action,
01525 const char *parent_dir,
01526 svn_cancel_func_t cancel_func,
01527 void *cancel_baton,
01528 apr_pool_t *pool);
01529
01530
01531 /**
01532 * A vtable that is driven by svn_repos_parse_dumpstream2().
01533 *
01534 * @since New in 1.1.
01535 */
01536 typedef struct svn_repos_parse_fns2_t
01537 {
01538 /** The parser has discovered a new revision record within the
01539 * parsing session represented by @a parse_baton. All the headers are
01540 * placed in @a headers (allocated in @a pool), which maps <tt>const
01541 * char *</tt> header-name ==> <tt>const char *</tt> header-value.
01542 * The @a revision_baton received back (also allocated in @a pool)
01543 * represents the revision.
01544 */
01545 svn_error_t *(*new_revision_record) (void **revision_baton,
01546 apr_hash_t *headers,
01547 void *parse_baton,
01548 apr_pool_t *pool);
01549
01550 /** The parser has discovered a new uuid record within the parsing
01551 * session represented by @a parse_baton. The uuid's value is
01552 * @a uuid, and it is allocated in @a pool.
01553 */
01554 svn_error_t *(*uuid_record) (const char *uuid,
01555 void *parse_baton,
01556 apr_pool_t *pool);
01557
01558 /** The parser has discovered a new node record within the current
01559 * revision represented by @a revision_baton. All the headers are
01560 * placed in @a headers (as with @c new_revision_record), allocated in
01561 * @a pool. The @a node_baton received back is allocated in @a pool
01562 * and represents the node.
01563 */
01564 svn_error_t *(*new_node_record) (void **node_baton,
01565 apr_hash_t *headers,
01566 void *revision_baton,
01567 apr_pool_t *pool);
01568
01569 /** For a given @a revision_baton, set a property @a name to @a value. */
01570 svn_error_t *(*set_revision_property) (void *revision_baton,
01571 const char *name,
01572 const svn_string_t *value);
01573
01574 /** For a given @a node_baton, set a property @a name to @a value. */
01575 svn_error_t *(*set_node_property) (void *node_baton,
01576 const char *name,
01577 const svn_string_t *value);
01578
01579 /** For a given @a node_baton, delete property @a name. */
01580 svn_error_t *(*delete_node_property) (void *node_baton, const char *name);
01581
01582 /** For a given @a node_baton, remove all properties. */
01583 svn_error_t *(*remove_node_props) (void *node_baton);
01584
01585 /** For a given @a node_baton, receive a writable @a stream capable of
01586 * receiving the node's fulltext. After writing the fulltext, call
01587 * the stream's close() function.
01588 *
01589 * If a @c NULL is returned instead of a stream, the vtable is
01590 * indicating that no text is desired, and the parser will not
01591 * attempt to send it.
01592 */
01593 svn_error_t *(*set_fulltext) (svn_stream_t **stream,
01594 void *node_baton);
01595
01596 /** For a given @a node_baton, set @a handler and @a handler_baton
01597 * to a window handler and baton capable of receiving a delta
01598 * against the node's previous contents. A NULL window will be
01599 * sent to the handler after all the windows are sent.
01600 *
01601 * If a @c NULL is returned instead of a handler, the vtable is
01602 * indicating that no delta is desired, and the parser will not
01603 * attempt to send it.
01604 */
01605 svn_error_t *(*apply_textdelta) (svn_txdelta_window_handler_t *handler,
01606 void **handler_baton,
01607 void *node_baton);
01608
01609 /** The parser has reached the end of the current node represented by
01610 * @a node_baton, it can be freed.
01611 */
01612 svn_error_t *(*close_node) (void *node_baton);
01613
01614 /** The parser has reached the end of the current revision
01615 * represented by @a revision_baton. In other words, there are no more
01616 * changed nodes within the revision. The baton can be freed.
01617 */
01618 svn_error_t *(*close_revision) (void *revision_baton);
01619
01620 } svn_repos_parse_fns2_t;
01621
01622 /** @deprecated Provided for backward compatibility with the 1.2 API. */
01623 typedef svn_repos_parse_fns2_t svn_repos_parser_fns2_t;
01624
01625
01626 /**
01627 * Read and parse dumpfile-formatted @a stream, calling callbacks in
01628 * @a parse_fns/@a parse_baton, and using @a pool for allocations.
01629 *
01630 * If @a cancel_func is not @c NULL, it is called periodically with
01631 * @a cancel_baton as argument to see if the client wishes to cancel
01632 * the dump.
01633 *
01634 * This parser has built-in knowledge of the dumpfile format, but only
01635 * in a general sense:
01636 *
01637 * * it recognizes revision and node records by looking for either
01638 * a REVISION_NUMBER or NODE_PATH headers.
01639 *
01640 * * it recognizes the CONTENT-LENGTH headers, so it knows if and
01641 * how to suck up the content body.
01642 *
01643 * * it knows how to parse a content body into two parts: props
01644 * and text, and pass the pieces to the vtable.
01645 *
01646 * This is enough knowledge to make it easy on vtable implementors,
01647 * but still allow expansion of the format: most headers are ignored.
01648 *
01649 * @since New in 1.1.
01650 */
01651 svn_error_t *
01652 svn_repos_parse_dumpstream2 (svn_stream_t *stream,
01653 const svn_repos_parse_fns2_t *parse_fns,
01654 void *parse_baton,
01655 svn_cancel_func_t cancel_func,
01656 void *cancel_baton,
01657 apr_pool_t *pool);
01658
01659
01660 /**
01661 * Set @a *parser and @a *parse_baton to a vtable parser which commits new
01662 * revisions to the fs in @a repos. The constructed parser will treat
01663 * UUID records in a manner consistent with @a uuid_action. Use @a pool
01664 * to operate on the fs.
01665 *
01666 * If @a use_history is set, then the parser will require relative
01667 * 'copyfrom' history to exist in the repository when it encounters
01668 * nodes that are added-with-history.
01669 *
01670 * If @a parent_dir is not null, then the parser will reparent all the
01671 * loaded nodes, from root to @a parent_dir. The directory @a parent_dir
01672 * must be an existing directory in the repository.
01673 *
01674 * Print all parsing feedback to @a outstream (if non-@c NULL).
01675 *
01676 *
01677 * @since New in 1.1.
01678 */
01679 svn_error_t *
01680 svn_repos_get_fs_build_parser2 (const svn_repos_parse_fns2_t **parser,
01681 void **parse_baton,
01682 svn_repos_t *repos,
01683 svn_boolean_t use_history,
01684 enum svn_repos_load_uuid uuid_action,
01685 svn_stream_t *outstream,
01686 const char *parent_dir,
01687 apr_pool_t *pool);
01688
01689
01690 /**
01691 * A vtable that is driven by svn_repos_parse_dumpstream().
01692 * Similar to @c svn_repos_parse_fns2_t except that it lacks
01693 * the delete_node_property and apply_textdelta callbacks.
01694 *
01695 * @deprecated Provided for backward compatibility with the 1.0 API.
01696 */
01697 typedef struct svn_repos_parse_fns_t
01698 {
01699 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01700 svn_error_t *(*new_revision_record) (void **revision_baton,
01701 apr_hash_t *headers,
01702 void *parse_baton,
01703 apr_pool_t *pool);
01704 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01705 svn_error_t *(*uuid_record) (const char *uuid,
01706 void *parse_baton,
01707 apr_pool_t *pool);
01708 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01709 svn_error_t *(*new_node_record) (void **node_baton,
01710 apr_hash_t *headers,
01711 void *revision_baton,
01712 apr_pool_t *pool);
01713 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01714 svn_error_t *(*set_revision_property) (void *revision_baton,
01715 const char *name,
01716 const svn_string_t *value);
01717 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01718 svn_error_t *(*set_node_property) (void *node_baton,
01719 const char *name,
01720 const svn_string_t *value);
01721 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01722 svn_error_t *(*remove_node_props) (void *node_baton);
01723 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01724 svn_error_t *(*set_fulltext) (svn_stream_t **stream,
01725 void *node_baton);
01726 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01727 svn_error_t *(*close_node) (void *node_baton);
01728 /** Same as the corresponding field in @c svn_repos_parse_fns2_t. */
01729 svn_error_t *(*close_revision) (void *revision_baton);
01730 } svn_repos_parser_fns_t;
01731
01732
01733 /**
01734 * Similar to svn_repos_parse_dumpstream2(), but uses the more limited
01735 * @c svn_repos_parser_fns_t vtable type.
01736 *
01737 * @deprecated Provided for backward compatibility with the 1.0 API.
01738 */
01739 svn_error_t *
01740 svn_repos_parse_dumpstream (svn_stream_t *stream,
01741 const svn_repos_parser_fns_t *parse_fns,
01742 void *parse_baton,
01743 svn_cancel_func_t cancel_func,
01744 void *cancel_baton,
01745 apr_pool_t *pool);
01746
01747
01748 /**
01749 * Similar to svn_repos_get_fs_build_parser2(), but yields the more
01750 * limited svn_repos_parser_fns_t vtable type.
01751 *
01752 * @deprecated Provided for backward compatibility with the 1.0 API.
01753 */
01754 svn_error_t *
01755 svn_repos_get_fs_build_parser (const svn_repos_parser_fns_t **parser,
01756 void **parse_baton,
01757 svn_repos_t *repos,
01758 svn_boolean_t use_history,
01759 enum svn_repos_load_uuid uuid_action,
01760 svn_stream_t *outstream,
01761 const char *parent_dir,
01762 apr_pool_t *pool);
01763
01764
01765 /** @} */
01766
01767 /** A data type which stores the authz information.
01768 *
01769 * @since New in 1.3.
01770 */
01771 typedef struct svn_authz_t svn_authz_t;
01772
01773 /** Read authz configuration data from @a file (a file or registry
01774 * path) into @a *authz_p, allocated in @a pool.
01775 *
01776 * If @a file is not a valid authz rule file, then return
01777 * SVN_AUTHZ_INVALID_CONFIG. The contents of @a *authz_p is then
01778 * undefined. If @a must_exist is TRUE, a missing authz file is also
01779 * an error.
01780 *
01781 * @since New in 1.3.
01782 */
01783 svn_error_t *
01784 svn_repos_authz_read (svn_authz_t **authz_p, const char *file,
01785 svn_boolean_t must_exist, apr_pool_t *pool);
01786
01787 /**
01788 * Check whether @a user can access @a path in the repository @a
01789 * repos_name with the @a required_access. @a authz lists the ACLs to
01790 * check against. Set @a *access_granted to indicate if the requested
01791 * access is granted.
01792 *
01793 * If @a path is NULL, then check whether @a user has the @a
01794 * required_access anywhere in the repository. Set @a *access_granted
01795 * to TRUE if at least one path is accessible with the @a
01796 * required_access.
01797 *
01798 * @since New in 1.3.
01799 */
01800 svn_error_t *
01801 svn_repos_authz_check_access (svn_authz_t *authz, const char *repos_name,
01802 const char *path, const char *user,
01803 svn_repos_authz_access_t required_access,
01804 svn_boolean_t *access_granted,
01805 apr_pool_t *pool);
01806
01807 #ifdef __cplusplus
01808 }
01809 #endif /* __cplusplus */
01810
01811 #endif /* SVN_REPOS_H */
1.2.14 written by Dimitri van Heesch,
© 1997-2002