1/* repos.h : interface to Subversion repository, private to libsvn_repos
2 *
3 * ====================================================================
4 *    Licensed to the Apache Software Foundation (ASF) under one
5 *    or more contributor license agreements.  See the NOTICE file
6 *    distributed with this work for additional information
7 *    regarding copyright ownership.  The ASF licenses this file
8 *    to you under the Apache License, Version 2.0 (the
9 *    "License"); you may not use this file except in compliance
10 *    with the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *    Unless required by applicable law or agreed to in writing,
15 *    software distributed under the License is distributed on an
16 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 *    KIND, either express or implied.  See the License for the
18 *    specific language governing permissions and limitations
19 *    under the License.
20 * ====================================================================
21 */
22
23#ifndef SVN_LIBSVN_REPOS_H
24#define SVN_LIBSVN_REPOS_H
25
26#include <apr_pools.h>
27#include <apr_hash.h>
28
29#include "svn_fs.h"
30#include "svn_config.h"
31
32#ifdef __cplusplus
33extern "C" {
34#endif /* __cplusplus */
35
36
37/* Repository format number.
38
39   Formats 0, 1 and 2 were pre-1.0.
40
41   Format 3 was current for 1.0 through to 1.3.
42
43   Format 4 was an abortive experiment during the development of the
44   locking feature in the lead up to 1.2.
45
46   Format 5 was new in 1.4, and is the first format which may contain
47   BDB or FSFS filesystems with a FS format other than 1, since prior
48   formats are accepted by some versions of Subversion which do not
49   pay attention to the FS format number.
50*/
51#define SVN_REPOS__FORMAT_NUMBER         SVN_REPOS__FORMAT_NUMBER_1_4
52#define SVN_REPOS__FORMAT_NUMBER_1_4     5
53#define SVN_REPOS__FORMAT_NUMBER_LEGACY  3
54
55
56/*** Repository layout. ***/
57
58/* The top-level repository dir contains a README and various
59   subdirectories.  */
60#define SVN_REPOS__README      "README.txt" /* Explanation for trespassers. */
61#define SVN_REPOS__FORMAT      "format"     /* Stores the current version
62                                               of the repository. */
63#define SVN_REPOS__DB_DIR      "db"         /* Where Berkeley lives. */
64#define SVN_REPOS__DAV_DIR     "dav"        /* DAV sandbox, for pre-1.5 */
65#define SVN_REPOS__LOCK_DIR    "locks"      /* Lock files live here. */
66#define SVN_REPOS__HOOK_DIR    "hooks"      /* Hook programs. */
67#define SVN_REPOS__CONF_DIR    "conf"       /* Configuration files. */
68
69/* Things for which we keep lockfiles. */
70#define SVN_REPOS__DB_LOCKFILE "db.lock" /* Our Berkeley lockfile. */
71#define SVN_REPOS__DB_LOGS_LOCKFILE "db-logs.lock" /* BDB logs lockfile. */
72
73/* In the repository hooks directory, look for these files. */
74#define SVN_REPOS__HOOK_START_COMMIT    "start-commit"
75#define SVN_REPOS__HOOK_PRE_COMMIT      "pre-commit"
76#define SVN_REPOS__HOOK_POST_COMMIT     "post-commit"
77#define SVN_REPOS__HOOK_READ_SENTINEL   "read-sentinels"
78#define SVN_REPOS__HOOK_WRITE_SENTINEL  "write-sentinels"
79#define SVN_REPOS__HOOK_PRE_REVPROP_CHANGE  "pre-revprop-change"
80#define SVN_REPOS__HOOK_POST_REVPROP_CHANGE "post-revprop-change"
81#define SVN_REPOS__HOOK_PRE_LOCK        "pre-lock"
82#define SVN_REPOS__HOOK_POST_LOCK       "post-lock"
83#define SVN_REPOS__HOOK_PRE_UNLOCK      "pre-unlock"
84#define SVN_REPOS__HOOK_POST_UNLOCK     "post-unlock"
85
86
87/* The extension added to the names of example hook scripts. */
88#define SVN_REPOS__HOOK_DESC_EXT        ".tmpl"
89
90/* The file which contains a custom set of environment variables
91 * passed inherited to hook scripts, in the repository conf directory. */
92#define SVN_REPOS__CONF_HOOKS_ENV "hooks-env"
93/* The name of the default section in the hooks-env config file. */
94#define SVN_REPOS__HOOKS_ENV_DEFAULT_SECTION "default"
95
96/* The configuration file for svnserve, in the repository conf directory. */
97#define SVN_REPOS__CONF_SVNSERVE_CONF "svnserve.conf"
98
99/* In the svnserve default configuration, these are the suggested
100   locations for the passwd, authz and groups files (in the repository
101   conf directory), and we put example templates there. */
102#define SVN_REPOS__CONF_PASSWD "passwd"
103#define SVN_REPOS__CONF_AUTHZ "authz"
104#define SVN_REPOS__CONF_GROUPS "groups"
105
106/* The Repository object, created by svn_repos_open2() and
107   svn_repos_create(). */
108struct svn_repos_t
109{
110  /* A Subversion filesystem object. */
111  svn_fs_t *fs;
112
113  /* The path to the repository's top-level directory. */
114  char *path;
115
116  /* The path to the repository's conf directory. */
117  char *conf_path;
118
119  /* The path to the repository's hooks directory. */
120  char *hook_path;
121
122  /* The path to the repository's locks directory. */
123  char *lock_path;
124
125  /* The path to the Berkeley DB filesystem environment. */
126  char *db_path;
127
128  /* The format number of this repository. */
129  int format;
130
131  /* The path to the repository's hooks enviroment file. If NULL, hooks run
132   * in an empty environment. */
133  const char *hooks_env_path;
134
135  /* The FS backend in use within this repository. */
136  const char *fs_type;
137
138  /* If non-null, a list of all the capabilities the client (on the
139     current connection) has self-reported.  Each element is a
140     'const char *', one of SVN_RA_CAPABILITY_*.
141
142     Note: it is somewhat counterintuitive that we store the client's
143     capabilities, which are session-specific, on the repository
144     object.  You'd think the capabilities here would represent the
145     *repository's* capabilities, but no, they represent the
146     client's -- we just don't have any other place to persist them. */
147  const apr_array_header_t *client_capabilities;
148
149  /* Maps SVN_REPOS_CAPABILITY_foo keys to "yes" or "no" values.
150     If a capability is not yet discovered, it is absent from the table.
151     Most likely the keys and values are constants anyway (and
152     sufficiently well-informed internal code may just compare against
153     those constants' addresses, therefore). */
154  apr_hash_t *repository_capabilities;
155
156  /* Pool from which this structure was allocated.  Also used for
157     auxiliary repository-related data that requires a matching
158     lifespan.  (As the svn_repos_t structure tends to be relatively
159     long-lived, please be careful regarding this pool's usage.)  */
160  apr_pool_t *pool;
161};
162
163
164/*** Hook-running Functions ***/
165
166/* Set *HOOKS_ENV_P to the parsed contents of the hooks-env file
167   LOCAL_ABSPATH, allocated in RESULT_POOL.  (This result is suitable
168   for delivery to the various hook wrapper functions which accept a
169   'hooks_env' parameter.)  If LOCAL_ABSPATH is NULL, set *HOOKS_ENV_P
170   to NULL.
171
172   Use SCRATCH_POOL for temporary allocations.  */
173svn_error_t *
174svn_repos__parse_hooks_env(apr_hash_t **hooks_env_p,
175                           const char *local_abspath,
176                           apr_pool_t *result_pool,
177                           apr_pool_t *scratch_pool);
178
179/* Run the start-commit hook for REPOS.  Use POOL for any temporary
180   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
181
182   HOOKS_ENV is a hash of hook script environment information returned
183   via svn_repos__parse_hooks_env() (or NULL if no such information is
184   available).
185
186   USER is the authenticated name of the user starting the commit.
187
188   CAPABILITIES is a list of 'const char *' capability names (using
189   SVN_RA_CAPABILITY_*) that the client has self-reported.  Note that
190   there is no guarantee the client is telling the truth: the hook
191   should not make security assumptions based on the capabilities.
192
193   TXN_NAME is the name of the commit transaction that's just been
194   created. */
195svn_error_t *
196svn_repos__hooks_start_commit(svn_repos_t *repos,
197                              apr_hash_t *hooks_env,
198                              const char *user,
199                              const apr_array_header_t *capabilities,
200                              const char *txn_name,
201                              apr_pool_t *pool);
202
203/* Run the pre-commit hook for REPOS.  Use POOL for any temporary
204   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
205
206   HOOKS_ENV is a hash of hook script environment information returned
207   via svn_repos__parse_hooks_env() (or NULL if no such information is
208   available).
209
210   TXN_NAME is the name of the transaction that is being committed.  */
211svn_error_t *
212svn_repos__hooks_pre_commit(svn_repos_t *repos,
213                            apr_hash_t *hooks_env,
214                            const char *txn_name,
215                            apr_pool_t *pool);
216
217/* Run the post-commit hook for REPOS.  Use POOL for any temporary
218   allocations.  If the hook fails, run SVN_ERR_REPOS_HOOK_FAILURE.
219
220   HOOKS_ENV is a hash of hook script environment information returned
221   via svn_repos__parse_hooks_env() (or NULL if no such information is
222   available).
223
224   REV is the revision that was created as a result of the commit.  */
225svn_error_t *
226svn_repos__hooks_post_commit(svn_repos_t *repos,
227                             apr_hash_t *hooks_env,
228                             svn_revnum_t rev,
229                             const char *txn_name,
230                             apr_pool_t *pool);
231
232/* Run the pre-revprop-change hook for REPOS.  Use POOL for any
233   temporary allocations.  If the hook fails, return
234   SVN_ERR_REPOS_HOOK_FAILURE.
235
236   HOOKS_ENV is a hash of hook script environment information returned
237   via svn_repos__parse_hooks_env() (or NULL if no such information is
238   available).
239
240   REV is the revision whose property is being changed.
241   AUTHOR is the authenticated name of the user changing the prop.
242   NAME is the name of the property being changed.
243   NEW_VALUE is the new value of the property.
244   ACTION is indicates if the property is being 'A'dded, 'M'odified,
245   or 'D'eleted.
246
247   The pre-revprop-change hook will have the new property value
248   written to its stdin.  If the property is being deleted, no data
249   will be written. */
250svn_error_t *
251svn_repos__hooks_pre_revprop_change(svn_repos_t *repos,
252                                    apr_hash_t *hooks_env,
253                                    svn_revnum_t rev,
254                                    const char *author,
255                                    const char *name,
256                                    const svn_string_t *new_value,
257                                    char action,
258                                    apr_pool_t *pool);
259
260/* Run the pre-revprop-change hook for REPOS.  Use POOL for any
261   temporary allocations.  If the hook fails, return
262   SVN_ERR_REPOS_HOOK_FAILURE.
263
264   HOOKS_ENV is a hash of hook script environment information returned
265   via svn_repos__parse_hooks_env() (or NULL if no such information is
266   available).
267
268   REV is the revision whose property was changed.
269   AUTHOR is the authenticated name of the user who changed the prop.
270   NAME is the name of the property that was changed, and OLD_VALUE is
271   that property's value immediately before the change, or null if
272   none.  ACTION indicates if the property was 'A'dded, 'M'odified,
273   or 'D'eleted.
274
275   The old value will be passed to the post-revprop hook on stdin.  If
276   the property is being created, no data will be written. */
277svn_error_t *
278svn_repos__hooks_post_revprop_change(svn_repos_t *repos,
279                                     apr_hash_t *hooks_env,
280                                     svn_revnum_t rev,
281                                     const char *author,
282                                     const char *name,
283                                     const svn_string_t *old_value,
284                                     char action,
285                                     apr_pool_t *pool);
286
287/* Run the pre-lock hook for REPOS.  Use POOL for any temporary
288   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
289
290   HOOKS_ENV is a hash of hook script environment information returned
291   via svn_repos__parse_hooks_env() (or NULL if no such information is
292   available).
293
294   PATH is the path being locked, USERNAME is the person doing it,
295   COMMENT is the comment of the lock, and is treated as an empty
296   string when NULL is given.  STEAL-LOCK is a flag if the user is
297   stealing the lock.
298
299   If TOKEN is non-null, set *TOKEN to a new lock token generated by
300   the pre-lock hook, if any (see the pre-lock hook template for more
301   information).  If TOKEN is non-null but the hook does not return
302   any token, then set *TOKEN to empty string. */
303
304svn_error_t *
305svn_repos__hooks_pre_lock(svn_repos_t *repos,
306                          apr_hash_t *hooks_env,
307                          const char **token,
308                          const char *path,
309                          const char *username,
310                          const char *comment,
311                          svn_boolean_t steal_lock,
312                          apr_pool_t *pool);
313
314/* Run the post-lock hook for REPOS.  Use POOL for any temporary
315   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
316
317   HOOKS_ENV is a hash of hook script environment information returned
318   via svn_repos__parse_hooks_env() (or NULL if no such information is
319   available).
320
321   PATHS is an array of paths being locked, USERNAME is the person
322   who did it.  */
323svn_error_t *
324svn_repos__hooks_post_lock(svn_repos_t *repos,
325                           apr_hash_t *hooks_env,
326                           const apr_array_header_t *paths,
327                           const char *username,
328                           apr_pool_t *pool);
329
330/* Run the pre-unlock hook for REPOS.  Use POOL for any temporary
331   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
332
333   HOOKS_ENV is a hash of hook script environment information returned
334   via svn_repos__parse_hooks_env() (or NULL if no such information is
335   available).
336
337   PATH is the path being unlocked, USERNAME is the person doing it,
338   TOKEN is the lock token to be unlocked which should not be NULL,
339   and BREAK-LOCK is a flag if the user is breaking the lock.  */
340svn_error_t *
341svn_repos__hooks_pre_unlock(svn_repos_t *repos,
342                            apr_hash_t *hooks_env,
343                            const char *path,
344                            const char *username,
345                            const char *token,
346                            svn_boolean_t break_lock,
347                            apr_pool_t *pool);
348
349/* Run the post-unlock hook for REPOS.  Use POOL for any temporary
350   allocations.  If the hook fails, return SVN_ERR_REPOS_HOOK_FAILURE.
351
352   HOOKS_ENV is a hash of hook script environment information returned
353   via svn_repos__parse_hooks_env() (or NULL if no such information is
354   available).
355
356   PATHS is an array of paths being unlocked, USERNAME is the person
357   who did it.  */
358svn_error_t *
359svn_repos__hooks_post_unlock(svn_repos_t *repos,
360                             apr_hash_t *hooks_env,
361                             const apr_array_header_t *paths,
362                             const char *username,
363                             apr_pool_t *pool);
364
365
366/*** Utility Functions ***/
367
368/* Set *PREV_PATH and *PREV_REV to the path and revision which
369   represent the location at which PATH in FS was located immediately
370   prior to REVISION iff there was a copy operation (to PATH or one of
371   its parent directories) between that previous location and
372   PATH@REVISION, and set *APPEARED_REV to the first revision in which
373   PATH@REVISION appeared at PATH as a result of that copy operation.
374
375   If there was no such copy operation in that portion
376   of PATH's history, set *PREV_PATH to NULL, and set *PREV_REV and
377   *APPEARED_REV to SVN_INVALID_REVNUM.
378
379   NOTE: Any of PREV_PATH, PREV_REV, and APPEARED_REV may be NULL to
380   if that information is of no interest to the caller.  */
381svn_error_t *
382svn_repos__prev_location(svn_revnum_t *appeared_rev,
383                         const char **prev_path,
384                         svn_revnum_t *prev_rev,
385                         svn_fs_t *fs,
386                         svn_revnum_t revision,
387                         const char *path,
388                         apr_pool_t *pool);
389
390#ifdef __cplusplus
391}
392#endif /* __cplusplus */
393
394#endif /* SVN_LIBSVN_REPOS_H */
395