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_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_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; }
svn_error_t * svn_repos_get_commit_editor5(const svn_delta_editor_t **editor, void **edit_baton, svn_repos_t *repos, svn_fs_txn_t *txn, const char *repos_url, const char *base_path, apr_hash_t *revprop_table, svn_commit_callback2_t callback, void *callback_baton, svn_repos_authz_callback_t authz_callback, void *authz_baton, apr_pool_t *pool) { svn_delta_editor_t *e; apr_pool_t *subpool = svn_pool_create(pool); struct edit_baton *eb; /* Do a global authz access lookup. Users with no write access whatsoever to the repository don't get a commit editor. */ if (authz_callback) { svn_boolean_t allowed; SVN_ERR(authz_callback(svn_authz_write, &allowed, NULL, NULL, authz_baton, pool)); if (!allowed) return svn_error_create(SVN_ERR_AUTHZ_UNWRITABLE, NULL, "Not authorized to open a commit editor."); } /* Allocate the structures. */ e = svn_delta_default_editor(pool); eb = apr_pcalloc(subpool, sizeof(*eb)); /* Set up the editor. */ e->open_root = open_root; e->delete_entry = delete_entry; e->add_directory = add_directory; e->open_directory = open_directory; e->change_dir_prop = change_dir_prop; e->add_file = add_file; e->open_file = open_file; e->close_file = close_file; e->apply_textdelta = apply_textdelta; e->change_file_prop = change_file_prop; e->close_edit = close_edit; e->abort_edit = abort_edit; /* Set up the edit baton. */ eb->pool = subpool; eb->revprop_table = svn_prop_hash_dup(revprop_table, subpool); eb->commit_callback = callback; eb->commit_callback_baton = callback_baton; eb->authz_callback = authz_callback; eb->authz_baton = authz_baton; eb->base_path = svn_fspath__canonicalize(base_path, subpool); eb->repos = repos; eb->repos_url = repos_url; eb->repos_name = svn_dirent_basename(svn_repos_path(repos, subpool), subpool); eb->fs = svn_repos_fs(repos); eb->txn = txn; eb->txn_owner = txn == NULL; *edit_baton = eb; *editor = e; return SVN_NO_ERROR; }