help-cmd.c revision 362181
1/*
2 * help-cmd.c -- Provide help
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
28/*** Includes. ***/
29
30#include "svn_hash.h"
31#include "svn_string.h"
32#include "svn_config.h"
33#include "svn_dirent_uri.h"
34#include "svn_error.h"
35#include "cl.h"
36
37#include "svn_private_config.h"
38
39
40/*** Code. ***/
41
42/* This implements the `svn_opt_subcommand_t' interface. */
43svn_error_t *
44svn_cl__help(apr_getopt_t *os,
45             void *baton,
46             apr_pool_t *pool)
47{
48  svn_cl__opt_state_t *opt_state = NULL;
49  svn_stringbuf_t *version_footer = NULL;
50  const char *config_path;
51
52  char help_header[] =
53  N_("usage: svn <subcommand> [options] [args]\n"
54     "Subversion command-line client.\n"
55     "Type 'svn help <subcommand>' for help on a specific subcommand.\n"
56     "Type 'svn --version' to see the program version and RA modules,\n"
57     "     'svn --version --verbose' to see dependency versions as well,\n"
58     "     'svn --version --quiet' to see just the version number.\n"
59     "\n"
60     "Most subcommands take file and/or directory arguments, recursing\n"
61     "on the directories.  If no arguments are supplied to such a\n"
62     "command, it recurses on the current directory (inclusive) by default.\n"
63     "\n"
64     "Available subcommands:\n");
65
66  char help_footer[] =
67  N_("Subversion is a tool for version control.\n"
68     "For additional information, see http://subversion.apache.org/\n");
69
70  const char *ra_desc_start
71    = _("The following repository access (RA) modules are available:\n\n");
72
73  if (baton)
74    {
75      svn_cl__cmd_baton_t *const cmd_baton = baton;
76#ifndef SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE
77      /* Windows never actually stores plaintext passwords, it
78         encrypts the contents using CryptoAPI. ...
79
80         ... If CryptoAPI is available ... but it should be on all
81         versions of Windows that are even remotely interesting two
82         days before the scheduled end of the world, when this comment
83         is being written. */
84#  ifndef WIN32
85      svn_boolean_t store_auth_creds =
86        SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS;
87      svn_boolean_t store_passwords =
88        SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS;
89      svn_boolean_t store_plaintext_passwords = FALSE;
90      svn_config_t *cfg;
91
92      if (cmd_baton->ctx->config)
93        {
94          cfg = svn_hash_gets(cmd_baton->ctx->config,
95                              SVN_CONFIG_CATEGORY_CONFIG);
96          if (cfg)
97            {
98              SVN_ERR(svn_config_get_bool(cfg, &store_auth_creds,
99                                          SVN_CONFIG_SECTION_AUTH,
100                                          SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
101                                          store_auth_creds));
102              SVN_ERR(svn_config_get_bool(cfg, &store_passwords,
103                                          SVN_CONFIG_SECTION_AUTH,
104                                          SVN_CONFIG_OPTION_STORE_PASSWORDS,
105                                          store_passwords));
106            }
107          cfg = svn_hash_gets(cmd_baton->ctx->config,
108                              SVN_CONFIG_CATEGORY_SERVERS);
109          if (cfg)
110            {
111              const char *value;
112              SVN_ERR(svn_config_get_yes_no_ask
113                      (cfg, &value,
114                       SVN_CONFIG_SECTION_GLOBAL,
115                       SVN_CONFIG_OPTION_STORE_PLAINTEXT_PASSWORDS,
116                       SVN_CONFIG_DEFAULT_OPTION_STORE_PLAINTEXT_PASSWORDS));
117              if (0 == svn_cstring_casecmp(value, SVN_CONFIG_TRUE))
118                store_plaintext_passwords = TRUE;
119            }
120        }
121
122      if (store_plaintext_passwords && store_auth_creds && store_passwords)
123        {
124          version_footer = svn_stringbuf_create(
125              _("WARNING: Plaintext password storage is enabled!\n\n"),
126              pool);
127          svn_stringbuf_appendcstr(version_footer, ra_desc_start);
128        }
129#  endif /* !WIN32 */
130#endif /* !SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE */
131
132      opt_state = cmd_baton->opt_state;
133    }
134
135  if (!version_footer)
136    version_footer = svn_stringbuf_create(ra_desc_start, pool);
137  SVN_ERR(svn_ra_print_modules(version_footer, pool));
138
139  /*
140   * Show auth creds storage providers.
141   */
142  SVN_ERR(svn_config_get_user_config_path(&config_path,
143                                          opt_state ? opt_state->config_dir
144                                                    : NULL,
145                                          NULL,
146                                          pool));
147  svn_stringbuf_appendcstr(version_footer,
148                           _("\nThe following authentication credential caches are available:\n\n"));
149
150  /*### There is no API to query available providers at run time. */
151  if (config_path)
152    {
153#if (defined(WIN32) && !defined(__MINGW32__))
154      version_footer =
155        svn_stringbuf_create(apr_psprintf(pool, _("%s* Wincrypt cache in %s\n"),
156                                          version_footer->data,
157                                          svn_dirent_local_style(config_path,
158                                                                 pool)),
159                             pool);
160#elif !defined(SVN_DISABLE_PLAINTEXT_PASSWORD_STORAGE)
161      version_footer =
162        svn_stringbuf_create(apr_psprintf(pool, _("%s* Plaintext cache in %s\n"),
163                                          version_footer->data,
164                                          svn_dirent_local_style(config_path,
165                                                                 pool)),
166                             pool);
167#endif
168    }
169#if (defined(SVN_HAVE_GNOME_KEYRING) || defined(SVN_HAVE_LIBSECRET))
170  svn_stringbuf_appendcstr(version_footer, "* Gnome Keyring\n");
171#endif
172#ifdef SVN_HAVE_GPG_AGENT
173  svn_stringbuf_appendcstr(version_footer, "* GPG-Agent\n");
174#endif
175#ifdef SVN_HAVE_KEYCHAIN_SERVICES
176  svn_stringbuf_appendcstr(version_footer, "* Mac OS X Keychain\n");
177#endif
178#ifdef SVN_HAVE_KWALLET
179  svn_stringbuf_appendcstr(version_footer, "* KWallet (KDE)\n");
180#endif
181
182  return svn_opt_print_help5(os,
183                             "svn",   /* ### erm, derive somehow? */
184                             opt_state ? opt_state->version : FALSE,
185                             opt_state ? opt_state->quiet : FALSE,
186                             opt_state ? opt_state->verbose : FALSE,
187                             version_footer->data,
188                             _(help_header),
189                             svn_cl__cmd_table,
190                             svn_cl__options,
191                             svn_cl__global_options,
192                             _(help_footer),
193                             pool);
194}
195