1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-02 12:01:32 +01:00

gpg: Print export statistics to the status-fd.

* common/status.h (STATUS_EXPORT_RES): New.
* g10/main.h (export_stats_t): New.
* g10/export.c (export_stats_s): New.
(export_new_stats, export_release_stats): New.
(export_print_stats): New.
(export_pubkeys, export_seckeys, export_secsubkeys)
(export_pubkey_buffer, do_export): Add arg "stats".
(do_export_stream): Add arg stats and update it.
* g10/gpg.c (main) <aExport, aExportSecret, aExportSecretSub>: Create,
pass, and print a stats object to the export function calls.

* g10/export.c (export_pubkeys_stream): Remove unused function.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-11-12 16:02:35 +01:00
parent a3b26d6c08
commit e3c48335f9
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
9 changed files with 172 additions and 51 deletions

View File

@ -55,12 +55,15 @@ enum
STATUS_GOODMDC, STATUS_GOODMDC,
STATUS_BADMDC, STATUS_BADMDC,
STATUS_ERRMDC, STATUS_ERRMDC,
STATUS_IMPORTED, STATUS_IMPORTED,
STATUS_IMPORT_OK, STATUS_IMPORT_OK,
STATUS_IMPORT_PROBLEM, STATUS_IMPORT_PROBLEM,
STATUS_IMPORT_RES, STATUS_IMPORT_RES,
STATUS_IMPORT_CHECK, STATUS_IMPORT_CHECK,
STATUS_EXPORT_RES,
STATUS_FILE_START, STATUS_FILE_START,
STATUS_FILE_DONE, STATUS_FILE_DONE,
STATUS_FILE_ERROR, STATUS_FILE_ERROR,

View File

@ -768,6 +768,16 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
- <not_imported> - <not_imported>
- <skipped_v3_keys> - <skipped_v3_keys>
*** EXPORT_RES <args>
Final statistics on export process (this is one long line). The
args are a list of unsigned numbers separated by white space:
- <count>
- <secret_count>
- <exported>
** Smartcard related ** Smartcard related
*** CARDCTRL <what> [<serialno>] *** CARDCTRL <what> [<serialno>]
This is used to control smartcard operations. Defined values for This is used to control smartcard operations. Defined values for

View File

