Success build TortoiseMerge.
[TortoiseGit.git] / src / TortoiseMerge / libsvn_diff / cmdline.c
blobc77b0021750fa7000cf29e27ac9d437cc9f27a7a
1 /*
2 * cmdline.c : Helpers for command-line programs.
4 * ====================================================================
5 * Copyright (c) 2003-2009 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
20 #include <stdlib.h> /* for atexit() */
21 #include <stdio.h> /* for setvbuf() */
22 #include <locale.h> /* for setlocale() */
24 #ifndef WIN32
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #endif
31 #include <apr_errno.h> /* for apr_strerror */
32 #include <apr_general.h> /* for apr_initialize/apr_terminate */
33 #include <apr_atomic.h> /* for apr_atomic_init */
34 #include <apr_strings.h> /* for apr_snprintf */
35 #include <apr_pools.h>
37 #include "svn_cmdline.h"
38 #include "svn_dso.h"
39 #include "svn_path.h"
40 #include "svn_pools.h"
41 #include "svn_error.h"
42 #include "svn_nls.h"
43 #include "svn_utf.h"
44 #include "svn_auth.h"
45 #include "svn_version.h"
46 #include "svn_xml.h"
47 #include "svn_base64.h"
48 #include "svn_config.h"
50 //#include "private/svn_cmdline_private.h"
51 //#include "private/svn_utf_private.h"
53 //#include "svn_private_config.h"
55 //#include "win32_crashrpt.h"
57 /* The stdin encoding. If null, it's the same as the native encoding. */
58 static const char *input_encoding = NULL;
60 /* The stdout encoding. If null, it's the same as the native encoding. */
61 static const char *output_encoding = NULL;
63 #if 0
64 int
65 svn_cmdline_init(const char *progname, FILE *error_stream)
67 apr_status_t status;
68 apr_pool_t *pool;
69 svn_error_t *err;
71 #ifndef WIN32
73 struct stat st;
75 /* The following makes sure that file descriptors 0 (stdin), 1
76 (stdout) and 2 (stderr) will not be "reused", because if
77 e.g. file descriptor 2 would be reused when opening a file, a
78 write to stderr would write to that file and most likely
79 corrupt it. */
80 if ((fstat(0, &st) == -1 && open("/dev/null", O_RDONLY) == -1) ||
81 (fstat(1, &st) == -1 && open("/dev/null", O_WRONLY) == -1) ||
82 (fstat(2, &st) == -1 && open("/dev/null", O_WRONLY) == -1))
84 if (error_stream)
85 fprintf(error_stream, "%s: error: cannot open '/dev/null'\n",
86 progname);
87 return EXIT_FAILURE;
90 #endif
92 /* Ignore any errors encountered while attempting to change stream
93 buffering, as the streams should retain their default buffering
94 modes. */
95 if (error_stream)
96 setvbuf(error_stream, NULL, _IONBF, 0);
97 #ifndef WIN32
98 setvbuf(stdout, NULL, _IOLBF, 0);
99 #endif
101 #ifdef WIN32
102 #if _MSC_VER < 1400
103 /* Initialize the input and output encodings. */
105 static char input_encoding_buffer[16];
106 static char output_encoding_buffer[16];
108 apr_snprintf(input_encoding_buffer, sizeof input_encoding_buffer,
109 "CP%u", (unsigned) GetConsoleCP());
110 input_encoding = input_encoding_buffer;
112 apr_snprintf(output_encoding_buffer, sizeof output_encoding_buffer,
113 "CP%u", (unsigned) GetConsoleOutputCP());
114 output_encoding = output_encoding_buffer;
116 #endif /* _MSC_VER < 1400 */
118 #ifdef SVN_USE_WIN32_CRASHHANDLER
119 /* Attach (but don't load) the crash handler */
120 SetUnhandledExceptionFilter(svn__unhandled_exception_filter);
121 #endif
123 #endif /* WIN32 */
125 /* C programs default to the "C" locale. But because svn is supposed
126 to be i18n-aware, it should inherit the default locale of its
127 environment. */
128 if (!setlocale(LC_ALL, "")
129 && !setlocale(LC_CTYPE, ""))
131 if (error_stream)
133 const char *env_vars[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
134 const char **env_var = &env_vars[0], *env_val = NULL;
135 while (*env_var)
137 env_val = getenv(*env_var);
138 if (env_val && env_val[0])
139 break;
140 ++env_var;
143 if (!*env_var)
145 /* Unlikely. Can setlocale fail if no env vars are set? */
146 --env_var;
147 env_val = "not set";
150 fprintf(error_stream,
151 "%s: warning: cannot set LC_CTYPE locale\n"
152 "%s: warning: environment variable %s is %s\n"
153 "%s: warning: please check that your locale name is correct\n",
154 progname, progname, *env_var, env_val, progname);
158 /* Initialize the APR subsystem, and register an atexit() function
159 to Uninitialize that subsystem at program exit. */
160 status = apr_initialize();
161 if (status)
163 if (error_stream)
165 char buf[1024];
166 apr_strerror(status, buf, sizeof(buf) - 1);
167 fprintf(error_stream,
168 "%s: error: cannot initialize APR: %s\n",
169 progname, buf);
171 return EXIT_FAILURE;
174 /* This has to happen before any pools are created. */
175 if ((err = svn_dso_initialize2()))
177 if (error_stream && err->message)
178 fprintf(error_stream, "%s", err->message);
180 svn_error_clear(err);
181 return EXIT_FAILURE;
184 if (0 > atexit(apr_terminate))
186 if (error_stream)
187 fprintf(error_stream,
188 "%s: error: atexit registration failed\n",
189 progname);
190 return EXIT_FAILURE;
193 /* Create a pool for use by the UTF-8 routines. It will be cleaned
194 up by APR at exit time. */
195 pool = svn_pool_create(NULL);
196 svn_utf_initialize(pool);
198 if ((err = svn_nls_init()))
200 if (error_stream && err->message)
201 fprintf(error_stream, "%s", err->message);
203 svn_error_clear(err);
204 return EXIT_FAILURE;
207 return EXIT_SUCCESS;
209 #endif
211 svn_error_t *
212 svn_cmdline_cstring_from_utf8(const char **dest,
213 const char *src,
214 apr_pool_t *pool)
216 if (output_encoding == NULL)
217 return svn_utf_cstring_from_utf8(dest, src, pool);
218 else
219 return svn_utf_cstring_from_utf8_ex2(dest, src, output_encoding, pool);
222 const char *
223 svn_cmdline_cstring_from_utf8_fuzzy(const char *src,
224 apr_pool_t *pool)
226 return svn_utf__cstring_from_utf8_fuzzy(src, pool,
227 svn_cmdline_cstring_from_utf8);
231 svn_error_t *
232 svn_cmdline_cstring_to_utf8(const char **dest,
233 const char *src,
234 apr_pool_t *pool)
236 if (input_encoding == NULL)
237 return svn_utf_cstring_to_utf8(dest, src, pool);
238 else
239 return svn_utf_cstring_to_utf8_ex2(dest, src, input_encoding, pool);
242 #if 0
243 svn_error_t *
244 svn_cmdline_path_local_style_from_utf8(const char **dest,
245 const char *src,
246 apr_pool_t *pool)
248 return svn_cmdline_cstring_from_utf8(dest,
249 svn_path_local_style(src, pool),
250 pool);
253 svn_error_t *
254 svn_cmdline_printf(apr_pool_t *pool, const char *fmt, ...)
256 const char *message;
257 va_list ap;
259 /* A note about encoding issues:
260 * APR uses the execution character set, but here we give it UTF-8 strings,
261 * both the fmt argument and any other string arguments. Since apr_pvsprintf
262 * only cares about and produces ASCII characters, this works under the
263 * assumption that all supported platforms use an execution character set
264 * with ASCII as a subset.
267 va_start(ap, fmt);
268 message = apr_pvsprintf(pool, fmt, ap);
269 va_end(ap);
271 return svn_cmdline_fputs(message, stdout, pool);
273 #endif
274 svn_error_t *
275 svn_cmdline_fprintf(FILE *stream, apr_pool_t *pool, const char *fmt, ...)
277 const char *message;
278 va_list ap;
280 /* See svn_cmdline_printf () for a note about character encoding issues. */
282 va_start(ap, fmt);
283 message = apr_pvsprintf(pool, fmt, ap);
284 va_end(ap);
286 return svn_cmdline_fputs(message, stream, pool);
289 svn_error_t *
290 svn_cmdline_fputs(const char *string, FILE* stream, apr_pool_t *pool)
292 svn_error_t *err;
293 const char *out;
295 err = svn_cmdline_cstring_from_utf8(&out, string, pool);
297 if (err)
299 svn_error_clear(err);
300 out = svn_cmdline_cstring_from_utf8_fuzzy(string, pool);
303 /* On POSIX systems, errno will be set on an error in fputs, but this might
304 not be the case on other platforms. We reset errno and only
305 use it if it was set by the below fputs call. Else, we just return
306 a generic error. */
307 errno = 0;
309 if (fputs(out, stream) == EOF)
311 if (errno)
312 return svn_error_wrap_apr(errno, _("Write error"));
313 else
314 return svn_error_create
315 (SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
318 return SVN_NO_ERROR;
320 #if 0
321 svn_error_t *
322 svn_cmdline_fflush(FILE *stream)
324 /* See comment in svn_cmdline_fputs about use of errno and stdio. */
325 errno = 0;
326 if (fflush(stream) == EOF)
328 if (errno)
329 return svn_error_wrap_apr(errno, _("Write error"));
330 else
331 return svn_error_create(SVN_ERR_IO_WRITE_ERROR, NULL, NULL);
334 return SVN_NO_ERROR;
337 const char *svn_cmdline_output_encoding(apr_pool_t *pool)
339 if (output_encoding)
340 return apr_pstrdup(pool, output_encoding);
341 else
342 return SVN_APR_LOCALE_CHARSET;
346 svn_cmdline_handle_exit_error(svn_error_t *err,
347 apr_pool_t *pool,
348 const char *prefix)
350 svn_handle_error2(err, stderr, FALSE, prefix);
351 svn_error_clear(err);
352 if (pool)
353 svn_pool_destroy(pool);
354 return EXIT_FAILURE;
357 /* This implements 'svn_auth_ssl_server_trust_prompt_func_t'.
359 Don't actually prompt. Instead, set *CRED_P to valid credentials
360 iff FAILURES is empty or is exactly SVN_AUTH_SSL_UNKNOWNCA. If
361 there are any other failure bits, then set *CRED_P to null (that
362 is, reject the cert).
364 Ignore MAY_SAVE; we don't save certs we never prompted for.
366 Ignore BATON, REALM, and CERT_INFO,
368 Ignore any further films by George Lucas. */
369 static svn_error_t *
370 ssl_trust_unknown_server_cert
371 (svn_auth_cred_ssl_server_trust_t **cred_p,
372 void *baton,
373 const char *realm,
374 apr_uint32_t failures,
375 const svn_auth_ssl_server_cert_info_t *cert_info,
376 svn_boolean_t may_save,
377 apr_pool_t *pool)
379 *cred_p = NULL;
381 if (failures == 0 || failures == SVN_AUTH_SSL_UNKNOWNCA)
383 *cred_p = apr_pcalloc(pool, sizeof(**cred_p));
384 (*cred_p)->may_save = FALSE;
385 (*cred_p)->accepted_failures = failures;
388 return SVN_NO_ERROR;
391 svn_error_t *
392 svn_cmdline_create_auth_baton(svn_auth_baton_t **ab,
393 svn_boolean_t non_interactive,
394 const char *auth_username,
395 const char *auth_password,
396 const char *config_dir,
397 svn_boolean_t no_auth_cache,
398 svn_boolean_t trust_server_cert,
399 svn_config_t *cfg,
400 svn_cancel_func_t cancel_func,
401 void *cancel_baton,
402 apr_pool_t *pool)
404 svn_boolean_t store_password_val = TRUE;
405 svn_boolean_t store_auth_creds_val = TRUE;
406 svn_auth_provider_object_t *provider;
407 svn_cmdline_prompt_baton2_t *pb = NULL;
409 /* The whole list of registered providers */
410 apr_array_header_t *providers;
412 /* Populate the registered providers with the platform-specific providers */
413 SVN_ERR(svn_auth_get_platform_specific_client_providers
414 (&providers, cfg, pool));
416 /* If we have a cancellation function, cram it and the stuff it
417 needs into the prompt baton. */
418 if (cancel_func)
420 pb = apr_palloc(pool, sizeof(*pb));
421 pb->cancel_func = cancel_func;
422 pb->cancel_baton = cancel_baton;
423 pb->config_dir = config_dir;
426 if (non_interactive == FALSE)
428 /* This provider doesn't prompt the user in order to get creds;
429 it prompts the user regarding the caching of creds. */
430 svn_auth_get_simple_provider2(&provider,
431 svn_cmdline_auth_plaintext_prompt,
432 pb, pool);
434 else
436 svn_auth_get_simple_provider2(&provider, NULL, NULL, pool);
439 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
440 svn_auth_get_username_provider(&provider, pool);
441 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
443 /* The server-cert, client-cert, and client-cert-password providers. */
444 SVN_ERR(svn_auth_get_platform_specific_provider(&provider,
445 "windows",
446 "ssl_server_trust",
447 pool));
449 if (provider)
450 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
452 svn_auth_get_ssl_server_trust_file_provider(&provider, pool);
453 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
454 svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
455 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
457 if (non_interactive == FALSE)
459 /* This provider doesn't prompt the user in order to get creds;
460 it prompts the user regarding the caching of creds. */
461 svn_auth_get_ssl_client_cert_pw_file_provider2
462 (&provider, svn_cmdline_auth_plaintext_passphrase_prompt,
463 pb, pool);
465 else
467 svn_auth_get_ssl_client_cert_pw_file_provider2(&provider, NULL, NULL,
468 pool);
470 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
472 if (non_interactive == FALSE)
474 /* Two basic prompt providers: username/password, and just username. */
475 svn_auth_get_simple_prompt_provider(&provider,
476 svn_cmdline_auth_simple_prompt,
478 2, /* retry limit */
479 pool);
480 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
482 svn_auth_get_username_prompt_provider
483 (&provider, svn_cmdline_auth_username_prompt, pb,
484 2, /* retry limit */ pool);
485 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
487 /* Three ssl prompt providers, for server-certs, client-certs,
488 and client-cert-passphrases. */
489 svn_auth_get_ssl_server_trust_prompt_provider
490 (&provider, svn_cmdline_auth_ssl_server_trust_prompt, pb, pool);
491 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
493 svn_auth_get_ssl_client_cert_prompt_provider
494 (&provider, svn_cmdline_auth_ssl_client_cert_prompt, pb, 2, pool);
495 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
497 svn_auth_get_ssl_client_cert_pw_prompt_provider
498 (&provider, svn_cmdline_auth_ssl_client_cert_pw_prompt, pb, 2, pool);
499 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
501 else if (trust_server_cert)
503 /* Remember, only register this provider if non_interactive. */
504 svn_auth_get_ssl_server_trust_prompt_provider
505 (&provider, ssl_trust_unknown_server_cert, NULL, pool);
506 APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
509 /* Build an authentication baton to give to libsvn_client. */
510 svn_auth_open(ab, providers, pool);
512 /* Place any default --username or --password credentials into the
513 auth_baton's run-time parameter hash. */
514 if (auth_username)
515 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_DEFAULT_USERNAME,
516 auth_username);
517 if (auth_password)
518 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD,
519 auth_password);
521 /* Same with the --non-interactive option. */
522 if (non_interactive)
523 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_NON_INTERACTIVE, "");
525 if (config_dir)
526 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_CONFIG_DIR,
527 config_dir);
529 /* Determine whether storing passwords in any form is allowed.
530 * This is the deprecated location for this option, the new
531 * location is SVN_CONFIG_CATEGORY_SERVERS. The RA layer may
532 * override the value we set here. */
533 SVN_ERR(svn_config_get_bool(cfg, &store_password_val,
534 SVN_CONFIG_SECTION_AUTH,
535 SVN_CONFIG_OPTION_STORE_PASSWORDS,
536 SVN_CONFIG_DEFAULT_OPTION_STORE_PASSWORDS));
538 if (! store_password_val)
539 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
541 /* Determine whether we are allowed to write to the auth/ area.
542 * This is the deprecated location for this option, the new
543 * location is SVN_CONFIG_CATEGORY_SERVERS. The RA layer may
544 * override the value we set here. */
545 SVN_ERR(svn_config_get_bool(cfg, &store_auth_creds_val,
546 SVN_CONFIG_SECTION_AUTH,
547 SVN_CONFIG_OPTION_STORE_AUTH_CREDS,
548 SVN_CONFIG_DEFAULT_OPTION_STORE_AUTH_CREDS));
550 if (no_auth_cache || ! store_auth_creds_val)
551 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
553 #ifdef SVN_HAVE_GNOME_KEYRING
554 svn_auth_set_parameter(*ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
555 &svn_cmdline__auth_gnome_keyring_unlock_prompt);
556 #endif /* SVN_HAVE_GNOME_KEYRING */
558 return SVN_NO_ERROR;
561 svn_error_t *
562 svn_cmdline__getopt_init(apr_getopt_t **os,
563 int argc,
564 const char *argv[],
565 apr_pool_t *pool)
567 apr_status_t apr_err = apr_getopt_init(os, pool, argc, argv);
568 if (apr_err)
569 return svn_error_wrap_apr(apr_err,
570 _("Error initializing command line arguments"));
571 return SVN_NO_ERROR;
575 void
576 svn_cmdline__print_xml_prop(svn_stringbuf_t **outstr,
577 const char* propname,
578 svn_string_t *propval,
579 apr_pool_t *pool)
581 const char *xml_safe;
582 const char *encoding = NULL;
584 if (*outstr == NULL)
585 *outstr = svn_stringbuf_create("", pool);
587 if (svn_xml_is_xml_safe(propval->data, propval->len))
589 svn_stringbuf_t *xml_esc = NULL;
590 svn_xml_escape_cdata_string(&xml_esc, propval, pool);
591 xml_safe = xml_esc->data;
593 else
595 const svn_string_t *base64ed = svn_base64_encode_string2(propval, TRUE,
596 pool);
597 encoding = "base64";
598 xml_safe = base64ed->data;
601 if (encoding)
602 svn_xml_make_open_tag(outstr, pool, svn_xml_protect_pcdata,
603 "property", "name", propname,
604 "encoding", encoding, NULL);
605 else
606 svn_xml_make_open_tag(outstr, pool, svn_xml_protect_pcdata,
607 "property", "name", propname, NULL);
609 svn_stringbuf_appendcstr(*outstr, xml_safe);
611 svn_xml_make_close_tag(outstr, pool, "property");
613 return;
617 #endif