svn_error_t * svn_repos__hooks_pre_unlock(svn_repos_t *repos, const char *path, const char *username, const char *token, svn_boolean_t break_lock, apr_pool_t *pool) { const char *hook = svn_repos_pre_unlock_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[7]; args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = path; args[3] = username ? username : ""; args[4] = token ? token : ""; args[5] = break_lock ? "1" : "0"; args[6] = NULL; SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_UNLOCK, hook, args, repos->hooks_env, NULL, pool)); } return SVN_NO_ERROR; }
svn_error_t * svn_repos__hooks_post_commit(svn_repos_t *repos, svn_revnum_t rev, apr_pool_t *pool) { const char *hook = svn_repos_post_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]; args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = apr_psprintf(pool, "%ld", rev); args[3] = NULL; SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_COMMIT, hook, args, repos->hooks_env, NULL, pool)); } return SVN_NO_ERROR; }
svn_error_t * svn_repos__hooks_pre_revprop_change(svn_repos_t *repos, svn_revnum_t rev, const char *author, const char *name, const svn_string_t *new_value, char action, apr_pool_t *pool) { const char *hook = svn_repos_pre_revprop_change_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[7]; apr_file_t *stdin_handle = NULL; char action_string[2]; /* Pass the new value as stdin to hook */ if (new_value) SVN_ERR(create_temp_file(&stdin_handle, new_value, pool)); else SVN_ERR(svn_io_file_open(&stdin_handle, SVN_NULL_DEVICE_NAME, APR_READ, APR_OS_DEFAULT, pool)); action_string[0] = action; action_string[1] = '\0'; args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = apr_psprintf(pool, "%ld", rev); args[3] = author ? author : ""; args[4] = name; args[5] = action_string; args[6] = NULL; SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_PRE_REVPROP_CHANGE, hook, args, repos->hooks_env, stdin_handle, pool)); SVN_ERR(svn_io_file_close(stdin_handle, pool)); } else { /* If the pre- hook doesn't exist at all, then default to MASSIVE PARANOIA. Changing revision properties is a lossy operation; so unless the repository admininstrator has *deliberately* created the pre-hook, disallow all changes. */ return svn_error_create (SVN_ERR_REPOS_DISABLED_FEATURE, NULL, _("Repository has not been enabled to accept revision propchanges;\n" "ask the administrator to create a pre-revprop-change hook")); } return SVN_NO_ERROR; }
svn_error_t * svn_repos__hooks_post_revprop_change(svn_repos_t *repos, apr_hash_t *hooks_env, svn_revnum_t rev, const char *author, const char *name, const svn_string_t *old_value, char action, apr_pool_t *pool) { const char *hook = svn_repos_post_revprop_change_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[7]; apr_file_t *stdin_handle = NULL; char action_string[2]; /* Pass the old value as stdin to hook */ if (old_value) SVN_ERR(create_temp_file(&stdin_handle, old_value, pool)); else SVN_ERR(svn_io_file_open(&stdin_handle, SVN_NULL_DEVICE_NAME, APR_READ, APR_OS_DEFAULT, pool)); action_string[0] = action; action_string[1] = '\0'; args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = apr_psprintf(pool, "%ld", rev); args[3] = author ? author : ""; args[4] = name; args[5] = action_string; args[6] = NULL; SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_REVPROP_CHANGE, hook, args, hooks_env, stdin_handle, pool)); SVN_ERR(svn_io_file_close(stdin_handle, pool)); } return SVN_NO_ERROR; }
svn_error_t * svn_repos__hooks_start_commit(svn_repos_t *repos, apr_hash_t *hooks_env, const char *user, const apr_array_header_t *capabilities, const char *txn_name, apr_pool_t *pool) { const char *hook = svn_repos_start_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[6]; char *capabilities_string; if (capabilities) { capabilities_string = svn_cstring_join(capabilities, ":", pool); /* Get rid of that annoying final colon. */ if (capabilities_string[0]) capabilities_string[strlen(capabilities_string) - 1] = '\0'; } else { capabilities_string = apr_pstrdup(pool, ""); } args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = user ? user : ""; args[3] = capabilities_string; args[4] = txn_name; args[5] = NULL; SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_START_COMMIT, hook, args, hooks_env, NULL, pool)); } return SVN_NO_ERROR; }
svn_error_t * svn_repos__hooks_pre_lock(svn_repos_t *repos, apr_hash_t *hooks_env, const char **token, const char *path, const char *username, const char *comment, svn_boolean_t steal_lock, apr_pool_t *pool) { const char *hook = svn_repos_pre_lock_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[7]; svn_string_t *buf; args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = path; args[3] = username; args[4] = comment ? comment : ""; args[5] = steal_lock ? "1" : "0"; args[6] = NULL; SVN_ERR(run_hook_cmd(&buf, SVN_REPOS__HOOK_PRE_LOCK, hook, args, hooks_env, NULL, pool)); if (token) /* No validation here; the FS will take care of that. */ *token = buf->data; } else if (token) *token = ""; 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; }
svn_error_t * svn_repos__hooks_post_unlock(svn_repos_t *repos, apr_hash_t *hooks_env, const apr_array_header_t *paths, const char *username, apr_pool_t *pool) { const char *hook = svn_repos_post_unlock_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[5]; apr_file_t *stdin_handle = NULL; svn_string_t *paths_str = svn_string_create(svn_cstring_join (paths, "\n", pool), pool); SVN_ERR(create_temp_file(&stdin_handle, paths_str, pool)); args[0] = hook; args[1] = svn_dirent_local_style(svn_repos_path(repos, pool), pool); args[2] = username ? username : ""; args[3] = NULL; args[4] = NULL; SVN_ERR(run_hook_cmd(NULL, SVN_REPOS__HOOK_POST_UNLOCK, hook, args, hooks_env, stdin_handle, pool)); SVN_ERR(svn_io_file_close(stdin_handle, pool)); } return SVN_NO_ERROR; }