@ -46,14 +46,28 @@ struct subkey_list_s
typedef struct subkey_list_s *subkey_list_t; typedef struct subkey_list_s *subkey_list_t;
static int do_export (ctrl_t ctrl, /* An object to track statistics for export operations. */
strlist_t users, int secret, unsigned int options ); struct export_stats_s
{
ulong count; /* Number of processed keys. */
ulong secret_count; /* Number of secret keys seen. */
ulong exported; /* Number of actual exported keys. */
};
/* Local prototypes. */
static int do_export (ctrl_t ctrl, strlist_t users, int secret,
unsigned int options, export_stats_t stats);
static int do_export_stream (ctrl_t ctrl, iobuf_t out, static int do_export_stream (ctrl_t ctrl, iobuf_t out,
strlist_t users, int secret, strlist_t users, int secret,
kbnode_t *keyblock_out, unsigned int options, kbnode_t *keyblock_out, unsigned int options,
int *any); export_stats_t stats, int *any);
/* Option parser for export options. See parse_options fro
details. */
int int
parse_export_options(char *str,unsigned int *options,int noisy) parse_export_options(char *str,unsigned int *options,int noisy)
{ {
@ -85,39 +99,102 @@ parse_export_options(char *str,unsigned int *options,int noisy)
} }
/**************** /* Create a new export stats object initialized to zero. On error
* Export the public keys (to standard out or --output). returns NULL and sets ERRNO. */
* Depending on opt.armor the output is armored. export_stats_t
* options are defined in main.h. export_new_stats (void)
* If USERS is NULL, the complete ring will be exported. */
int
export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options )
{ {
return do_export (ctrl, users, 0, options ); export_stats_t stats;
return xtrycalloc (1, sizeof *stats);
} }
/****************
* Export to an already opened stream; return -1 if no keys have
* been exported
*/
int
export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users,
kbnode_t *keyblock_out, unsigned int options )
{
int any, rc;
rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any); /* Release an export stats object. */
if (!rc && !any) void
rc = -1; export_release_stats (export_stats_t stats)
return rc; {
xfree (stats);
}
/* Print export statistics using the status interface. */
void
export_print_stats (export_stats_t stats)
{
if (!stats)
return;
if (is_status_enabled ())
{
char buf[15*20];
snprintf (buf, sizeof buf, "%lu %lu %lu",
stats->count,
stats->secret_count,
stats->exported );
write_status_text (STATUS_EXPORT_RES, buf);
}
} }
/* /*
* Export a single key into a memory buffer. * Export public keys (to stdout or to --output FILE).
*
* Depending on opt.armor the output is armored. OPTIONS are defined
* in main.h. If USERS is NULL, all keys will be exported. STATS is
* either an export stats object for update or NULL.
*
* This function is the core of "gpg --export".
*/
int
export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
export_stats_t stats)
{
return do_export (ctrl, users, 0, options, stats);
}
/*
* Export secret keys (to stdout or to --output FILE).
*
* Depending on opt.armor the output is armored. If USERS is NULL,
* all secret keys will be exported. STATS is either an export stats
* object for update or NULL.
*
* This function is the core of "gpg --export-secret-keys".
*/
int
export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
{
return do_export (ctrl, users, 1, 0, stats);
}
/*
* Export secret sub keys (to stdout or to --output FILE).
*
* This is the same as export_seckeys but replaces the primary key by
* a stub key. Depending on opt.armor the output is armored. If
* USERS is NULL, all secret subkeys will be exported. STATS is
* either an export stats object for update or NULL.
*
* This function is the core of "gpg --export-secret-subkeys".
*/
int
export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats)
{
return do_export (ctrl, users, 2, 0, stats);
}
/*
* Export a single key into a memory buffer. STATS is either an
* export stats object for update or NULL.
*/ */
gpg_error_t gpg_error_t
export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
export_stats_t stats,
kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) kbnode_t *r_keyblock, void **r_data, size_t *r_datalen)
{ {
gpg_error_t err; gpg_error_t err;
@ -134,7 +211,8 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
iobuf = iobuf_temp (); iobuf = iobuf_temp ();
err = do_export_stream (ctrl, iobuf, helplist, 0, r_keyblock, options, &any); err = do_export_stream (ctrl, iobuf, helplist, 0, r_keyblock, options,
stats, &any);
if (!err && !any) if (!err && !any)
err = gpg_error (GPG_ERR_NOT_FOUND); err = gpg_error (GPG_ERR_NOT_FOUND);
if (!err) if (!err)
@ -166,26 +244,14 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
} }
int
export_seckeys (ctrl_t ctrl, strlist_t users )
{
return do_export (ctrl, users, 1, 0);
}
int
export_secsubkeys (ctrl_t ctrl, strlist_t users )
{
return do_export (ctrl, users, 2, 0);
}
/* Export the keys identified by the list of strings in USERS. If /* Export the keys identified by the list of strings in USERS. If
Secret is false public keys will be exported. With secret true Secret is false public keys will be exported. With secret true
secret keys will be exported; in this case 1 means the entire secret keys will be exported; in this case 1 means the entire
secret keyblock and 2 only the subkeys. OPTIONS are the export secret keyblock and 2 only the subkeys. OPTIONS are the export
options to apply. */ options to apply. */
static int static int
do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options ) do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options,
export_stats_t stats)
{ {
IOBUF out = NULL; IOBUF out = NULL;
int any, rc; int any, rc;
@ -205,7 +271,7 @@ do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options )
push_armor_filter (afx, out); push_armor_filter (afx, out);
} }
rc = do_export_stream (ctrl, out, users, secret, NULL, options, &any ); rc = do_export_stream (ctrl, out, users, secret, NULL, options, stats, &any);
if ( rc || !any ) if ( rc || !any )
iobuf_cancel (out); iobuf_cancel (out);
@ -754,7 +820,8 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk)
key has been exported true is stored at ANY. */ key has been exported true is stored at ANY. */
static int static int
do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
kbnode_t *keyblock_out, unsigned int options, int *any) kbnode_t *keyblock_out, unsigned int options,
export_stats_t stats, int *any)
{ {
gpg_error_t err = 0; gpg_error_t err = 0;
PACKET pkt; PACKET pkt;
@ -767,7 +834,10 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
strlist_t sl; strlist_t sl;
gcry_cipher_hd_t cipherhd = NULL; gcry_cipher_hd_t cipherhd = NULL;
char *cache_nonce = NULL; char *cache_nonce = NULL;
struct export_stats_s dummystats;
if (!stats)
stats = &dummystats;
*any = 0; *any = 0;
init_packet (&pkt); init_packet (&pkt);
kdbhd = keydb_new (); kdbhd = keydb_new ();
@ -877,6 +947,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
log_error ("public key packet not found in keyblock - skipped\n"); log_error ("public key packet not found in keyblock - skipped\n");
continue; continue;
} }
stats->count++;
setup_main_keyids (keyblock); /* gpg_format_keydesc needs it. */ setup_main_keyids (keyblock); /* gpg_format_keydesc needs it. */
pk = node->pkt->pkt.public_key; pk = node->pkt->pkt.public_key;
keyid_from_pk (pk, keyid); keyid_from_pk (pk, keyid);
@ -906,6 +977,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
"not yet supported - skipped\n", keystr (keyid)); "not yet supported - skipped\n", keystr (keyid));
continue; continue;
} }
stats->secret_count++;
} }
/* Always do the cleaning on the public key part if requested. /* Always do the cleaning on the public key part if requested.
@ -1109,6 +1181,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
} }
err = build_packet (out, node->pkt); err = build_packet (out, node->pkt);
if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
stats->exported++;
} }
else if (!err) else if (!err)
{ {
@ -1164,6 +1238,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
goto unwraperror; goto unwraperror;
err = build_packet (out, node->pkt); err = build_packet (out, node->pkt);
if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
stats->exported++;
goto unwraperror_leave; goto unwraperror_leave;
unwraperror: unwraperror:
@ -1201,8 +1277,11 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret,
else else
{ {
err = build_packet (out, node->pkt); err = build_packet (out, node->pkt);
if (!err && node->pkt->pkttype == PKT_PUBLIC_KEY)
stats->exported++;
} }
if (err) if (err)
{ {
log_error ("build_packet(%d) failed: %s\n", log_error ("build_packet(%d) failed: %s\n",

View File

@ -4306,7 +4306,12 @@ main (int argc, char **argv)
else if( cmd == aRecvKeys ) else if( cmd == aRecvKeys )
rc = keyserver_import (ctrl, sl ); rc = keyserver_import (ctrl, sl );
else else
rc = export_pubkeys (ctrl, sl, opt.export_options); {
export_stats_t stats = export_new_stats ();
rc = export_pubkeys (ctrl, sl, opt.export_options, stats);
export_print_stats (stats);
export_release_stats (stats);
}
if(rc) if(rc)
{ {
if(cmd==aSendKeys) if(cmd==aSendKeys)
@ -4372,7 +4377,12 @@ main (int argc, char **argv)
sl = NULL; sl = NULL;
for( ; argc; argc--, argv++ ) for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings ); add_to_strlist2( &sl, *argv, utf8_strings );
export_seckeys (ctrl, sl); {
export_stats_t stats = export_new_stats ();
export_seckeys (ctrl, sl, stats);
export_print_stats (stats);
export_release_stats (stats);
}
free_strlist(sl); free_strlist(sl);
break; break;
@ -4380,7 +4390,12 @@ main (int argc, char **argv)
sl = NULL; sl = NULL;
for( ; argc; argc--, argv++ ) for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings ); add_to_strlist2( &sl, *argv, utf8_strings );
export_secsubkeys (ctrl, sl); {
export_stats_t stats = export_new_stats ();
export_secsubkeys (ctrl, sl, stats);
export_print_stats (stats);
export_release_stats (stats);
}
free_strlist(sl); free_strlist(sl);
break; break;

View File

@ -606,11 +606,13 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
gpg_error_t gpg_error_t
export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
export_stats_t stats,
kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) kbnode_t *r_keyblock, void **r_data, size_t *r_datalen)
{ {
(void)ctrl; (void)ctrl;
(void)keyspec; (void)keyspec;
(void)options; (void)options;
(void)stats;
*r_keyblock = NULL; *r_keyblock = NULL;
*r_data = NULL; *r_data = NULL;

View File

@ -906,7 +906,7 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock)
/* We do not have an export fucntion which allows to pass a /* We do not have an export fucntion which allows to pass a
keyblock, thus we need to search the key again. */ keyblock, thus we need to search the key again. */
err = export_pubkey_buffer (ctrl, hexfpr, err = export_pubkey_buffer (ctrl, hexfpr,
EXPORT_DANE_FORMAT, EXPORT_DANE_FORMAT, NULL,
&dummy_keyblock, &data, &datalen); &dummy_keyblock, &data, &datalen);
release_kbnode (dummy_keyblock); release_kbnode (dummy_keyblock);
if (!err) if (!err)

