svn_error_t * svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets) { svn_error_t *err; err = svn_client__assert_homogeneous_target_type(targets); if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err, NULL); return err; }
/* Set *COMMON_PARENT_URL to the nearest common parent URL of all TARGETS. * If TARGETS are local paths, then the entry for each path is examined * and *COMMON_PARENT is set to the common parent URL for all the * targets (as opposed to the common local path). * * If there is no common parent, either because the targets are a * mixture of URLs and local paths, or because they simply do not * share a common parent, then return SVN_ERR_UNSUPPORTED_FEATURE. * * DO_LOCK is TRUE for locking TARGETS, and FALSE for unlocking them. * FORCE is TRUE for breaking or stealing locks, and FALSE otherwise. * * Each key stored in *REL_TARGETS_P is a path relative to * *COMMON_PARENT. If TARGETS are local paths, then: if DO_LOCK is * true, the value is a pointer to the corresponding base_revision * (allocated in POOL) for the path, else the value is the lock token * (or "" if no token found in the wc). * * If TARGETS is an array of urls, REL_FS_PATHS_P is set to NULL. * Otherwise each key in REL_FS_PATHS_P is an repository path (relative to * COMMON_PARENT) mapped to the target path for TARGET (relative to * the common parent WC path). working copy targets that they "belong" to. * * If *COMMON_PARENT is a URL, then the values are a pointer to * SVN_INVALID_REVNUM (allocated in pool) if DO_LOCK, else "". * * TARGETS may not be empty. */ static svn_error_t * organize_lock_targets(const char **common_parent_url, const char **base_dir, apr_hash_t **rel_targets_p, apr_hash_t **rel_fs_paths_p, const apr_array_header_t *targets, svn_boolean_t do_lock, svn_boolean_t force, svn_client_ctx_t *ctx, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { const char *common_url = NULL; const char *common_dirent = NULL; apr_hash_t *rel_targets_ret = apr_hash_make(result_pool); apr_hash_t *rel_fs_paths = NULL; apr_array_header_t *rel_targets; svn_boolean_t url_mode; int i; SVN_ERR_ASSERT(targets->nelts); SVN_ERR(svn_client__assert_homogeneous_target_type(targets)); url_mode = svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *)); if (url_mode) { svn_revnum_t *invalid_revnum = apr_palloc(result_pool, sizeof(*invalid_revnum)); *invalid_revnum = SVN_INVALID_REVNUM; /* Get the common parent URL and a bunch of relpaths, one per target. */ SVN_ERR(condense_targets(&common_url, &rel_targets, targets, TRUE, TRUE, result_pool, scratch_pool)); if (! (common_url && *common_url)) return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL, _("No common parent found, unable to operate " "on disjoint arguments")); /* Create mapping of the target relpaths to either SVN_INVALID_REVNUM (if our caller is locking) or to an empty lock token string (if the caller is unlocking). */ for (i = 0; i < rel_targets->nelts; i++) { apr_hash_set(rel_targets_ret, APR_ARRAY_IDX(rel_targets, i, const char *), APR_HASH_KEY_STRING, do_lock ? (const void *)invalid_revnum : (const void *)""); } } else {
svn_error_t * svn_cl__assert_homogeneous_target_type(const apr_array_header_t *targets) { svn_error_t *err; err = svn_client__assert_homogeneous_target_type(targets); if (err && err->apr_err == SVN_ERR_ILLEGAL_TARGET) return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err, _("Cannot mix repository and working copy " "targets")); return err; }
svn_error_t * svn_client_propset_local(const char *propname, const svn_string_t *propval, const apr_array_header_t *targets, svn_depth_t depth, svn_boolean_t skip_checks, const apr_array_header_t *changelists, svn_client_ctx_t *ctx, apr_pool_t *scratch_pool) { apr_pool_t *iterpool = svn_pool_create(scratch_pool); svn_boolean_t targets_are_urls; int i; if (targets->nelts == 0) return SVN_NO_ERROR; /* Check for homogeneity among our targets. */ targets_are_urls = svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *)); SVN_ERR(svn_client__assert_homogeneous_target_type(targets)); if (targets_are_urls) return svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, _("Targets must be working copy paths")); SVN_ERR(check_prop_name(propname, propval)); for (i = 0; i < targets->nelts; i++) { svn_node_kind_t kind; const char *target_abspath; svn_error_t *err; struct set_props_baton baton; const char *target = APR_ARRAY_IDX(targets, i, const char *); svn_pool_clear(iterpool); /* Check for cancellation */ if (ctx->cancel_func) SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, iterpool)); err = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath, FALSE, iterpool); if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) || (!err && (kind == svn_node_unknown || kind == svn_node_none))) { if (ctx->notify_func2) { svn_wc_notify_t *notify = svn_wc_create_notify( target_abspath, svn_wc_notify_path_nonexistent, iterpool); ctx->notify_func2(ctx->notify_baton2, notify, iterpool); } svn_error_clear(err); } else SVN_ERR(err); baton.ctx = ctx; baton.local_abspath = target_abspath; baton.depth = depth; baton.kind = kind; baton.propname = propname; baton.propval = propval; baton.skip_checks = skip_checks; baton.changelist_filter = changelists; SVN_ERR(svn_wc__call_with_write_lock(set_props_cb, &baton, ctx->wc_ctx, target_abspath, FALSE, iterpool, iterpool)); } svn_pool_destroy(iterpool); return SVN_NO_ERROR; }