1289177Speter/* 2289177Speter * list-cmd.c -- list a URL 3289177Speter * 4289177Speter * ==================================================================== 5289177Speter * Licensed to the Apache Software Foundation (ASF) under one 6289177Speter * or more contributor license agreements. See the NOTICE file 7289177Speter * distributed with this work for additional information 8289177Speter * regarding copyright ownership. The ASF licenses this file 9289177Speter * to you under the Apache License, Version 2.0 (the 10289177Speter * "License"); you may not use this file except in compliance 11289177Speter * with the License. You may obtain a copy of the License at 12289177Speter * 13289177Speter * http://www.apache.org/licenses/LICENSE-2.0 14289177Speter * 15289177Speter * Unless required by applicable law or agreed to in writing, 16289177Speter * software distributed under the License is distributed on an 17289177Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18289177Speter * KIND, either express or implied. See the License for the 19289177Speter * specific language governing permissions and limitations 20289177Speter * under the License. 21289177Speter * ==================================================================== 22289177Speter */ 23289177Speter 24289177Speter#include "svn_cmdline.h" 25289177Speter#include "svn_client.h" 26289177Speter#include "svn_error.h" 27289177Speter#include "svn_pools.h" 28289177Speter#include "svn_time.h" 29289177Speter#include "svn_xml.h" 30289177Speter#include "svn_dirent_uri.h" 31289177Speter#include "svn_path.h" 32289177Speter#include "svn_utf.h" 33289177Speter#include "svn_opt.h" 34289177Speter 35289177Speter#include "cl.h" 36289177Speter 37289177Speter#include "svn_private_config.h" 38289177Speter#include "private/svn_string_private.h" 39289177Speter 40289177Speter 41289177Speter 42289177Speter/* Baton used when printing directory entries. */ 43289177Speterstruct print_baton { 44289177Speter svn_boolean_t verbose; 45289177Speter apr_int64_t directories; 46289177Speter apr_int64_t files; 47289177Speter apr_int64_t locks; 48289177Speter svn_client_ctx_t *ctx; 49289177Speter}; 50289177Speter 51289177Speter/* This implements the svn_client_list_func2_t API, printing a single 52289177Speter directory entry in text format. */ 53289177Speterstatic svn_error_t * 54289177Speterprint_dirent(void *baton, 55289177Speter const char *path, 56289177Speter const svn_dirent_t *dirent, 57289177Speter const svn_lock_t *lock, 58289177Speter const char *abs_path, 59289177Speter const char *external_parent_url, 60289177Speter const char *external_target, 61289177Speter apr_pool_t *pool) 62289177Speter{ 63289177Speter struct print_baton *pb = baton; 64289177Speter 65289177Speter if (pb->ctx->cancel_func) 66289177Speter SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton)); 67289177Speter 68289177Speter if (dirent->kind == svn_node_dir) 69289177Speter pb->directories++; 70289177Speter if (dirent->kind == svn_node_file) 71289177Speter pb->files++; 72289177Speter if (lock) 73289177Speter pb->locks++; 74289177Speter 75289177Speter return SVN_NO_ERROR; 76289177Speter} 77289177Speter 78289177Speter 79289177Speter/* This implements the `svn_opt_subcommand_t' interface. */ 80289177Spetersvn_error_t * 81289177Spetersvn_cl__null_list(apr_getopt_t *os, 82289177Speter void *baton, 83289177Speter apr_pool_t *pool) 84289177Speter{ 85289177Speter svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; 86289177Speter svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; 87289177Speter apr_array_header_t *targets; 88289177Speter int i; 89289177Speter apr_pool_t *subpool = svn_pool_create(pool); 90289177Speter apr_uint32_t dirent_fields; 91289177Speter struct print_baton pb = { FALSE }; 92289177Speter svn_boolean_t seen_nonexistent_target = FALSE; 93289177Speter svn_error_t *err; 94289177Speter 95289177Speter SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os, 96289177Speter opt_state->targets, 97289177Speter ctx, FALSE, pool)); 98289177Speter 99289177Speter /* Add "." if user passed 0 arguments */ 100289177Speter svn_opt_push_implicit_dot_target(targets, pool); 101289177Speter 102289177Speter if (opt_state->verbose) 103289177Speter dirent_fields = SVN_DIRENT_ALL; 104289177Speter else 105289177Speter dirent_fields = SVN_DIRENT_KIND; /* the only thing we actually need... */ 106289177Speter 107289177Speter pb.ctx = ctx; 108289177Speter pb.verbose = opt_state->verbose; 109289177Speter 110289177Speter if (opt_state->depth == svn_depth_unknown) 111289177Speter opt_state->depth = svn_depth_immediates; 112289177Speter 113289177Speter /* For each target, try to list it. */ 114289177Speter for (i = 0; i < targets->nelts; i++) 115289177Speter { 116289177Speter const char *target = APR_ARRAY_IDX(targets, i, const char *); 117289177Speter const char *truepath; 118289177Speter svn_opt_revision_t peg_revision; 119289177Speter 120289177Speter svn_pool_clear(subpool); 121289177Speter 122289177Speter SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton)); 123289177Speter 124289177Speter /* Get peg revisions. */ 125289177Speter SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target, 126289177Speter subpool)); 127289177Speter 128289177Speter err = svn_client_list3(truepath, &peg_revision, 129289177Speter &(opt_state->start_revision), 130289177Speter opt_state->depth, 131289177Speter dirent_fields, 132289177Speter opt_state->verbose, 133289177Speter FALSE, /* include externals */ 134289177Speter print_dirent, 135289177Speter &pb, ctx, subpool); 136289177Speter 137289177Speter if (err) 138289177Speter { 139289177Speter /* If one of the targets is a non-existent URL or wc-entry, 140289177Speter don't bail out. Just warn and move on to the next target. */ 141289177Speter if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND || 142289177Speter err->apr_err == SVN_ERR_FS_NOT_FOUND) 143289177Speter svn_handle_warning2(stderr, err, "svnbench: "); 144289177Speter else 145289177Speter return svn_error_trace(err); 146289177Speter 147289177Speter svn_error_clear(err); 148289177Speter err = NULL; 149289177Speter seen_nonexistent_target = TRUE; 150289177Speter } 151289177Speter else if (!opt_state->quiet) 152289177Speter SVN_ERR(svn_cmdline_printf(pool, 153289177Speter _("%15s directories\n" 154289177Speter "%15s files\n" 155289177Speter "%15s locks\n"), 156289177Speter svn__ui64toa_sep(pb.directories, ',', pool), 157289177Speter svn__ui64toa_sep(pb.files, ',', pool), 158289177Speter svn__ui64toa_sep(pb.locks, ',', pool))); 159289177Speter } 160289177Speter 161289177Speter svn_pool_destroy(subpool); 162289177Speter 163289177Speter if (seen_nonexistent_target) 164289177Speter return svn_error_create( 165289177Speter SVN_ERR_ILLEGAL_TARGET, NULL, 166289177Speter _("Could not list all targets because some targets don't exist")); 167289177Speter else 168289177Speter return SVN_NO_ERROR; 169289177Speter} 170