/* Open a file somewhere in the adm area for directory PATH. * First, add the adm subdir as the next component of PATH, then add * each of the varargs (they are char *'s), then add EXTENSION if it * is non-null, then open the resulting file as *STREAM. * * If FLAGS indicates writing, open the file in the adm tmp area. * This means the file will probably need to be renamed from there, * either by passing the sync flag to close_adm_file() later, or with * an explicit call to sync_adm_file(). */ static svn_error_t * open_adm_file(svn_stream_t **stream, const char **selected_path, const char *path, const char *extension, svn_boolean_t for_writing, apr_pool_t *result_pool, apr_pool_t *scratch_pool, ...) { svn_error_t *err; va_list ap; /* If we're writing, always do it to a tmp file. */ if (for_writing) { /* Extend with tmp name. */ va_start(ap, scratch_pool); path = v_extend_with_adm_name(path, extension, TRUE, result_pool, ap); va_end(ap); err = svn_stream_open_writable(stream, path, result_pool, scratch_pool); } else { /* Extend with regular adm name. */ va_start(ap, scratch_pool); path = v_extend_with_adm_name(path, extension, FALSE, result_pool, ap); va_end(ap); err = svn_stream_open_readonly(stream, path, result_pool, scratch_pool); } if (selected_path) *selected_path = path; /* note: built in result_pool */ if (for_writing && err && APR_STATUS_IS_EEXIST(err->apr_err)) { /* Exclusive open failed, delete and retry */ svn_error_clear(err); SVN_ERR(svn_io_remove_file(path, scratch_pool)); err = svn_stream_open_writable(stream, path, result_pool, scratch_pool); } /* Examine the error from the first and/or second attempt at opening. */ if (for_writing && err && APR_STATUS_IS_ENOENT(err->apr_err)) { /* If we receive a failure to open a file in our temporary directory, * it may be because our temporary directories aren't created. * Older SVN clients did not create these directories. * 'svn cleanup' will fix this problem. */ err = svn_error_quick_wrap(err, _("Your .svn/tmp directory may be missing or " "corrupt; run 'svn cleanup' and try again")); } return err; }
static svn_error_t * file_textdelta(void *file_baton, const char *base_checksum, apr_pool_t *result_pool, svn_txdelta_window_handler_t *handler, void **handler_baton) { struct file_baton_t *fb = file_baton; svn_stream_t *target; SVN_ERR_ASSERT(! fb->writing); SVN_ERR(svn_stream_open_writable(&target, fb->local_abspath, fb->pool, fb->pool)); fb->writing = TRUE; svn_txdelta_apply(svn_stream_empty(fb->pool) /* source */, target, fb->digest, fb->local_abspath, fb->pool, /* Provide the handler directly */ handler, handler_baton); return SVN_NO_ERROR; }
svn_error_t * svn_client__copy_foreign(const char *url, const char *dst_abspath, svn_opt_revision_t *peg_revision, svn_opt_revision_t *revision, svn_depth_t depth, svn_boolean_t make_parents, svn_boolean_t already_locked, svn_client_ctx_t *ctx, apr_pool_t *scratch_pool) { svn_ra_session_t *ra_session; svn_client__pathrev_t *loc; svn_node_kind_t kind; svn_node_kind_t wc_kind; const char *dir_abspath; SVN_ERR_ASSERT(svn_path_is_url(url)); SVN_ERR_ASSERT(svn_dirent_is_absolute(dst_abspath)); /* Do we need to validate/update revisions? */ SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc, url, NULL, peg_revision, revision, ctx, scratch_pool)); SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, scratch_pool)); if (kind != svn_node_file && kind != svn_node_dir) return svn_error_createf( SVN_ERR_ILLEGAL_TARGET, NULL, _("'%s' is not a valid location inside a repository"), url); SVN_ERR(svn_wc_read_kind2(&wc_kind, ctx->wc_ctx, dst_abspath, FALSE, TRUE, scratch_pool)); if (wc_kind != svn_node_none) { return svn_error_createf( SVN_ERR_ENTRY_EXISTS, NULL, _("'%s' is already under version control"), svn_dirent_local_style(dst_abspath, scratch_pool)); } dir_abspath = svn_dirent_dirname(dst_abspath, scratch_pool); SVN_ERR(svn_wc_read_kind2(&wc_kind, ctx->wc_ctx, dir_abspath, FALSE, FALSE, scratch_pool)); if (wc_kind == svn_node_none) { if (make_parents) SVN_ERR(svn_client__make_local_parents(dir_abspath, make_parents, ctx, scratch_pool)); SVN_ERR(svn_wc_read_kind2(&wc_kind, ctx->wc_ctx, dir_abspath, FALSE, FALSE, scratch_pool)); } if (wc_kind != svn_node_dir) return svn_error_createf( SVN_ERR_ENTRY_NOT_FOUND, NULL, _("Can't add '%s', because no parent directory is found"), svn_dirent_local_style(dst_abspath, scratch_pool)); if (kind == svn_node_file) { svn_stream_t *target; apr_hash_t *props; apr_hash_index_t *hi; SVN_ERR(svn_stream_open_writable(&target, dst_abspath, scratch_pool, scratch_pool)); SVN_ERR(svn_ra_get_file(ra_session, "", loc->rev, target, NULL, &props, scratch_pool)); if (props != NULL) for (hi = apr_hash_first(scratch_pool, props); hi; hi = apr_hash_next(hi)) { const char *name = apr_hash_this_key(hi); if (svn_property_kind2(name) != svn_prop_regular_kind || ! strcmp(name, SVN_PROP_MERGEINFO)) { /* We can't handle DAV, ENTRY and merge specific props here */ svn_hash_sets(props, name, NULL); } } if (!already_locked) SVN_WC__CALL_WITH_WRITE_LOCK( svn_wc_add_from_disk3(ctx->wc_ctx, dst_abspath, props, TRUE /* skip checks */, ctx->notify_func2, ctx->notify_baton2, scratch_pool), ctx->wc_ctx, dir_abspath, FALSE, scratch_pool); else SVN_ERR(svn_wc_add_from_disk3(ctx->wc_ctx, dst_abspath, props, TRUE /* skip checks */, ctx->notify_func2, ctx->notify_baton2, scratch_pool)); } else { if (!already_locked) SVN_WC__CALL_WITH_WRITE_LOCK( copy_foreign_dir(ra_session, loc, ctx->wc_ctx, dst_abspath, depth, ctx->notify_func2, ctx->notify_baton2, ctx->cancel_func, ctx->cancel_baton, scratch_pool), ctx->wc_ctx, dir_abspath, FALSE, scratch_pool); else SVN_ERR(copy_foreign_dir(ra_session, loc, ctx->wc_ctx, dst_abspath, depth, ctx->notify_func2, ctx->notify_baton2, ctx->cancel_func, ctx->cancel_baton, scratch_pool)); } return SVN_NO_ERROR; }