/* Conforms to svn_ra_serf__xml_closed_t */ static svn_error_t * blame_closed(svn_ra_serf__xml_estate_t *xes, void *baton, int leaving_state, const svn_string_t *cdata, apr_hash_t *attrs, apr_pool_t *scratch_pool) { blame_context_t *blame_ctx = baton; if (leaving_state == FILE_REV) { /* Note that we test STREAM, but any pointer is currently invalid. It was closed when left the TXDELTA state. */ if (blame_ctx->stream == NULL) { const char *path; const char *rev; path = svn_hash_gets(attrs, "path"); rev = svn_hash_gets(attrs, "rev"); /* Send a "no content" notification. */ SVN_ERR(blame_ctx->file_rev(blame_ctx->file_rev_baton, path, SVN_STR_TO_REV(rev), blame_ctx->rev_props, FALSE /* result_of_merge */, NULL, NULL, /* txdelta / baton */ blame_ctx->prop_diffs, scratch_pool)); } } else if (leaving_state == MERGED_REVISION) { svn_ra_serf__xml_note(xes, FILE_REV, "merged-revision", "*"); } else if (leaving_state == TXDELTA) { SVN_ERR(svn_stream_close(blame_ctx->stream)); } else { const char *name; const svn_string_t *value; SVN_ERR_ASSERT(leaving_state == REV_PROP || leaving_state == SET_PROP || leaving_state == REMOVE_PROP); name = apr_pstrdup(blame_ctx->state_pool, svn_hash_gets(attrs, "name")); if (leaving_state == REMOVE_PROP) { value = NULL; } else { const char *encoding = svn_hash_gets(attrs, "encoding"); if (encoding && strcmp(encoding, "base64") == 0) value = svn_base64_decode_string(cdata, blame_ctx->state_pool); else value = svn_string_dup(cdata, blame_ctx->state_pool); } if (leaving_state == REV_PROP) { svn_hash_sets(blame_ctx->rev_props, name, value); } else { svn_prop_t *prop = apr_array_push(blame_ctx->prop_diffs); prop->name = name; prop->value = value; } } return SVN_NO_ERROR; }
svn_error_t * svn_repos__get_commit_ev2(svn_editor_t **editor, svn_repos_t *repos, svn_authz_t *authz, const char *authz_repos_name, const char *authz_user, apr_hash_t *revprops, svn_commit_callback2_t commit_cb, void *commit_baton, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { static const svn_editor_cb_many_t editor_cbs = { add_directory_cb, add_file_cb, add_symlink_cb, add_absent_cb, alter_directory_cb, alter_file_cb, alter_symlink_cb, delete_cb, copy_cb, move_cb, rotate_cb, complete_cb, abort_cb }; struct ev2_baton *eb; const svn_string_t *author; 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, scratch_pool, scratch_pool)); /* Can the user modify the repository at all? */ /* ### check against AUTHZ. */ author = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR); eb = apr_palloc(result_pool, sizeof(*eb)); eb->repos = repos; eb->authz = authz; eb->authz_repos_name = authz_repos_name; eb->authz_user = authz_user; eb->commit_cb = commit_cb; eb->commit_baton = commit_baton; SVN_ERR(svn_fs__editor_create(&eb->inner, &eb->txn_name, repos->fs, SVN_FS_TXN_CHECK_LOCKS, cancel_func, cancel_baton, result_pool, scratch_pool)); /* The TXN has been created. Go ahead and apply all revision properties. */ SVN_ERR(apply_revprops(repos->fs, eb->txn_name, revprops, scratch_pool)); /* Okay... some access is allowed. Let's run the start-commit hook. */ SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env, author ? author->data : NULL, repos->client_capabilities, eb->txn_name, scratch_pool)); /* Wrap the FS editor within our editor. */ SVN_ERR(svn_editor_create(editor, eb, cancel_func, cancel_baton, result_pool, scratch_pool)); SVN_ERR(svn_editor_setcb_many(*editor, &editor_cbs, scratch_pool)); return SVN_NO_ERROR; }
svn_error_t * svn_config_walk_auth_data(const char *config_dir, svn_config_auth_walk_func_t walk_func, void *walk_baton, apr_pool_t *scratch_pool) { int i; apr_pool_t *iterpool; svn_boolean_t finished = FALSE; const char *cred_kinds[] = { SVN_AUTH_CRED_SIMPLE, SVN_AUTH_CRED_USERNAME, SVN_AUTH_CRED_SSL_CLIENT_CERT, SVN_AUTH_CRED_SSL_CLIENT_CERT_PW, SVN_AUTH_CRED_SSL_SERVER_TRUST, NULL }; iterpool = svn_pool_create(scratch_pool); for (i = 0; cred_kinds[i]; i++) { const char *item_path; const char *dir_path; apr_hash_t *nodes; svn_error_t *err; apr_pool_t *itempool; apr_hash_index_t *hi; svn_pool_clear(iterpool); if (finished) break; SVN_ERR(svn_auth__file_path(&item_path, cred_kinds[i], "!", config_dir, iterpool)); dir_path = svn_dirent_dirname(item_path, iterpool); err = svn_io_get_dirents3(&nodes, dir_path, TRUE, iterpool, iterpool); if (err) { if (!APR_STATUS_IS_ENOENT(err->apr_err) && !SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)) return svn_error_trace(err); svn_error_clear(err); continue; } itempool = svn_pool_create(iterpool); for (hi = apr_hash_first(iterpool, nodes); hi; hi = apr_hash_next(hi)) { svn_io_dirent2_t *dirent = svn__apr_hash_index_val(hi); svn_stream_t *stream; apr_hash_t *creds_hash; const svn_string_t *realm; svn_boolean_t delete_file = FALSE; if (finished) break; if (dirent->kind != svn_node_file) continue; svn_pool_clear(itempool); item_path = svn_dirent_join(dir_path, svn__apr_hash_index_key(hi), itempool); err = svn_stream_open_readonly(&stream, item_path, itempool, itempool); if (err) { /* Ignore this file. There are no credentials in it anyway */ svn_error_clear(err); continue; } creds_hash = apr_hash_make(itempool); err = svn_hash_read2(creds_hash, stream, SVN_HASH_TERMINATOR, itempool); err = svn_error_compose_create(err, svn_stream_close(stream)); if (err) { /* Ignore this file. There are no credentials in it anyway */ svn_error_clear(err); continue; } realm = svn_hash_gets(creds_hash, SVN_CONFIG_REALMSTRING_KEY); if (! realm) continue; /* Not an auth file */ err = walk_func(&delete_file, walk_baton, cred_kinds[i], realm->data, creds_hash, itempool); if (err && err->apr_err == SVN_ERR_CEASE_INVOCATION) { svn_error_clear(err); err = SVN_NO_ERROR; finished = TRUE; } SVN_ERR(err); if (delete_file) { /* Delete the file on disk */ SVN_ERR(svn_io_remove_file2(item_path, TRUE, itempool)); } } } svn_pool_destroy(iterpool); return SVN_NO_ERROR; }
/* Given a list of committables described by their common base abspath BASE_ABSPATH and a list of relative dirents TARGET_RELPATHS determine which absolute paths must be locked to commit all these targets and return this as a const char * array in LOCK_TARGETS Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporary storage */ static svn_error_t * determine_lock_targets(apr_array_header_t **lock_targets, svn_wc_context_t *wc_ctx, const char *base_abspath, const apr_array_header_t *target_relpaths, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { apr_pool_t *iterpool = svn_pool_create(scratch_pool); apr_hash_t *wc_items; /* const char *wcroot -> apr_array_header_t */ apr_hash_index_t *hi; int i; wc_items = apr_hash_make(scratch_pool); /* Create an array of targets for each working copy used */ for (i = 0; i < target_relpaths->nelts; i++) { const char *target_abspath; const char *wcroot_abspath; apr_array_header_t *wc_targets; svn_error_t *err; const char *target_relpath = APR_ARRAY_IDX(target_relpaths, i, const char *); svn_pool_clear(iterpool); target_abspath = svn_dirent_join(base_abspath, target_relpath, scratch_pool); err = svn_wc__get_wcroot(&wcroot_abspath, wc_ctx, target_abspath, iterpool, iterpool); if (err) { if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) { svn_error_clear(err); continue; } return svn_error_trace(err); } wc_targets = svn_hash_gets(wc_items, wcroot_abspath); if (! wc_targets) { wc_targets = apr_array_make(scratch_pool, 4, sizeof(const char *)); svn_hash_sets(wc_items, apr_pstrdup(scratch_pool, wcroot_abspath), wc_targets); } APR_ARRAY_PUSH(wc_targets, const char *) = target_abspath; } *lock_targets = apr_array_make(result_pool, apr_hash_count(wc_items), sizeof(const char *)); /* For each working copy determine where to lock */ for (hi = apr_hash_first(scratch_pool, wc_items); hi; hi = apr_hash_next(hi)) { const char *common; const char *wcroot_abspath = apr_hash_this_key(hi); apr_array_header_t *wc_targets = apr_hash_this_val(hi); svn_pool_clear(iterpool); if (wc_targets->nelts == 1) { const char *target_abspath; target_abspath = APR_ARRAY_IDX(wc_targets, 0, const char *); if (! strcmp(wcroot_abspath, target_abspath)) { APR_ARRAY_PUSH(*lock_targets, const char *) = apr_pstrdup(result_pool, target_abspath); } else { /* Lock the parent to allow deleting the target */ APR_ARRAY_PUSH(*lock_targets, const char *) = svn_dirent_dirname(target_abspath, result_pool); } }