1/* 2 * svn_fs_util.h: Declarations for the APIs of libsvn_fs_util to be 3 * consumed by only fs_* libs. 4 * 5 * ==================================================================== 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 * ==================================================================== 23 */ 24 25#ifndef SVN_FS_UTIL_H 26#define SVN_FS_UTIL_H 27 28#include <apr_pools.h> 29 30#include "svn_types.h" 31#include "svn_error.h" 32#include "svn_version.h" 33#include "svn_fs.h" 34 35#ifdef __cplusplus 36extern "C" { 37#endif /* __cplusplus */ 38 39/* Get libsvn_fs_util version information. */ 40const svn_version_t * 41svn_fs_util__version(void); 42 43/* Returns whether PATH is in canonical form as defined by 44 svn_fs__canonicalize_abspath(). 45 */ 46svn_boolean_t 47svn_fs__is_canonical_abspath(const char *path); 48 49/* Return a canonicalized version of a filesystem PATH, allocated in POOL. 50 51 While the filesystem API is pretty flexible about the incoming paths 52 (they must be UTF-8 with '/' as separators, but they don't have to 53 begin with '/', and multiple contiguous '/'s are ignored) we want any 54 paths that are physically stored in the underlying database to look 55 consistent. Specifically, absolute filesystem paths should begin with 56 '/', and all redundant and trailing '/' characters be removed. 57 58 This is similar to svn_fspath__canonicalize() but doesn't treat "." 59 segments as special. 60*/ 61const char * 62svn_fs__canonicalize_abspath(const char *path, apr_pool_t *pool); 63 64/* If EXPECT_OPEN, verify that FS refers to an open database; 65 otherwise, verify that FS refers to an unopened database. Return 66 an appropriate error if the expectation fails to match the 67 reality. */ 68svn_error_t * 69svn_fs__check_fs(svn_fs_t *fs, svn_boolean_t expect_open); 70 71/* An identifier for FS to be used in the text of error messages. 72 (Not used anywhere but in this header.) 73 74 Note: we log the UUID, rather than (fs)->path, since some of these 75 errors are marshalled to the client. */ 76#define svn_fs__identifier(fs) ((fs)->uuid) 77 78/* Constructing nice error messages for roots. */ 79 80/* Build an SVN_ERR_FS_NOT_FOUND error, with a detailed error text, 81 for PATH in ROOT. ROOT is of type svn_fs_root_t *. */ 82#define SVN_FS__NOT_FOUND(root, path) ( \ 83 root->is_txn_root ? \ 84 svn_error_createf \ 85 (SVN_ERR_FS_NOT_FOUND, 0, \ 86 _("File not found: transaction '%s', path '%s'"), \ 87 root->txn, path) \ 88 : \ 89 svn_error_createf \ 90 (SVN_ERR_FS_NOT_FOUND, 0, \ 91 _("File not found: revision %ld, path '%s'"), \ 92 root->rev, path) \ 93 ) 94 95 96/* Build a detailed `file already exists' message for PATH in ROOT. 97 ROOT is of type svn_fs_root_t *. */ 98#define SVN_FS__ALREADY_EXISTS(root, path_str) ( \ 99 root->is_txn_root ? \ 100 svn_error_createf \ 101 (SVN_ERR_FS_ALREADY_EXISTS, 0, \ 102 _("File already exists: filesystem '%s', transaction '%s', path '%s'"), \ 103 svn_fs__identifier(root->fs), root->txn, path_str) \ 104 : \ 105 svn_error_createf \ 106 (SVN_ERR_FS_ALREADY_EXISTS, 0, \ 107 _("File already exists: filesystem '%s', revision %ld, path '%s'"), \ 108 svn_fs__identifier(root->fs), root->rev, path_str) \ 109 ) 110 111/* ROOT is of type svn_fs_root_t *. */ 112#define SVN_FS__NOT_TXN(root) \ 113 svn_error_create \ 114 (SVN_ERR_FS_NOT_TXN_ROOT, NULL, \ 115 _("Root object must be a transaction root")) 116 117/* SVN_FS__ERR_NOT_MUTABLE: the caller attempted to change a node 118 outside of a transaction. FS is of type "svn_fs_t *". */ 119#define SVN_FS__ERR_NOT_MUTABLE(fs, rev, path_in_repo) \ 120 svn_error_createf( \ 121 SVN_ERR_FS_NOT_MUTABLE, 0, \ 122 _("File is not mutable: filesystem '%s', revision %ld, path '%s'"), \ 123 svn_fs__identifier(fs), rev, path_in_repo) 124 125/* FS is of type "svn_fs_t *".*/ 126#define SVN_FS__ERR_NOT_DIRECTORY(fs, path_in_repo) \ 127 svn_error_createf( \ 128 SVN_ERR_FS_NOT_DIRECTORY, 0, \ 129 _("'%s' is not a directory in filesystem '%s'"), \ 130 path_in_repo, svn_fs__identifier(fs)) 131 132/* FS is of type "svn_fs_t *". */ 133#define SVN_FS__ERR_NOT_FILE(fs, path_in_repo) \ 134 svn_error_createf( \ 135 SVN_ERR_FS_NOT_FILE, 0, \ 136 _("'%s' is not a file in filesystem '%s'"), \ 137 path_in_repo, svn_fs__identifier(fs)) 138 139 140/* FS is of type "svn_fs_t *", LOCK is of type "svn_lock_t *". */ 141#define SVN_FS__ERR_PATH_ALREADY_LOCKED(fs, lock) \ 142 svn_error_createf( \ 143 SVN_ERR_FS_PATH_ALREADY_LOCKED, 0, \ 144 _("Path '%s' is already locked by user '%s' in filesystem '%s'"), \ 145 (lock)->path, (lock)->owner, svn_fs__identifier(fs)) 146 147/* FS is of type "svn_fs_t *". */ 148#define SVN_FS__ERR_NO_SUCH_LOCK(fs, path_in_repo) \ 149 svn_error_createf( \ 150 SVN_ERR_FS_NO_SUCH_LOCK, 0, \ 151 _("No lock on path '%s' in filesystem '%s'"), \ 152 path_in_repo, svn_fs__identifier(fs)) 153 154/* FS is of type "svn_fs_t *". */ 155#define SVN_FS__ERR_LOCK_EXPIRED(fs, token) \ 156 svn_error_createf( \ 157 SVN_ERR_FS_LOCK_EXPIRED, 0, \ 158 _("Lock has expired: lock-token '%s' in filesystem '%s'"), \ 159 token, svn_fs__identifier(fs)) 160 161/* FS is of type "svn_fs_t *". */ 162#define SVN_FS__ERR_NO_USER(fs) \ 163 svn_error_createf( \ 164 SVN_ERR_FS_NO_USER, 0, \ 165 _("No username is currently associated with filesystem '%s'"), \ 166 svn_fs__identifier(fs)) 167 168/* SVN_FS__ERR_LOCK_OWNER_MISMATCH: trying to use a lock whose 169 LOCK_OWNER doesn't match the USERNAME associated with FS. 170 FS is of type "svn_fs_t *". */ 171#define SVN_FS__ERR_LOCK_OWNER_MISMATCH(fs, username, lock_owner) \ 172 svn_error_createf( \ 173 SVN_ERR_FS_LOCK_OWNER_MISMATCH, 0, \ 174 _("User '%s' is trying to use a lock owned by '%s' in " \ 175 "filesystem '%s'"), \ 176 username, lock_owner, svn_fs__identifier(fs)) 177 178/* Return a NULL-terminated copy of the first component of PATH, 179 allocated in POOL. If path is empty, or consists entirely of 180 slashes, return the empty string. 181 182 If the component is followed by one or more slashes, we set *NEXT_P 183 to point after the slashes. If the component ends PATH, we set 184 *NEXT_P to zero. This means: 185 - If *NEXT_P is zero, then the component ends the PATH, and there 186 are no trailing slashes in the path. 187 - If *NEXT_P points at PATH's terminating NULL character, then 188 the component returned was the last, and PATH ends with one or more 189 slash characters. 190 - Otherwise, *NEXT_P points to the beginning of the next component 191 of PATH. You can pass this value to next_entry_name to extract 192 the next component. */ 193char * 194svn_fs__next_entry_name(const char **next_p, 195 const char *path, 196 apr_pool_t *pool); 197 198/* Allocate an svn_fs_path_change2_t structure in POOL, initialize and 199 return it. 200 201 Set the node_rev_id field of the created struct to NODE_REV_ID, and 202 change_kind to CHANGE_KIND. Set all other fields to their _unknown, 203 NULL or invalid value, respectively. */ 204svn_fs_path_change2_t * 205svn_fs__path_change_create_internal(const svn_fs_id_t *node_rev_id, 206 svn_fs_path_change_kind_t change_kind, 207 apr_pool_t *pool); 208 209/* Allocate an svn_fs_path_change3_t structure in RESULT_POOL, initialize 210 and return it. 211 212 Set the change_kind to CHANGE_KIND. Set all other fields to their 213 _unknown, NULL or invalid value, respectively. */ 214svn_fs_path_change3_t * 215svn_fs__path_change_create_internal2(svn_fs_path_change_kind_t change_kind, 216 apr_pool_t *result_pool); 217 218/* Append REL_PATH (which may contain slashes) to each path that exists in 219 the mergeinfo INPUT, and return a new mergeinfo in *OUTPUT. Deep 220 copies the values. Perform all allocations in POOL. */ 221svn_error_t * 222svn_fs__append_to_merged_froms(svn_mergeinfo_t *output, 223 svn_mergeinfo_t input, 224 const char *rel_path, 225 apr_pool_t *pool); 226 227/* Given the FS creation options in CONFIG, return the oldest version that 228 we shall be compatible with in *COMPATIBLE_VERSION. The patch level 229 is always set to 0 and the tag to "". Allocate the result in POOL. 230 231 Note that the result will always be compatible to the current tool 232 version, i.e. will be a version number not more recent than this tool. */ 233svn_error_t * 234svn_fs__compatible_version(svn_version_t **compatible_version, 235 apr_hash_t *config, 236 apr_pool_t *pool); 237 238/* Compare the property lists A and B using POOL for temporary allocations. 239 Return true iff both lists contain the same properties with the same 240 values. A and B may be NULL in which case they will be equal to and 241 empty list. */ 242svn_boolean_t 243svn_fs__prop_lists_equal(apr_hash_t *a, 244 apr_hash_t *b, 245 apr_pool_t *pool); 246 247#ifdef __cplusplus 248} 249#endif /* __cplusplus */ 250 251#endif /* SVN_FS_UTIL_H */ 252