]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/subversion/subversion/svn/proplist-cmd.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / subversion / subversion / svn / proplist-cmd.c
1 /*
2  * proplist-cmd.c -- List properties of files/dirs
3  *
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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
20  *    under the License.
21  * ====================================================================
22  */
23
24 /* ==================================================================== */
25
26
27 \f
28 /*** Includes. ***/
29
30 #include "svn_cmdline.h"
31 #include "svn_pools.h"
32 #include "svn_client.h"
33 #include "svn_error_codes.h"
34 #include "svn_error.h"
35 #include "svn_dirent_uri.h"
36 #include "svn_path.h"
37 #include "svn_xml.h"
38 #include "svn_props.h"
39 #include "cl.h"
40
41 #include "private/svn_cmdline_private.h"
42
43 #include "svn_private_config.h"
44
45 typedef struct proplist_baton_t
46 {
47   svn_cl__opt_state_t *opt_state;
48   svn_boolean_t is_url;
49 } proplist_baton_t;
50
51 \f
52 /*** Code. ***/
53
54 /* This implements the svn_proplist_receiver2_t interface, printing XML to
55    stdout. */
56 static svn_error_t *
57 proplist_receiver_xml(void *baton,
58                       const char *path,
59                       apr_hash_t *prop_hash,
60                       apr_array_header_t *inherited_props,
61                       apr_pool_t *pool)
62 {
63   svn_cl__opt_state_t *opt_state = ((proplist_baton_t *)baton)->opt_state;
64   svn_boolean_t is_url = ((proplist_baton_t *)baton)->is_url;
65   svn_stringbuf_t *sb;
66   const char *name_local;
67
68   if (inherited_props && inherited_props->nelts)
69     {
70       int i;
71       apr_pool_t *iterpool = svn_pool_create(pool);
72
73       for (i = 0; i < inherited_props->nelts; i++)
74         {
75           svn_prop_inherited_item_t *iprop =
76             APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);
77
78           sb = NULL;
79
80           if (svn_path_is_url(iprop->path_or_url))
81             name_local = iprop->path_or_url;
82           else
83             name_local = svn_dirent_local_style(iprop->path_or_url, iterpool);
84
85           svn_xml_make_open_tag(&sb, iterpool, svn_xml_normal, "target",
86                             "path", name_local, NULL);
87           SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, iprop->prop_hash,
88                                                    (! opt_state->verbose),
89                                                    TRUE, iterpool));
90           svn_xml_make_close_tag(&sb, iterpool, "target");
91           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
92         }
93       svn_pool_destroy(iterpool);
94     }
95
96   if (! is_url)
97     name_local = svn_dirent_local_style(path, pool);
98   else
99     name_local = path;
100
101   sb = NULL;
102
103
104   if (prop_hash)
105     {
106       /* "<target ...>" */
107         svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
108                               "path", name_local, NULL);
109
110         SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, prop_hash,
111                                                  (! opt_state->verbose),
112                                                  FALSE, pool));
113
114         /* "</target>" */
115         svn_xml_make_close_tag(&sb, pool, "target");
116         SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
117     }
118
119   return SVN_NO_ERROR;
120 }
121
122
123 /* This implements the svn_proplist_receiver2_t interface. */
124 static svn_error_t *
125 proplist_receiver(void *baton,
126                   const char *path,
127                   apr_hash_t *prop_hash,
128                   apr_array_header_t *inherited_props,
129                   apr_pool_t *pool)
130 {
131   svn_cl__opt_state_t *opt_state = ((proplist_baton_t *)baton)->opt_state;
132   svn_boolean_t is_url = ((proplist_baton_t *)baton)->is_url;
133   const char *name_local;
134
135   if (! is_url)
136     name_local = svn_dirent_local_style(path, pool);
137   else
138     name_local = path;
139
140   if (inherited_props)
141     {
142       int i;
143       apr_pool_t *iterpool = svn_pool_create(pool);
144
145       for (i = 0; i < inherited_props->nelts; i++)
146         {
147           svn_prop_inherited_item_t *iprop =
148             APR_ARRAY_IDX(inherited_props, i, svn_prop_inherited_item_t *);
149
150           svn_pool_clear(iterpool);
151
152           if (!opt_state->quiet)
153             {
154               if (svn_path_is_url(iprop->path_or_url))
155                 SVN_ERR(svn_cmdline_printf(
156                   iterpool, _("Inherited properties on '%s',\nfrom '%s':\n"),
157                   name_local, iprop->path_or_url));
158               else
159                 SVN_ERR(svn_cmdline_printf(
160                   iterpool, _("Inherited properties on '%s',\nfrom '%s':\n"),
161                   name_local, svn_dirent_local_style(iprop->path_or_url,
162                                                      iterpool)));
163             }
164
165           SVN_ERR(svn_cmdline__print_prop_hash(NULL, iprop->prop_hash,
166                                                (! opt_state->verbose),
167                                                iterpool));
168         }
169       svn_pool_destroy(iterpool);
170     }
171
172   if (prop_hash && apr_hash_count(prop_hash))
173     {
174       if (!opt_state->quiet)
175         SVN_ERR(svn_cmdline_printf(pool, _("Properties on '%s':\n"),
176                                    name_local));
177       SVN_ERR(svn_cmdline__print_prop_hash(NULL, prop_hash,
178                                            (! opt_state->verbose), pool));
179     }
180
181   return SVN_NO_ERROR;
182 }
183
184
185 /* This implements the `svn_opt_subcommand_t' interface. */
186 svn_error_t *
187 svn_cl__proplist(apr_getopt_t *os,
188                  void *baton,
189                  apr_pool_t *scratch_pool)
190 {
191   svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
192   svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
193   apr_array_header_t *targets;
194   apr_array_header_t *errors = apr_array_make(scratch_pool, 0,
195                                               sizeof(apr_status_t));
196
197   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
198                                                       opt_state->targets,
199                                                       ctx, FALSE,
200                                                       scratch_pool));
201
202   /* Add "." if user passed 0 file arguments */
203   svn_opt_push_implicit_dot_target(targets, scratch_pool);
204
205   if (opt_state->revprop)  /* operate on revprops */
206     {
207       svn_revnum_t rev;
208       const char *URL;
209       apr_hash_t *proplist;
210
211       if (opt_state->show_inherited_props)
212         return svn_error_create(
213           SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
214           _("--show-inherited-props can't be used with --revprop"));
215
216       SVN_ERR(svn_cl__revprop_prepare(&opt_state->start_revision, targets,
217                                       &URL, ctx, scratch_pool));
218
219       /* Let libsvn_client do the real work. */
220       SVN_ERR(svn_client_revprop_list(&proplist,
221                                       URL, &(opt_state->start_revision),
222                                       &rev, ctx, scratch_pool));
223
224       if (opt_state->xml)
225         {
226           svn_stringbuf_t *sb = NULL;
227           char *revstr = apr_psprintf(scratch_pool, "%ld", rev);
228
229           SVN_ERR(svn_cl__xml_print_header("properties", scratch_pool));
230
231           svn_xml_make_open_tag(&sb, scratch_pool, svn_xml_normal,
232                                 "revprops",
233                                 "rev", revstr, NULL);
234           SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, proplist,
235                                                    (! opt_state->verbose),
236                                                    FALSE, scratch_pool));
237           svn_xml_make_close_tag(&sb, scratch_pool, "revprops");
238
239           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
240           SVN_ERR(svn_cl__xml_print_footer("properties", scratch_pool));
241         }
242       else
243         {
244           SVN_ERR
245             (svn_cmdline_printf(scratch_pool,
246                                 _("Unversioned properties on revision %ld:\n"),
247                                 rev));
248
249           SVN_ERR(svn_cmdline__print_prop_hash(NULL, proplist,
250                                                (! opt_state->verbose),
251                                                scratch_pool));
252         }
253     }
254   else  /* operate on normal, versioned properties (not revprops) */
255     {
256       int i;
257       apr_pool_t *iterpool;
258       svn_proplist_receiver2_t pl_receiver;
259
260       if (opt_state->xml)
261         {
262           SVN_ERR(svn_cl__xml_print_header("properties", scratch_pool));
263           pl_receiver = proplist_receiver_xml;
264         }
265       else
266         {
267           pl_receiver = proplist_receiver;
268         }
269
270       if (opt_state->depth == svn_depth_unknown)
271         opt_state->depth = svn_depth_empty;
272
273       iterpool = svn_pool_create(scratch_pool);
274       for (i = 0; i < targets->nelts; i++)
275         {
276           const char *target = APR_ARRAY_IDX(targets, i, const char *);
277           proplist_baton_t pl_baton;
278           const char *truepath;
279           svn_opt_revision_t peg_revision;
280
281           svn_pool_clear(iterpool);
282           SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
283
284           pl_baton.is_url = svn_path_is_url(target);
285           pl_baton.opt_state = opt_state;
286
287           /* Check for a peg revision. */
288           SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
289                                      iterpool));
290
291           SVN_ERR(svn_cl__try(
292                    svn_client_proplist4(truepath, &peg_revision,
293                                         &(opt_state->start_revision),
294                                         opt_state->depth,
295                                         opt_state->changelists,
296                                         opt_state->show_inherited_props,
297                                         pl_receiver, &pl_baton,
298                                         ctx, iterpool),
299                    errors, opt_state->quiet,
300                    SVN_ERR_UNVERSIONED_RESOURCE,
301                    SVN_ERR_ENTRY_NOT_FOUND,
302                    SVN_NO_ERROR));
303         }
304       svn_pool_destroy(iterpool);
305
306       if (opt_state->xml)
307         SVN_ERR(svn_cl__xml_print_footer("properties", scratch_pool));
308
309       /* Error out *after* we closed the XML element */
310       if (errors->nelts > 0)
311         {
312           svn_error_t *err;
313
314           err = svn_error_create(SVN_ERR_ILLEGAL_TARGET, NULL, NULL);
315           for (i = 0; i < errors->nelts; i++)
316             {
317               apr_status_t status = APR_ARRAY_IDX(errors, i, apr_status_t);
318
319               if (status == SVN_ERR_ENTRY_NOT_FOUND)
320                 err = svn_error_quick_wrap(err,
321                                            _("Could not display properties "
322                                              "of all targets because some "
323                                              "targets don't exist"));
324               else if (status == SVN_ERR_UNVERSIONED_RESOURCE)
325                 err = svn_error_quick_wrap(err,
326                                            _("Could not display properties "
327                                              "of all targets because some "
328                                              "targets are not versioned"));
329             }
330
331           return svn_error_trace(err);
332         }
333     }
334
335   return SVN_NO_ERROR;
336 }