View File

@ -1796,6 +1796,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs,
err = export_pubkey_buffer (ctrl, kspec->d, err = export_pubkey_buffer (ctrl, kspec->d,
opt.keyserver_options.export_options, opt.keyserver_options.export_options,
NULL,
&keyblock, &data, &datalen); &keyblock, &data, &datalen);
if (err) if (err)
log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err)); log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err));

View File

@ -339,16 +339,25 @@ int collapse_uids( KBNODE *keyblock );
/*-- export.c --*/ /*-- export.c --*/
struct export_stats_s;
typedef struct export_stats_s *export_stats_t;
export_stats_t export_new_stats (void);
void export_release_stats (export_stats_t stats);
void export_print_stats (export_stats_t stats);
int parse_export_options(char *str,unsigned int *options,int noisy); int parse_export_options(char *str,unsigned int *options,int noisy);
int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options );
int export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int export_pubkeys (ctrl_t ctrl, strlist_t users, unsigned int options,
kbnode_t *keyblock_out, unsigned int options ); export_stats_t stats);
int export_seckeys (ctrl_t ctrl, strlist_t users, export_stats_t stats);
int export_secsubkeys (ctrl_t ctrl, strlist_t users, export_stats_t stats);
gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec,
unsigned int options, unsigned int options,
export_stats_t stats,
kbnode_t *r_keyblock, kbnode_t *r_keyblock,
void **r_data, size_t *r_datalen); void **r_data, size_t *r_datalen);
int export_seckeys (ctrl_t ctrl, strlist_t users);
int export_secsubkeys (ctrl_t ctrl, strlist_t users);
/*-- dearmor.c --*/ /*-- dearmor.c --*/
int dearmor_file( const char *fname ); int dearmor_file( const char *fname );

View File

@ -418,11 +418,13 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid,
gpg_error_t gpg_error_t
export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options,
export_stats_t stats,
kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) kbnode_t *r_keyblock, void **r_data, size_t *r_datalen)
{ {
(void)ctrl; (void)ctrl;
(void)keyspec; (void)keyspec;
(void)options; (void)options;
(void)stats;
*r_keyblock = NULL; *r_keyblock = NULL;
*r_data = NULL; *r_data = NULL;