mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpgconf: New option --show-versions.
* tools/gpgconf.c: Include exechelp.h. New option --show-versions. (get_revision_from_blurb): New. (show_version_gnupg): New. (show_version_libgcrypt): New. (show_version_gpgrt): New. (show_versions_via_dirmngr): New. (show_versions): New. * tools/gpgconf-comp.c (GPGNAME): Remove unused macro. * dirmngr/dirmngr.c (main): New internal option --gpgconf-versions. (get_revision_from_blurb): New. (gpgconf_versions): New. -- This option should be helpful to gather information for debugging. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
371228a244
commit
357ad9ae29
@ -99,6 +99,7 @@ enum cmd_and_opt_values {
|
|||||||
aFlush,
|
aFlush,
|
||||||
aGPGConfList,
|
aGPGConfList,
|
||||||
aGPGConfTest,
|
aGPGConfTest,
|
||||||
|
aGPGConfVersions,
|
||||||
|
|
||||||
oOptions,
|
oOptions,
|
||||||
oDebug,
|
oDebug,
|
||||||
@ -161,6 +162,7 @@ static gpgrt_opt_t opts[] = {
|
|||||||
|
|
||||||
ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
|
ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
|
||||||
ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
|
ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
|
||||||
|
ARGPARSE_c (aGPGConfVersions, "gpgconf-versions", "@"),
|
||||||
|
|
||||||
ARGPARSE_group (300, N_("@Commands:\n ")),
|
ARGPARSE_group (300, N_("@Commands:\n ")),
|
||||||
|
|
||||||
@ -411,6 +413,8 @@ static ldap_server_t parse_ldapserver_file (const char* filename, int ienoent);
|
|||||||
static fingerprint_list_t parse_ocsp_signer (const char *string);
|
static fingerprint_list_t parse_ocsp_signer (const char *string);
|
||||||
static void netactivity_action (void);
|
static void netactivity_action (void);
|
||||||
static void handle_connections (assuan_fd_t listen_fd);
|
static void handle_connections (assuan_fd_t listen_fd);
|
||||||
|
static void gpgconf_versions (void);
|
||||||
|
|
||||||
|
|
||||||
/* NPth wrapper function definitions. */
|
/* NPth wrapper function definitions. */
|
||||||
ASSUAN_SYSTEM_NPTH_IMPL;
|
ASSUAN_SYSTEM_NPTH_IMPL;
|
||||||
@ -1007,6 +1011,7 @@ main (int argc, char **argv)
|
|||||||
case aFetchCRL:
|
case aFetchCRL:
|
||||||
case aGPGConfList:
|
case aGPGConfList:
|
||||||
case aGPGConfTest:
|
case aGPGConfTest:
|
||||||
|
case aGPGConfVersions:
|
||||||
cmd = pargs.r_opt;
|
cmd = pargs.r_opt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1116,7 +1121,7 @@ main (int argc, char **argv)
|
|||||||
* because it will attempt to connect to the tor client and that can
|
* because it will attempt to connect to the tor client and that can
|
||||||
* be time consuming. */
|
* be time consuming. */
|
||||||
post_option_parsing ();
|
post_option_parsing ();
|
||||||
if (cmd != aGPGConfTest && cmd != aGPGConfList)
|
if (cmd != aGPGConfTest && cmd != aGPGConfList && cmd != aGPGConfVersions)
|
||||||
set_tor_mode ();
|
set_tor_mode ();
|
||||||
|
|
||||||
/* Get LDAP server list from file. */
|
/* Get LDAP server list from file. */
|
||||||
@ -1518,6 +1523,9 @@ main (int argc, char **argv)
|
|||||||
es_printf ("resolver-timeout:%lu:%u\n",
|
es_printf ("resolver-timeout:%lu:%u\n",
|
||||||
flags | GC_OPT_FLAG_DEFAULT, 0);
|
flags | GC_OPT_FLAG_DEFAULT, 0);
|
||||||
}
|
}
|
||||||
|
else if (cmd == aGPGConfVersions)
|
||||||
|
gpgconf_versions ();
|
||||||
|
|
||||||
cleanup ();
|
cleanup ();
|
||||||
return !!rc;
|
return !!rc;
|
||||||
}
|
}
|
||||||
@ -2327,3 +2335,61 @@ dirmngr_get_current_socket_name (void)
|
|||||||
else
|
else
|
||||||
return dirmngr_socket_name ();
|
return dirmngr_socket_name ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse the revision part from the extended version blurb. */
|
||||||
|
static const char *
|
||||||
|
get_revision_from_blurb (const char *blurb, int *r_len)
|
||||||
|
{
|
||||||
|
const char *s = blurb? blurb : "";
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (; *s; s++)
|
||||||
|
if (*s == '\n' && s[1] == '(')
|
||||||
|
break;
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
s += 2;
|
||||||
|
for (n=0; s[n] && s[n] != ' '; n++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = "?";
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
*r_len = n;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print versions of dirmngr and used libraries. This is used by
|
||||||
|
* "gpgconf --show-versions" so that there is no need to link gpgconf
|
||||||
|
* against all these libraries. This is an internal API and should
|
||||||
|
* not be relied upon. */
|
||||||
|
static void
|
||||||
|
gpgconf_versions (void)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
/* Unfortunately Npth has no way to get the version. */
|
||||||
|
|
||||||
|
s = get_revision_from_blurb (assuan_check_version ("\x01\x01"), &n);
|
||||||
|
es_fprintf (es_stdout, "* Libassuan %s (%.*s)\n\n",
|
||||||
|
assuan_check_version (NULL), n, s);
|
||||||
|
|
||||||
|
es_fprintf (es_stdout, "* KSBA %s \n\n",
|
||||||
|
ksba_check_version (NULL));
|
||||||
|
|
||||||
|
#ifdef HTTP_USE_NTBTLS
|
||||||
|
s = get_revision_from_blurb (ntbtls_check_version ("\x01\x01"), &n);
|
||||||
|
es_fprintf (es_stdout, "* NTBTLS %s (%.*s)\n\n",
|
||||||
|
ntbtls_check_version (NULL), n, s);
|
||||||
|
#elif HTTP_USE_GNUTLS
|
||||||
|
es_fprintf (es_stdout, "* GNUTLS %s\n\n",
|
||||||
|
gnutls_check_version (NULL));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -52,14 +52,6 @@
|
|||||||
#include "../common/gc-opt-flags.h"
|
#include "../common/gc-opt-flags.h"
|
||||||
#include "gpgconf.h"
|
#include "gpgconf.h"
|
||||||
|
|
||||||
/* There is a problem with gpg 1.4 under Windows: --gpgconf-list
|
|
||||||
returns a plain filename without escaping. As long as we have not
|
|
||||||
fixed that we need to use gpg2. */
|
|
||||||
#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
|
|
||||||
#define GPGNAME "gpg2"
|
|
||||||
#else
|
|
||||||
#define GPGNAME GPG_NAME
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
168
tools/gpgconf.c
168
tools/gpgconf.c
@ -33,6 +33,7 @@
|
|||||||
#include "../common/sysutils.h"
|
#include "../common/sysutils.h"
|
||||||
#include "../common/init.h"
|
#include "../common/init.h"
|
||||||
#include "../common/status.h"
|
#include "../common/status.h"
|
||||||
|
#include "../common/exechelp.h"
|
||||||
|
|
||||||
|
|
||||||
/* Constants to identify the commands and options. */
|
/* Constants to identify the commands and options. */
|
||||||
@ -69,6 +70,7 @@ enum cmd_and_opt_values
|
|||||||
aRemoveSocketDir,
|
aRemoveSocketDir,
|
||||||
aApplyProfile,
|
aApplyProfile,
|
||||||
aReload,
|
aReload,
|
||||||
|
aShowVersions,
|
||||||
aShowCodepages
|
aShowCodepages
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -100,6 +102,7 @@ static gpgrt_opt_t opts[] =
|
|||||||
{ aKill, "kill", 256, N_("kill a given component")},
|
{ aKill, "kill", 256, N_("kill a given component")},
|
||||||
{ aCreateSocketDir, "create-socketdir", 256, "@"},
|
{ aCreateSocketDir, "create-socketdir", 256, "@"},
|
||||||
{ aRemoveSocketDir, "remove-socketdir", 256, "@"},
|
{ aRemoveSocketDir, "remove-socketdir", 256, "@"},
|
||||||
|
ARGPARSE_c (aShowVersions, "show-versions", "@"),
|
||||||
ARGPARSE_c (aShowCodepages, "show-codepages", "@"),
|
ARGPARSE_c (aShowCodepages, "show-codepages", "@"),
|
||||||
|
|
||||||
{ 301, NULL, 0, N_("@\nOptions:\n ") },
|
{ 301, NULL, 0, N_("@\nOptions:\n ") },
|
||||||
@ -127,6 +130,9 @@ static gpgrt_opt_t opts[] =
|
|||||||
* this is NULL. */
|
* this is NULL. */
|
||||||
static estream_t statusfp;
|
static estream_t statusfp;
|
||||||
|
|
||||||
|
static void show_versions (estream_t fp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Print usage information and provide strings for help. */
|
/* Print usage information and provide strings for help. */
|
||||||
static const char *
|
static const char *
|
||||||
@ -604,6 +610,7 @@ main (int argc, char **argv)
|
|||||||
case aKill:
|
case aKill:
|
||||||
case aCreateSocketDir:
|
case aCreateSocketDir:
|
||||||
case aRemoveSocketDir:
|
case aRemoveSocketDir:
|
||||||
|
case aShowVersions:
|
||||||
case aShowCodepages:
|
case aShowCodepages:
|
||||||
cmd = pargs.r_opt;
|
cmd = pargs.r_opt;
|
||||||
break;
|
break;
|
||||||
@ -923,6 +930,13 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aShowVersions:
|
||||||
|
{
|
||||||
|
get_outfp (&outfp);
|
||||||
|
show_versions (outfp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case aShowCodepages:
|
case aShowCodepages:
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
{
|
{
|
||||||
@ -961,3 +975,157 @@ gpgconf_failure (gpg_error_t err)
|
|||||||
gpg_err_code (err) == GPG_ERR_USER_2? GPG_ERR_EINVAL : err);
|
gpg_err_code (err) == GPG_ERR_USER_2? GPG_ERR_EINVAL : err);
|
||||||
exit (gpg_err_code (err) == GPG_ERR_USER_2? 2 : 1);
|
exit (gpg_err_code (err) == GPG_ERR_USER_2? 2 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse the revision part from the extended version blurb. */
|
||||||
|
static const char *
|
||||||
|
get_revision_from_blurb (const char *blurb, int *r_len)
|
||||||
|
{
|
||||||
|
const char *s = blurb? blurb : "";
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (; *s; s++)
|
||||||
|
if (*s == '\n' && s[1] == '(')
|
||||||
|
break;
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
s += 2;
|
||||||
|
for (n=0; s[n] && s[n] != ' '; n++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = "?";
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
*r_len = n;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_version_gnupg (estream_t fp)
|
||||||
|
{
|
||||||
|
es_fprintf (fp, "* GnuPG %s (%s)\n%s\n",
|
||||||
|
gpgrt_strusage (13), BUILD_REVISION, gpgrt_strusage (17));
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
{
|
||||||
|
OSVERSIONINFO osvi = { sizeof (osvi) };
|
||||||
|
|
||||||
|
GetVersionEx (&osvi);
|
||||||
|
es_fprintf (fp, "Windows %lu.%lu build %lu%s%s%s\n",
|
||||||
|
(unsigned long)osvi.dwMajorVersion,
|
||||||
|
(unsigned long)osvi.dwMinorVersion,
|
||||||
|
(unsigned long)osvi.dwBuildNumber,
|
||||||
|
*osvi.szCSDVersion? " (":"",
|
||||||
|
osvi.szCSDVersion,
|
||||||
|
*osvi.szCSDVersion? ")":""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_version_libgcrypt (estream_t fp)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
s = get_revision_from_blurb (gcry_check_version ("\x01\x01"), &n);
|
||||||
|
es_fprintf (fp, "* Libgcrypt %s (%.*s)\n",
|
||||||
|
gcry_check_version (NULL), n, s);
|
||||||
|
#if GCRYPT_VERSION_NUMBER >= 0x010800
|
||||||
|
s = gcry_get_config (0, NULL);
|
||||||
|
if (s)
|
||||||
|
es_fputs (s, fp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_version_gpgrt (estream_t fp)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
s = get_revision_from_blurb (gpg_error_check_version ("\x01\x01"), &n);
|
||||||
|
es_fprintf (fp, "* GpgRT %s (%.*s)\n",
|
||||||
|
gpg_error_check_version (NULL), n, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Printing version information for other libraries is problematic
|
||||||
|
* because we don't want to link gpgconf to all these libraries. The
|
||||||
|
* best solution is delegating this to dirmngr which uses libassuan,
|
||||||
|
* libksba, libnpth and ntbtls anyway. */
|
||||||
|
static void
|
||||||
|
show_versions_via_dirmngr (estream_t fp)
|
||||||
|
{
|
||||||
|
gpg_error_t err;
|
||||||
|
const char *pgmname;
|
||||||
|
const char *argv[2];
|
||||||
|
estream_t outfp;
|
||||||
|
pid_t pid;
|
||||||
|
char *line = NULL;
|
||||||
|
size_t line_len = 0;
|
||||||
|
ssize_t length;
|
||||||
|
int exitcode;
|
||||||
|
|
||||||
|
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR);
|
||||||
|
argv[0] = "--gpgconf-versions";
|
||||||
|
argv[1] = NULL;
|
||||||
|
err = gnupg_spawn_process (pgmname, argv, NULL, NULL, 0,
|
||||||
|
NULL, &outfp, NULL, &pid);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("error spawning %s: %s", pgmname, gpg_strerror (err));
|
||||||
|
es_fprintf (fp, "[error: can't get further info]\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((length = es_read_line (outfp, &line, &line_len, NULL)) > 0)
|
||||||
|
{
|
||||||
|
/* Strip newline and carriage return, if present. */
|
||||||
|
while (length > 0
|
||||||
|
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
|
||||||
|
line[--length] = '\0';
|
||||||
|
es_fprintf (fp, "%s\n", line);
|
||||||
|
}
|
||||||
|
if (length < 0 || es_ferror (outfp))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error reading from %s: %s\n", pgmname, gpg_strerror (err));
|
||||||
|
}
|
||||||
|
if (es_fclose (outfp))
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
log_error ("error closing output stream of %s: %s\n",
|
||||||
|
pgmname, gpg_strerror (err));
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gnupg_wait_process (pgmname, pid, 1, &exitcode);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("running %s failed (exitcode=%d): %s\n",
|
||||||
|
pgmname, exitcode, gpg_strerror (err));
|
||||||
|
es_fprintf (fp, "[error: can't get further info]\n");
|
||||||
|
}
|
||||||
|
gnupg_release_process (pid);
|
||||||
|
xfree (line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Show all kind of version information. */
|
||||||
|
static void
|
||||||
|
show_versions (estream_t fp)
|
||||||
|
{
|
||||||
|
show_version_gnupg (fp);
|
||||||
|
es_fputc ('\n', fp);
|
||||||
|
show_version_libgcrypt (fp);
|
||||||
|
es_fputc ('\n', fp);
|
||||||
|
show_version_gpgrt (fp);
|
||||||
|
es_fputc ('\n', fp);
|
||||||
|
show_versions_via_dirmngr (fp);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user