svn_error_t * svn_repos_fs_lock(svn_lock_t **lock, svn_repos_t *repos, const char *path, const char *token, const char *comment, svn_boolean_t is_dav_comment, apr_time_t expiration_date, svn_revnum_t current_rev, svn_boolean_t steal_lock, apr_pool_t *pool) { svn_error_t *err; svn_fs_access_t *access_ctx = NULL; const char *username = NULL; const char *new_token; apr_array_header_t *paths; apr_hash_t *hooks_env; /* Parse the hooks-env file (if any). */ SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path, pool, pool)); /* Setup an array of paths in anticipation of the ra layers handling multiple locks in one request (1.3 most likely). This is only used by svn_repos__hooks_post_lock. */ paths = apr_array_make(pool, 1, sizeof(const char *)); APR_ARRAY_PUSH(paths, const char *) = path; SVN_ERR(svn_fs_get_access(&access_ctx, repos->fs)); if (access_ctx) SVN_ERR(svn_fs_access_get_username(&username, access_ctx)); if (! username) return svn_error_createf (SVN_ERR_FS_NO_USER, NULL, "Cannot lock path '%s', no authenticated username available.", path); /* Run pre-lock hook. This could throw error, preventing svn_fs_lock() from happening. */ SVN_ERR(svn_repos__hooks_pre_lock(repos, hooks_env, &new_token, path, username, comment, steal_lock, pool)); if (*new_token) token = new_token; /* Lock. */ SVN_ERR(svn_fs_lock(lock, repos->fs, path, token, comment, is_dav_comment, expiration_date, current_rev, steal_lock, pool)); /* Run post-lock hook. */ if ((err = svn_repos__hooks_post_lock(repos, hooks_env, paths, username, pool))) return svn_error_create (SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED, err, "Lock succeeded, but post-lock hook failed"); return SVN_NO_ERROR; }
svn_error_t * svn_repos_fs_unlock(svn_repos_t *repos, const char *path, const char *token, svn_boolean_t break_lock, apr_pool_t *pool) { svn_error_t *err; svn_fs_access_t *access_ctx = NULL; const char *username = NULL; apr_array_header_t *paths; apr_hash_t *hooks_env; /* Parse the hooks-env file (if any). */ SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path, pool, pool)); /* Setup an array of paths in anticipation of the ra layers handling multiple locks in one request (1.3 most likely). This is only used by svn_repos__hooks_post_lock. */ paths = apr_array_make(pool, 1, sizeof(const char *)); APR_ARRAY_PUSH(paths, const char *) = path; SVN_ERR(svn_fs_get_access(&access_ctx, repos->fs)); if (access_ctx) SVN_ERR(svn_fs_access_get_username(&username, access_ctx)); if (! break_lock && ! username) return svn_error_createf (SVN_ERR_FS_NO_USER, NULL, _("Cannot unlock path '%s', no authenticated username available"), path); /* Run pre-unlock hook. This could throw error, preventing svn_fs_unlock() from happening. */ SVN_ERR(svn_repos__hooks_pre_unlock(repos, hooks_env, path, username, token, break_lock, pool)); /* Unlock. */ SVN_ERR(svn_fs_unlock(repos->fs, path, token, break_lock, pool)); /* Run post-unlock hook. */ if ((err = svn_repos__hooks_post_unlock(repos, hooks_env, paths, username, pool))) return svn_error_create (SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED, err, _("Unlock succeeded, but post-unlock hook failed")); return SVN_NO_ERROR; }
svn_error_t * svn_repos__hooks_pre_commit(svn_repos_t *repos, apr_hash_t *hooks_env, const char *txn_name, apr_pool_t *pool) { const char *hook = svn_repos_pre_commit_hook(repos, pool); svn_boolean_t broken_link; if ((hook = check_hook_cmd(hook, &broken_link, pool)) && broken_link) { return hook_symlink_error(hook); } else if (hook) { const char *args[4]; svn_fs_access_t *access_ctx; apr_file_t *stdin_handle = NULL; args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = txn_name; args[3] = NULL; SVN_ERR(svn_fs_get_access(&access_ctx, repos->fs)); if (access_ctx) { apr_hash_t *lock_tokens = svn_fs__access_get_lock_tokens(access_ctx); if (apr_hash_count(lock_tokens)) { SVN_ERR(lock_token_content(&stdin_handle, lock_tokens, pool)); } } if (!stdin_handle) SVN_ERR(svn_io_file_open(&stdin_handle, SVN_NULL_DEVICE_NAME, APR_READ, APR_OS_DEFAULT, pool)); SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_COMMIT, hook, args, hooks_env, stdin_handle, pool)); } return SVN_NO_ERROR; }
static svn_error_t * svn_ra_local__get_commit_editor(svn_ra_session_t *session, const svn_delta_editor_t **editor, void **edit_baton, apr_hash_t *revprop_table, svn_commit_callback2_t callback, void *callback_baton, apr_hash_t *lock_tokens, svn_boolean_t keep_locks, apr_pool_t *pool) { svn_ra_local__session_baton_t *sess = session->priv; struct deltify_etc_baton *db = apr_palloc(pool, sizeof(*db)); apr_hash_index_t *hi; svn_fs_access_t *fs_access; db->fs = sess->fs; db->repos = sess->repos; db->fs_path = sess->fs_path->data; if (! keep_locks) db->lock_tokens = lock_tokens; else db->lock_tokens = NULL; db->pool = pool; db->callback = callback; db->callback_baton = callback_baton; SVN_ERR(get_username(session, pool)); /* If there are lock tokens to add, do so. */ if (lock_tokens) { SVN_ERR(svn_fs_get_access(&fs_access, sess->fs)); /* If there is no access context, the filesystem will scream if a lock is needed. */ if (fs_access) { for (hi = apr_hash_first(pool, lock_tokens); hi; hi = apr_hash_next(hi)) { void *val; const char *path, *token; const void *key; apr_hash_this(hi, &key, NULL, &val); path = svn_path_join(sess->fs_path->data, (const char *)key, pool); token = val; SVN_ERR(svn_fs_access_add_lock_token2(fs_access, path, token)); } } } /* Copy the revprops table so we can add the username. */ revprop_table = apr_hash_copy(pool, revprop_table); apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, APR_HASH_KEY_STRING, svn_string_create(sess->username, pool)); /* Get the repos commit-editor */ return svn_repos_get_commit_editor5 (editor, edit_baton, sess->repos, NULL, svn_path_uri_decode(sess->repos_url, pool), sess->fs_path->data, revprop_table, deltify_etc, db, NULL, NULL, pool); }