static svn_error_t * add_open_helper(const char *path, char action, svn_node_kind_t kind, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_rev, apr_pool_t *pool, void **child_baton) { struct node_baton *pb = parent_baton; struct edit_baton *eb = pb->edit_baton; struct node_baton *nb = apr_pcalloc(pool, sizeof(*nb)); assert(parent_baton && path); nb->edit_baton = eb; nb->parent_baton = pb; /* Create and populate the node. */ nb->node = create_child_node(pb->node, svn_path_basename(path, pool), eb->node_pool); nb->node->kind = kind; nb->node->action = action; nb->node->copyfrom_rev = copyfrom_rev; nb->node->copyfrom_path = copyfrom_path ? apr_pstrdup(eb->node_pool, copyfrom_path) : NULL; *child_baton = nb; return SVN_NO_ERROR; }
static svn_error_t * list_func (void *baton, const char *path, const svn_dirent_t *dirent, const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool) { lua_State *L = baton; if (strcmp (path, "") == 0) { if (dirent->kind == svn_node_file) { path = svn_path_basename (abs_path, pool); } else { return SVN_NO_ERROR; } } lua_pushfstring (L, "%s%s", path, dirent->kind == svn_node_dir ? "/" : ""); lua_newtable (L); if (dirent->kind == svn_node_file) lua_pushinteger (L, dirent->size); else lua_pushnil (L); lua_setfield (L, -2, "size"); if (dirent->last_author) lua_pushstring (L, dirent->last_author); else lua_pushnil (L); lua_setfield (L, -2, "author"); lua_pushinteger (L, dirent->created_rev); lua_setfield (L, -2, "revision"); lua_pushstring (L, svn_time_to_human_cstring (dirent->time, pool)); lua_setfield (L, -2, "date"); lua_settable (L, -3); return SVN_NO_ERROR; }
static svn_error_t * delete_entry(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *pool) { struct node_baton *d = parent_baton; struct edit_baton *eb = d->edit_baton; svn_repos_node_t *node; const char *name; const char *base_path; svn_revnum_t base_rev; svn_fs_root_t *base_root; svn_node_kind_t kind; /* Get (or create) the change node and update it. */ name = svn_path_basename(path, pool); node = find_child_by_name(d->node, name); if (! node) node = create_child_node(d->node, name, eb->node_pool); node->action = 'D'; /* We need to look up this node's parents to see what its original path in the filesystem was. Why? Because if this deletion occurred underneath a copied path, the thing that was deleted probably lived at a different location (relative to the copy source). */ find_real_base_location(&base_path, &base_rev, node, pool); if (! SVN_IS_VALID_REVNUM(base_rev)) { /* No interesting base revision? We'll just look for the path in our base root. */ base_root = eb->base_root; } else { /* Oh. Perhaps some copy goodness happened somewhere? */ SVN_ERR(svn_fs_revision_root(&base_root, eb->fs, base_rev, pool)); } /* Now figure out if this thing was a file or a dir. */ SVN_ERR(svn_fs_check_path(&kind, base_root, base_path, pool)); if (kind == svn_node_none) return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL, _("'%s' not found in filesystem"), path); node->kind = kind; return SVN_NO_ERROR; }
static svn_error_t * list_func (void *baton, const char *path, const svn_dirent_t *dirent, const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool) { lua_State *L = baton; if (strcmp (path, "") == 0) { if (dirent->kind == svn_node_file) { path = svn_path_basename (abs_path, pool); } else { return SVN_NO_ERROR; } } lua_pushfstring (L, "%s%s", path, dirent->kind == svn_node_dir ? "/" : ""); lua_pushinteger (L, dirent->created_rev); lua_settable (L, -3); return SVN_NO_ERROR; }
svn_error_t * svn_client__get_auto_props(apr_hash_t **properties, const char **mimetype, const char *path, svn_client_ctx_t *ctx, apr_pool_t *pool) { svn_config_t *cfg; svn_boolean_t use_autoprops; auto_props_baton_t autoprops; /* initialisation */ autoprops.properties = apr_hash_make(pool); autoprops.filename = svn_path_basename(path, pool); autoprops.pool = pool; autoprops.mimetype = NULL; autoprops.have_executable = FALSE; *properties = autoprops.properties; cfg = ctx->config ? apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG, APR_HASH_KEY_STRING) : NULL; /* check that auto props is enabled */ SVN_ERR(svn_config_get_bool(cfg, &use_autoprops, SVN_CONFIG_SECTION_MISCELLANY, SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE)); /* search for auto props */ if (use_autoprops) svn_config_enumerate2(cfg, SVN_CONFIG_SECTION_AUTO_PROPS, auto_props_enumerator, &autoprops, pool); /* if mimetype has not been set check the file */ if (! autoprops.mimetype) { SVN_ERR(svn_io_detect_mimetype2(&autoprops.mimetype, path, ctx->mimetypes_map, pool)); if (autoprops.mimetype) apr_hash_set(autoprops.properties, SVN_PROP_MIME_TYPE, strlen(SVN_PROP_MIME_TYPE), svn_string_create(autoprops.mimetype, pool)); } /* Don't automatically set the svn:executable property on added items * on OS400. While OS400 supports the executable permission its use is * inconsistent at best. */ #ifndef AS400 /* if executable has not been set check the file */ if (! autoprops.have_executable) { svn_boolean_t executable = FALSE; SVN_ERR(svn_io_is_file_executable(&executable, path, pool)); if (executable) apr_hash_set(autoprops.properties, SVN_PROP_EXECUTABLE, strlen(SVN_PROP_EXECUTABLE), svn_string_create("", pool)); } #endif *mimetype = autoprops.mimetype; return SVN_NO_ERROR; }
/* Note: This is substantially copied into svn_client_args_to_target_array() in * order to move to libsvn_client while maintaining backward compatibility. */ svn_error_t * svn_opt__args_to_target_array(apr_array_header_t **targets_p, apr_getopt_t *os, apr_array_header_t *known_targets, apr_pool_t *pool) { int i; svn_error_t *err = SVN_NO_ERROR; apr_array_header_t *input_targets = apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *)); apr_array_header_t *output_targets = apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *)); /* Step 1: create a master array of targets that are in UTF-8 encoding, and come from concatenating the targets left by apr_getopt, plus any extra targets (e.g., from the --targets switch.) */ for (; os->ind < os->argc; os->ind++) { /* The apr_getopt targets are still in native encoding. */ const char *raw_target = os->argv[os->ind]; SVN_ERR(svn_utf_cstring_to_utf8 ((const char **) apr_array_push(input_targets), raw_target, pool)); } if (known_targets) { for (i = 0; i < known_targets->nelts; i++) { /* The --targets array have already been converted to UTF-8, because we needed to split up the list with svn_cstring_split. */ const char *utf8_target = APR_ARRAY_IDX(known_targets, i, const char *); APR_ARRAY_PUSH(input_targets, const char *) = utf8_target; } } /* Step 2: process each target. */ for (i = 0; i < input_targets->nelts; i++) { const char *utf8_target = APR_ARRAY_IDX(input_targets, i, const char *); const char *true_target; const char *target; /* after all processing is finished */ const char *peg_rev; /* * This is needed so that the target can be properly canonicalized, * otherwise the canonicalization does not treat a ".@BASE" as a "." * with a BASE peg revision, and it is not canonicalized to "@BASE". * If any peg revision exists, it is appended to the final * canonicalized path or URL. Do not use svn_opt_parse_path() * because the resulting peg revision is a structure that would have * to be converted back into a string. Converting from a string date * to the apr_time_t field in the svn_opt_revision_value_t and back to * a string would not necessarily preserve the exact bytes of the * input date, so its easier just to keep it in string form. */ SVN_ERR(svn_opt__split_arg_at_peg_revision(&true_target, &peg_rev, utf8_target, pool)); /* URLs and wc-paths get treated differently. */ if (svn_path_is_url(true_target)) { SVN_ERR(svn_opt__arg_canonicalize_url(&true_target, true_target, pool)); } else /* not a url, so treat as a path */ { const char *base_name; SVN_ERR(svn_opt__arg_canonicalize_path(&true_target, true_target, pool)); /* If the target has the same name as a Subversion working copy administrative dir, skip it. */ base_name = svn_path_basename(true_target, pool); /* FIXME: The canonical list of administrative directory names is maintained in libsvn_wc/adm_files.c:svn_wc_set_adm_dir(). That list can't be used here, because that use would create a circular dependency between libsvn_wc and libsvn_subr. Make sure changes to the lists are always synchronized! */ if (0 == strcmp(base_name, ".svn") || 0 == strcmp(base_name, "_svn")) { err = svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED, err, _("'%s' ends in a reserved name"), utf8_target); continue; } } target = apr_pstrcat(pool, true_target, peg_rev, NULL); APR_ARRAY_PUSH(output_targets, const char *) = target; } /* kff todo: need to remove redundancies from targets before passing it to the cmd_func. */ *targets_p = output_targets; return err; }
/* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * svn_cl__export(apr_getopt_t *os, void *baton, apr_pool_t *pool) { svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; const char *from, *to; apr_array_header_t *targets; svn_error_t *err; svn_opt_revision_t peg_revision; const char *truefrom; SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, opt_state->targets, ctx, pool)); /* We want exactly 1 or 2 targets for this subcommand. */ if (targets->nelts < 1) return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL); if (targets->nelts > 2) return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL); /* The first target is the `from' path. */ from = APR_ARRAY_IDX(targets, 0, const char *); /* Get the peg revision if present. */ SVN_ERR(svn_opt_parse_path(&peg_revision, &truefrom, from, pool)); /* If only one target was given, split off the basename to use as the `to' path. Else, a `to' path was supplied. */ if (targets->nelts == 1) to = svn_path_uri_decode(svn_path_basename(truefrom, pool), pool); else to = APR_ARRAY_IDX(targets, 1, const char *); SVN_ERR(svn_opt__split_arg_at_peg_revision(&to, NULL, to, pool)); if (! opt_state->quiet) svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2, FALSE, TRUE, FALSE, pool); if (opt_state->depth == svn_depth_unknown) opt_state->depth = svn_depth_infinity; /* Decode the partially encoded URL and escape all URL unsafe characters. */ if (svn_path_is_url(truefrom)) truefrom = svn_path_uri_encode(svn_path_uri_decode(truefrom, pool), pool); /* Do the export. */ err = svn_client_export4(NULL, truefrom, to, &peg_revision, &(opt_state->start_revision), opt_state->force, opt_state->ignore_externals, opt_state->depth, opt_state->native_eol, ctx, pool); if (err && err->apr_err == SVN_ERR_WC_OBSTRUCTED_UPDATE && !opt_state->force) SVN_ERR_W(err, _("Destination directory exists; please remove " "the directory or use --force to overwrite")); return err; }
svn_error_t * svn_ra_neon__search_for_starting_props(svn_ra_neon__resource_t **rsrc, const char **missing_path, svn_ra_neon__session_t *sess, const char *url, apr_pool_t *pool) { svn_error_t *err = SVN_NO_ERROR; apr_size_t len; svn_stringbuf_t *path_s; ne_uri parsed_url; svn_stringbuf_t *lopped_path = svn_stringbuf_create(url, pool); /* initialize to make sure it'll fit without reallocating */ apr_pool_t *iterpool = svn_pool_create(pool); /* Split the url into its component pieces (scheme, host, path, etc). We want the path part. */ ne_uri_parse(url, &parsed_url); if (parsed_url.path == NULL) { ne_uri_free(&parsed_url); return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL, _("Neon was unable to parse URL '%s'"), url); } svn_stringbuf_setempty(lopped_path); path_s = svn_stringbuf_create(parsed_url.path, pool); ne_uri_free(&parsed_url); /* Try to get the starting_props from the public url. If the resource no longer exists in HEAD, we'll get a failure. That's fine: just keep removing components and trying to get the starting_props from parent directories. */ while (! svn_path_is_empty(path_s->data)) { svn_pool_clear(iterpool); err = svn_ra_neon__get_starting_props(rsrc, sess, path_s->data, NULL, iterpool); if (! err) break; /* found an existing parent! */ if (err->apr_err != SVN_ERR_FS_NOT_FOUND) return err; /* found a _real_ error */ /* else... lop off the basename and try again. */ svn_stringbuf_set(lopped_path, svn_path_join(svn_path_basename(path_s->data, iterpool), lopped_path->data, iterpool)); len = path_s->len; svn_path_remove_component(path_s); /* if we detect an infinite loop, get out. */ if (path_s->len == len) return svn_error_quick_wrap (err, _("The path was not part of a repository")); svn_error_clear(err); } /* error out if entire URL was bogus (not a single part of it exists in the repository!) */ if (svn_path_is_empty(path_s->data)) return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL, _("No part of path '%s' was found in " "repository HEAD"), parsed_url.path); /* Duplicate rsrc out of iterpool into pool */ { apr_hash_index_t *hi; svn_ra_neon__resource_t *tmp = apr_pcalloc(pool, sizeof(*tmp)); tmp->url = apr_pstrdup(pool, (*rsrc)->url); tmp->is_collection = (*rsrc)->is_collection; tmp->pool = pool; tmp->propset = apr_hash_make(pool); for (hi = apr_hash_first(iterpool, (*rsrc)->propset); hi; hi = apr_hash_next(hi)) { const void *key; void *val; apr_hash_this(hi, &key, NULL, &val); apr_hash_set(tmp->propset, apr_pstrdup(pool, key), APR_HASH_KEY_STRING, svn_string_dup(val, pool)); } *rsrc = tmp; } *missing_path = lopped_path->data; svn_pool_destroy(iterpool); return SVN_NO_ERROR; }
/* A callback of type svn_info_receiver_t. */ static svn_error_t * print_info(void *baton, const char *target, const svn_info_t *info, apr_pool_t *pool) { SVN_ERR(svn_cmdline_printf(pool, _("Path: %s\n"), svn_path_local_style(target, pool))); /* ### remove this someday: it's only here for cmdline output compatibility with svn 1.1 and older. */ if (info->kind != svn_node_dir) SVN_ERR(svn_cmdline_printf(pool, _("Name: %s\n"), svn_path_basename(target, pool))); if (info->URL) SVN_ERR(svn_cmdline_printf(pool, _("URL: %s\n"), info->URL)); if (info->repos_root_URL) SVN_ERR(svn_cmdline_printf(pool, _("Repository Root: %s\n"), info->repos_root_URL)); if (info->repos_UUID) SVN_ERR(svn_cmdline_printf(pool, _("Repository UUID: %s\n"), info->repos_UUID)); if (SVN_IS_VALID_REVNUM(info->rev)) SVN_ERR(svn_cmdline_printf(pool, _("Revision: %ld\n"), info->rev)); switch (info->kind) { case svn_node_file: SVN_ERR(svn_cmdline_printf(pool, _("Node Kind: file\n"))); break; case svn_node_dir: SVN_ERR(svn_cmdline_printf(pool, _("Node Kind: directory\n"))); break; case svn_node_none: SVN_ERR(svn_cmdline_printf(pool, _("Node Kind: none\n"))); break; case svn_node_unknown: default: SVN_ERR(svn_cmdline_printf(pool, _("Node Kind: unknown\n"))); break; } if (info->has_wc_info) { switch (info->schedule) { case svn_wc_schedule_normal: SVN_ERR(svn_cmdline_printf(pool, _("Schedule: normal\n"))); break; case svn_wc_schedule_add: SVN_ERR(svn_cmdline_printf(pool, _("Schedule: add\n"))); break; case svn_wc_schedule_delete: SVN_ERR(svn_cmdline_printf(pool, _("Schedule: delete\n"))); break; case svn_wc_schedule_replace: SVN_ERR(svn_cmdline_printf(pool, _("Schedule: replace\n"))); break; default: break; } switch (info->depth) { case svn_depth_unknown: /* Unknown depth is the norm for remote directories anyway (although infinity would be equally appropriate). Let's not bother to print it. */ break; case svn_depth_empty: SVN_ERR(svn_cmdline_printf(pool, _("Depth: empty\n"))); break; case svn_depth_files: SVN_ERR(svn_cmdline_printf(pool, _("Depth: files\n"))); break; case svn_depth_immediates: SVN_ERR(svn_cmdline_printf(pool, _("Depth: immediates\n"))); break; case svn_depth_infinity: /* Infinity is the default depth for working copy directories. Let's not print it, it's not special enough to be worth mentioning. */ break; default: /* Other depths should never happen here. */ SVN_ERR(svn_cmdline_printf(pool, _("Depth: INVALID\n"))); } if (info->copyfrom_url) SVN_ERR(svn_cmdline_printf(pool, _("Copied From URL: %s\n"), info->copyfrom_url)); if (SVN_IS_VALID_REVNUM(info->copyfrom_rev)) SVN_ERR(svn_cmdline_printf(pool, _("Copied From Rev: %ld\n"), info->copyfrom_rev)); } if (info->last_changed_author) SVN_ERR(svn_cmdline_printf(pool, _("Last Changed Author: %s\n"), info->last_changed_author)); if (SVN_IS_VALID_REVNUM(info->last_changed_rev)) SVN_ERR(svn_cmdline_printf(pool, _("Last Changed Rev: %ld\n"), info->last_changed_rev)); if (info->last_changed_date) SVN_ERR(svn_cl__info_print_time(info->last_changed_date, _("Last Changed Date"), pool)); if (info->has_wc_info) { if (info->text_time) SVN_ERR(svn_cl__info_print_time(info->text_time, _("Text Last Updated"), pool)); if (info->checksum) SVN_ERR(svn_cmdline_printf(pool, _("Checksum: %s\n"), info->checksum)); if (info->conflict_old) SVN_ERR(svn_cmdline_printf(pool, _("Conflict Previous Base File: %s\n"), svn_path_local_style(info->conflict_old, pool))); if (info->conflict_wrk) SVN_ERR(svn_cmdline_printf (pool, _("Conflict Previous Working File: %s\n"), svn_path_local_style(info->conflict_wrk, pool))); if (info->conflict_new) SVN_ERR(svn_cmdline_printf(pool, _("Conflict Current Base File: %s\n"), svn_path_local_style(info->conflict_new, pool))); if (info->prejfile) SVN_ERR(svn_cmdline_printf(pool, _("Conflict Properties File: %s\n"), svn_path_local_style(info->prejfile, pool))); } if (info->lock) { if (info->lock->token) SVN_ERR(svn_cmdline_printf(pool, _("Lock Token: %s\n"), info->lock->token)); if (info->lock->owner) SVN_ERR(svn_cmdline_printf(pool, _("Lock Owner: %s\n"), info->lock->owner)); if (info->lock->creation_date) SVN_ERR(svn_cl__info_print_time(info->lock->creation_date, _("Lock Created"), pool)); if (info->lock->expiration_date) SVN_ERR(svn_cl__info_print_time(info->lock->expiration_date, _("Lock Expires"), pool)); if (info->lock->comment) { int comment_lines; /* NOTE: The stdio will handle newline translation. */ comment_lines = svn_cstring_count_newlines(info->lock->comment) + 1; SVN_ERR(svn_cmdline_printf(pool, Q_("Lock Comment (%i line):\n%s\n", "Lock Comment (%i lines):\n%s\n", comment_lines), comment_lines, info->lock->comment)); } } if (info->changelist) SVN_ERR(svn_cmdline_printf(pool, _("Changelist: %s\n"), info->changelist)); if (info->tree_conflict) { const char *desc, *src_left_version, *src_right_version; SVN_ERR(svn_cl__get_human_readable_tree_conflict_description( &desc, info->tree_conflict, pool)); src_left_version = svn_cl__node_description(info->tree_conflict->src_left_version, pool); src_right_version = svn_cl__node_description(info->tree_conflict->src_right_version, pool); svn_cmdline_printf(pool, "%s: %s\n", _("Tree conflict"), desc); if (src_left_version) svn_cmdline_printf(pool, " %s: %s\n", _("Source left"), /* (1) */ src_left_version); /* (1): Sneaking in a space in "Source left" so that it is the * same length as "Source right" while it still starts in the same * column. That's just a tiny tweak in the English `svn'. */ if (src_right_version) svn_cmdline_printf(pool, " %s: %s\n", _("Source right"), src_right_version); } /* Print extra newline separator. */ return svn_cmdline_printf(pool, "\n"); }