2 * list-cmd.c -- list a URL
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
24 #include "svn_cmdline.h"
25 #include "svn_client.h"
26 #include "svn_error.h"
27 #include "svn_pools.h"
30 #include "svn_dirent_uri.h"
37 #include "svn_private_config.h"
38 #include "private/svn_string_private.h"
42 /* Baton used when printing directory entries. */
44 svn_boolean_t verbose;
45 apr_int64_t directories;
48 svn_client_ctx_t *ctx;
51 /* Field flags required for this function */
52 static const apr_uint32_t print_dirent_fields = SVN_DIRENT_KIND;
53 static const apr_uint32_t print_dirent_fields_verbose = (
54 SVN_DIRENT_KIND | SVN_DIRENT_SIZE | SVN_DIRENT_TIME |
55 SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR);
57 /* This implements the svn_client_list_func2_t API, printing a single
58 directory entry in text format. */
60 print_dirent(void *baton,
62 const svn_dirent_t *dirent,
63 const svn_lock_t *lock,
65 const char *external_parent_url,
66 const char *external_target,
69 struct print_baton *pb = baton;
71 if (pb->ctx->cancel_func)
72 SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton));
74 if (dirent->kind == svn_node_dir)
76 if (dirent->kind == svn_node_file)
85 /* This implements the `svn_opt_subcommand_t' interface. */
87 svn_cl__null_list(apr_getopt_t *os,
91 svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
92 svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
93 apr_array_header_t *targets;
95 apr_pool_t *subpool = svn_pool_create(pool);
96 apr_uint32_t dirent_fields;
97 struct print_baton pb = { FALSE };
98 svn_boolean_t seen_nonexistent_target = FALSE;
101 SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
105 /* Add "." if user passed 0 arguments */
106 svn_opt_push_implicit_dot_target(targets, pool);
108 if (opt_state->verbose)
109 dirent_fields = print_dirent_fields_verbose;
111 dirent_fields = print_dirent_fields;
114 pb.verbose = opt_state->verbose;
116 if (opt_state->depth == svn_depth_unknown)
117 opt_state->depth = svn_depth_immediates;
119 /* For each target, try to list it. */
120 for (i = 0; i < targets->nelts; i++)
122 const char *target = APR_ARRAY_IDX(targets, i, const char *);
123 const char *truepath;
124 svn_opt_revision_t peg_revision;
125 apr_array_header_t *patterns = NULL;
128 svn_pool_clear(subpool);
130 SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
132 /* Get peg revisions. */
133 SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
136 if (opt_state->search_patterns)
138 patterns = apr_array_make(subpool, 4, sizeof(const char *));
139 for (k = 0; k < opt_state->search_patterns->nelts; ++k)
141 apr_array_header_t *pattern_group
142 = APR_ARRAY_IDX(opt_state->search_patterns, k,
143 apr_array_header_t *);
145 /* Should never fail but ... */
146 if (pattern_group->nelts != 1)
147 return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
148 _("'search-and' option is not supported"));
150 APR_ARRAY_PUSH(patterns, const char *)
151 = APR_ARRAY_IDX(pattern_group, 0, const char *);
155 err = svn_client_list4(truepath, &peg_revision,
156 &(opt_state->start_revision), patterns,
160 FALSE, /* include externals */
166 /* If one of the targets is a non-existent URL or wc-entry,
167 don't bail out. Just warn and move on to the next target. */
168 if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
169 err->apr_err == SVN_ERR_FS_NOT_FOUND)
170 svn_handle_warning2(stderr, err, "svnbench: ");
172 return svn_error_trace(err);
174 svn_error_clear(err);
176 seen_nonexistent_target = TRUE;
178 else if (!opt_state->quiet)
179 SVN_ERR(svn_cmdline_printf(pool,
180 _("%15s directories\n"
183 svn__ui64toa_sep(pb.directories, ',', pool),
184 svn__ui64toa_sep(pb.files, ',', pool),
185 svn__ui64toa_sep(pb.locks, ',', pool)));
188 svn_pool_destroy(subpool);
190 if (seen_nonexistent_target)
191 return svn_error_create(
192 SVN_ERR_ILLEGAL_TARGET, NULL,
193 _("Could not list all targets because some targets don't exist"));