Add progress CB and subkey listing
This commit is contained in:
parent
a92ecd4470
commit
6b4ca13dd4
1
README
1
README
@ -12,6 +12,7 @@ ftp.gnupg.org/pub/gcrypt/alpha/gnupg/gnupg-1.1.2.tar.gz) and install
|
||||
the agent from the agent subdirectory or use the new
|
||||
gpgme_set_passphrase_cb()
|
||||
|
||||
|
||||
Please subscribe to the gnupg-devel@gnupg.org mailing list if you want
|
||||
to do serious work.
|
||||
|
||||
|
@ -13,10 +13,10 @@ AM_MAINTAINER_MODE
|
||||
# AGE, set REVISION to 0.
|
||||
# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
|
||||
# CURRENT, set AGE and REVISION to 0.
|
||||
AM_INIT_AUTOMAKE(gpgme,0.1.2)
|
||||
LIBGPGME_LT_CURRENT=0
|
||||
LIBGPGME_LT_AGE=0
|
||||
LIBGPGME_LT_REVISION=3
|
||||
AM_INIT_AUTOMAKE(gpgme,0.1.3)
|
||||
LIBGPGME_LT_CURRENT=1
|
||||
LIBGPGME_LT_AGE=1
|
||||
LIBGPGME_LT_REVISION=0
|
||||
##############################################
|
||||
|
||||
AC_SUBST(LIBGPGME_LT_CURRENT)
|
||||
|
@ -72,6 +72,9 @@ struct gpgme_context_s {
|
||||
GpgmePassphraseCb passphrase_cb;
|
||||
void *passphrase_cb_value;
|
||||
|
||||
GpgmeProgressCb progress_cb;
|
||||
void *progress_cb_value;
|
||||
|
||||
GpgmeData help_data_1;
|
||||
};
|
||||
|
||||
|
@ -31,8 +31,33 @@
|
||||
static void
|
||||
genkey_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
|
||||
{
|
||||
if ( code == STATUS_PROGRESS )
|
||||
if ( code == STATUS_PROGRESS && *args ) {
|
||||
if (ctx->progress_cb) {
|
||||
char *p;
|
||||
int type=0, current=0, total=0;
|
||||
|
||||
if ( (p = strchr (args, ' ')) ) {
|
||||
*p++ = 0;
|
||||
if (*p) {
|
||||
type = *(byte*)p;
|
||||
if ( (p = strchr (p+1, ' ')) ) {
|
||||
*p++ = 0;
|
||||
if (*p) {
|
||||
current = atoi (p);
|
||||
if ( (p = strchr (p+1, ' ')) ) {
|
||||
*p++ = 0;
|
||||
total = atoi (p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( type != 'X' )
|
||||
ctx->progress_cb ( ctx->progress_cb_value, args, type,
|
||||
current, total );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf (stderr, "genkey_status: code=%d args=`%s'\n",
|
||||
code, args );
|
||||
|
@ -183,7 +183,28 @@ gpgme_set_passphrase_cb ( GpgmeCtx c, GpgmePassphraseCb cb, void *cb_value )
|
||||
c->passphrase_cb_value = cb_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_set_pprogress_cb:
|
||||
* @c: the context
|
||||
* @cb: A callback function
|
||||
* @cb_value: The value passed to the callback function
|
||||
*
|
||||
* This function sets a callback function to be used as a progress indicator.
|
||||
*
|
||||
* The callback function is defined as:
|
||||
* <literal>
|
||||
* typedef void (*GpgmeProgressCb) (void*cb_value,
|
||||
* const char *what, int type,
|
||||
* int curretn, int total);
|
||||
* </literal>
|
||||
* For details on the progress events, see the entry for the PROGRESS
|
||||
* status in the file doc/DETAILS of the GnuPG distribution.
|
||||
**/
|
||||
void
|
||||
gpgme_set_progress_cb ( GpgmeCtx c, GpgmeProgressCb cb, void *cb_value )
|
||||
{
|
||||
c->progress_cb = cb;
|
||||
c->progress_cb_value = cb_value;
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ extern "C" {
|
||||
* let autoconf (using the AM_PATH_GPGME macro) check that this
|
||||
* header matches the installed library.
|
||||
* Warning: Do not edit the next line. configure will do that for you! */
|
||||
#define GPGME_VERSION "0.1.2"
|
||||
#define GPGME_VERSION "0.1.3"
|
||||
|
||||
|
||||
|
||||
@ -99,7 +99,11 @@ typedef enum {
|
||||
} GpgmeSigMode;
|
||||
|
||||
|
||||
typedef const char *(*GpgmePassphraseCb)(void*, const char *desc, void *r_hd);
|
||||
typedef const char *(*GpgmePassphraseCb)(void*,
|
||||
const char *desc, void *r_hd);
|
||||
typedef void (*GpgmeProgressCb)(void *opaque,
|
||||
const char *what,
|
||||
int type, int current, int total );
|
||||
|
||||
|
||||
/* Context management */
|
||||
@ -112,6 +116,7 @@ void gpgme_set_armor ( GpgmeCtx c, int yes );
|
||||
void gpgme_set_textmode (GpgmeCtx c, int yes);
|
||||
void gpgme_set_passphrase_cb (GpgmeCtx c,
|
||||
GpgmePassphraseCb cb, void *cb_value);
|
||||
void gpgme_set_progress_cb (GpgmeCtx c, GpgmeProgressCb cb, void *cb_value);
|
||||
|
||||
|
||||
|
||||
|
58
gpgme/key.c
58
gpgme/key.c
@ -45,15 +45,42 @@ _gpgme_key_new( GpgmeKey *r_key )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct subkey_s *
|
||||
_gpgme_key_add_subkey (GpgmeKey key)
|
||||
{
|
||||
struct subkey_s *k, *kk;
|
||||
|
||||
k = xtrycalloc (1, sizeof *k);
|
||||
if (!k)
|
||||
return NULL;
|
||||
|
||||
if( !(kk=key->keys.next) )
|
||||
key->keys.next = k;
|
||||
else {
|
||||
while ( kk->next )
|
||||
kk = kk->next;
|
||||
kk->next = k;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_key_release ( GpgmeKey key )
|
||||
{
|
||||
struct user_id_s *u, *u2;
|
||||
struct subkey_s *k, *k2;
|
||||
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
xfree (key->fingerprint);
|
||||
xfree (key->keys.fingerprint);
|
||||
for (k = key->keys.next; k; k = k2 ) {
|
||||
k2 = k->next;
|
||||
xfree (k->fingerprint);
|
||||
xfree (k);
|
||||
}
|
||||
for (u = key->uids; u; u = u2 ) {
|
||||
u2 = u->next;
|
||||
xfree (u);
|
||||
@ -250,6 +277,7 @@ gpgme_key_get_as_xml ( GpgmeKey key )
|
||||
{
|
||||
GpgmeData d;
|
||||
struct user_id_s *u;
|
||||
struct subkey_s *k;
|
||||
|
||||
if ( !key )
|
||||
return NULL;
|
||||
@ -259,25 +287,33 @@ gpgme_key_get_as_xml ( GpgmeKey key )
|
||||
|
||||
_gpgme_data_append_string ( d, "<GnupgKeyblock>\n"
|
||||
" <mainkey>\n" );
|
||||
add_tag_and_string (d, "keyid", key->keyid );
|
||||
if (key)
|
||||
add_tag_and_string (d, "fpr", key->fingerprint );
|
||||
add_tag_and_uint (d, "algo", key->key_algo );
|
||||
add_tag_and_uint (d, "len", key->key_len );
|
||||
add_tag_and_time (d, "created", key->timestamp );
|
||||
add_tag_and_string (d, "keyid", key->keys.keyid );
|
||||
if (key->keys.fingerprint)
|
||||
add_tag_and_string (d, "fpr", key->keys.fingerprint );
|
||||
add_tag_and_uint (d, "algo", key->keys.key_algo );
|
||||
add_tag_and_uint (d, "len", key->keys.key_len );
|
||||
add_tag_and_time (d, "created", key->keys.timestamp );
|
||||
/*add_tag_and_time (d, "expires", key->expires );*/
|
||||
_gpgme_data_append_string (d, " </mainkey>\n");
|
||||
|
||||
/* No the user IDs */
|
||||
/* Now the user IDs */
|
||||
for ( u = key->uids; u; u = u->next ) {
|
||||
_gpgme_data_append_string (d, " <userid>\n");
|
||||
add_tag_and_string ( d, "raw", u->name );
|
||||
add_user_id ( d, u->name );
|
||||
_gpgme_data_append_string (d, " </userid>\n");
|
||||
}
|
||||
_gpgme_data_append_string (d, " <subkey>\n");
|
||||
_gpgme_data_append_string (d, " </subkey>\n");
|
||||
|
||||
for (k=key->keys.next; k; k = k->next ) {
|
||||
_gpgme_data_append_string (d, " <subkey>\n");
|
||||
add_tag_and_string (d, "keyid", k->keyid );
|
||||
if (k->fingerprint)
|
||||
add_tag_and_string (d, "fpr", k->fingerprint );
|
||||
add_tag_and_uint (d, "algo", k->key_algo );
|
||||
add_tag_and_uint (d, "len", k->key_len );
|
||||
add_tag_and_time (d, "created", k->timestamp );
|
||||
_gpgme_data_append_string (d, " </subkey>\n");
|
||||
}
|
||||
_gpgme_data_append_string ( d, "</GnupgKeyblock>\n" );
|
||||
|
||||
return _gpgme_data_release_and_return_string (d);
|
||||
@ -285,3 +321,5 @@ gpgme_key_get_as_xml ( GpgmeKey key )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
16
gpgme/key.h
16
gpgme/key.h
@ -25,8 +25,8 @@
|
||||
#include "types.h"
|
||||
#include "context.h"
|
||||
|
||||
|
||||
struct gpgme_key_s {
|
||||
struct subkey_s {
|
||||
struct subkey_s *next;
|
||||
struct {
|
||||
unsigned int revoked:1 ;
|
||||
unsigned int expired:1 ;
|
||||
@ -37,11 +37,19 @@ struct gpgme_key_s {
|
||||
char keyid[16+1];
|
||||
char *fingerprint; /* malloced hex digits */
|
||||
time_t timestamp; /* -1 for invalid, 0 for not available */
|
||||
struct user_id_s *uids;
|
||||
|
||||
};
|
||||
|
||||
struct gpgme_key_s {
|
||||
struct {
|
||||
unsigned int revoked:1 ;
|
||||
unsigned int expired:1 ;
|
||||
unsigned int disabled:1 ;
|
||||
} gloflags;
|
||||
struct subkey_s keys;
|
||||
struct user_id_s *uids;
|
||||
};
|
||||
|
||||
struct subkey_s *_gpgme_key_add_subkey (GpgmeKey key);
|
||||
GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );
|
||||
|
||||
|
||||
|
104
gpgme/keylist.c
104
gpgme/keylist.c
@ -91,14 +91,14 @@ parse_timestamp ( char *p )
|
||||
|
||||
|
||||
static void
|
||||
set_trust_info ( GpgmeKey key, const char *s )
|
||||
set_mainkey_trust_info ( GpgmeKey key, const char *s )
|
||||
{
|
||||
/* look at letters and stop at the first digit */
|
||||
for (; *s && !my_isdigit (*s); s++ ) {
|
||||
switch (*s) {
|
||||
case 'e': key->flags.expired = 1; break;
|
||||
case 'r': key->flags.revoked = 1; break;
|
||||
case 'd': key->flags.disabled = 1; break;
|
||||
case 'e': key->keys.flags.expired = 1; break;
|
||||
case 'r': key->keys.flags.revoked = 1; break;
|
||||
case 'd': key->keys.flags.disabled = 1; break;
|
||||
case 'n': key->uids->validity = 1; break;
|
||||
case 'm': key->uids->validity = 2; break;
|
||||
case 'f': key->uids->validity = 3; break;
|
||||
@ -107,6 +107,19 @@ set_trust_info ( GpgmeKey key, const char *s )
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_subkey_trust_info ( struct subkey_s *k, const char *s )
|
||||
{
|
||||
/* look at letters and stop at the first digit */
|
||||
for (; *s && !my_isdigit (*s); s++ ) {
|
||||
switch (*s) {
|
||||
case 'e': k->flags.expired = 1; break;
|
||||
case 'r': k->flags.revoked = 1; break;
|
||||
case 'd': k->flags.disabled = 1; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Note: we are allowed to modify line */
|
||||
static void
|
||||
@ -120,15 +133,13 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
|
||||
GpgmeKey key = ctx->tmp_key;
|
||||
int i;
|
||||
const char *trust_info = NULL;
|
||||
|
||||
struct subkey_s *sk = NULL;
|
||||
|
||||
if ( ctx->out_of_core )
|
||||
return;
|
||||
if (!line)
|
||||
return; /* EOF */
|
||||
|
||||
/*fprintf (stderr, "line=`%s'\n", line );*/
|
||||
|
||||
for (p = line; p; p = pend) {
|
||||
field++;
|
||||
pend = strchr (p, ':');
|
||||
@ -142,8 +153,14 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
|
||||
rectype = RT_UID;
|
||||
key = ctx->tmp_key;
|
||||
}
|
||||
else if ( !strcmp ( p, "sub" ) )
|
||||
else if ( !strcmp ( p, "sub" ) && key ) {
|
||||
/* start a new subkey */
|
||||
rectype = RT_SUB;
|
||||
if ( !(sk = _gpgme_key_add_subkey (key)) ) {
|
||||
ctx->out_of_core=1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ( !strcmp ( p, "pub" ) ) {
|
||||
/* start a new keyblock */
|
||||
if ( _gpgme_key_new ( &key ) ) {
|
||||
@ -166,28 +183,27 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
|
||||
rectype = RT_NONE;
|
||||
|
||||
}
|
||||
else if ( rectype == RT_PUB /*|| rectype == RT_SUB*/ ) {
|
||||
else if ( rectype == RT_PUB ) {
|
||||
switch (field) {
|
||||
case 2: /* trust info */
|
||||
if ( rectype == RT_PUB )
|
||||
trust_info = p; /*save for later */
|
||||
break;
|
||||
case 3: /* key length */
|
||||
i = atoi (p);
|
||||
if ( i > 1 ) /* ignore invalid values */
|
||||
key->key_len = i;
|
||||
key->keys.key_len = i;
|
||||
break;
|
||||
case 4: /* pubkey algo */
|
||||
i = atoi (p);
|
||||
if ( i > 1 && i < 128 )
|
||||
key->key_algo = i;
|
||||
key->keys.key_algo = i;
|
||||
break;
|
||||
case 5: /* long keyid */
|
||||
if ( strlen (p) == DIM(key->keyid)-1 )
|
||||
strcpy (key->keyid, p);
|
||||
if ( strlen (p) == DIM(key->keys.keyid)-1 )
|
||||
strcpy (key->keys.keyid, p);
|
||||
break;
|
||||
case 6: /* timestamp (1998-02-28) */
|
||||
key->timestamp = parse_timestamp (p);
|
||||
key->keys.timestamp = parse_timestamp (p);
|
||||
break;
|
||||
case 7: /* valid for n days */
|
||||
break;
|
||||
@ -196,14 +212,49 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
|
||||
case 9: /* ownertrust */
|
||||
break;
|
||||
case 10: /* This is the first name listed */
|
||||
if ( rectype == RT_PUB ) {
|
||||
if ( _gpgme_key_append_name ( key, p) )
|
||||
ctx->out_of_core = 1;
|
||||
else {
|
||||
if (trust_info)
|
||||
set_trust_info (key, trust_info);
|
||||
set_mainkey_trust_info (key, trust_info);
|
||||
}
|
||||
break;
|
||||
case 11: /* signature class */
|
||||
break;
|
||||
case 12:
|
||||
pend = NULL; /* we can stop here */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( rectype == RT_SUB && sk ) {
|
||||
switch (field) {
|
||||
case 2: /* trust info */
|
||||
set_subkey_trust_info ( sk, p);
|
||||
break;
|
||||
case 3: /* key length */
|
||||
i = atoi (p);
|
||||
if ( i > 1 ) /* ignore invalid values */
|
||||
sk->key_len = i;
|
||||
break;
|
||||
case 4: /* pubkey algo */
|
||||
i = atoi (p);
|
||||
if ( i > 1 && i < 128 )
|
||||
sk->key_algo = i;
|
||||
break;
|
||||
case 5: /* long keyid */
|
||||
if ( strlen (p) == DIM(sk->keyid)-1 )
|
||||
strcpy (sk->keyid, p);
|
||||
break;
|
||||
case 6: /* timestamp (1998-02-28) */
|
||||
sk->timestamp = parse_timestamp (p);
|
||||
break;
|
||||
case 7: /* valid for n days */
|
||||
break;
|
||||
case 8: /* reserved (LID) */
|
||||
break;
|
||||
case 9: /* ownertrust */
|
||||
break;
|
||||
case 10:/* user ID n/a for a subkey */
|
||||
break;
|
||||
case 11: /* signature class */
|
||||
break;
|
||||
@ -222,7 +273,7 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
|
||||
ctx->out_of_core = 1;
|
||||
else {
|
||||
if (trust_info)
|
||||
set_trust_info (key, trust_info);
|
||||
set_mainkey_trust_info (key, trust_info);
|
||||
}
|
||||
pend = NULL; /* we can stop here */
|
||||
break;
|
||||
@ -231,9 +282,9 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
|
||||
else if ( rectype == RT_FPR ) {
|
||||
switch (field) {
|
||||
case 10: /* fingerprint (take only the first one)*/
|
||||
if ( !key->fingerprint && *p ) {
|
||||
key->fingerprint = xtrystrdup (p);
|
||||
if ( !key->fingerprint )
|
||||
if ( !key->keys.fingerprint && *p ) {
|
||||
key->keys.fingerprint = xtrystrdup (p);
|
||||
if ( !key->keys.fingerprint )
|
||||
ctx->out_of_core = 1;
|
||||
}
|
||||
pend = NULL; /* that is all we want */
|
||||
@ -266,7 +317,7 @@ finish_key ( GpgmeCtx ctx )
|
||||
}
|
||||
q->key = key;
|
||||
q->next = NULL;
|
||||
/* fixme: lock queue */
|
||||
/* fixme: lock queue. Use a tail pointer? */
|
||||
if ( !(q2 = ctx->key_queue) )
|
||||
ctx->key_queue = q;
|
||||
else {
|
||||
@ -373,12 +424,3 @@ gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -559,8 +559,8 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
||||
(int)GetLastError ());
|
||||
}
|
||||
else if ( navail ) {
|
||||
fprintf (stderr, "** fd %d has %d bytes to read\n",
|
||||
fds[i].fd, navail );
|
||||
/*fprintf (stderr, "** fd %d has %d bytes to read\n",
|
||||
fds[i].fd, navail );*/
|
||||
fds[i].signaled = 1;
|
||||
count++;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ do_select ( void )
|
||||
if ( n <= 0 )
|
||||
return 0; /* error or timeout */
|
||||
|
||||
for (i=0; i < fd_table_size /*&& n*/; i++ ) {
|
||||
for (i=0; i < fd_table_size && n; i++ ) {
|
||||
if ( fd_table[i].fd != -1 && fd_table[i].signaled
|
||||
&& !fd_table[i].frozen ) {
|
||||
q = fd_table[i].opaque;
|
||||
@ -328,7 +328,7 @@ _gpgme_freeze_fd ( int fd )
|
||||
for (i=0; i < fd_table_size; i++ ) {
|
||||
if ( fd_table[i].fd == fd ) {
|
||||
fd_table[i].frozen = 1;
|
||||
fprintf (stderr, "** FD %d frozen\n", fd );
|
||||
/*fprintf (stderr, "** FD %d frozen\n", fd );*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -344,7 +344,7 @@ _gpgme_thaw_fd ( int fd )
|
||||
for (i=0; i < fd_table_size; i++ ) {
|
||||
if ( fd_table[i].fd == fd ) {
|
||||
fd_table[i].frozen = 0;
|
||||
fprintf (stderr, "** FD %d thawed\n", fd );
|
||||
/*fprintf (stderr, "** FD %d thawed\n", fd );*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=.
|
||||
|
||||
TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist t-export t-import \
|
||||
t-genkey
|
||||
TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist t-export t-import
|
||||
|
||||
|
||||
EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \
|
||||
pubkey-1.asc seckey-1.asc
|
||||
@ -13,7 +13,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
|
||||
INCLUDES =
|
||||
LDADD = ../gpgme/libgpgme.la
|
||||
|
||||
noinst_PROGRAMS = $(TESTS)
|
||||
# We don't run t-genkey in the test suite, because it taes too long
|
||||
noinst_PROGRAMS = $(TESTS) t-genkey
|
||||
|
||||
distclean-local:
|
||||
$(srcdir)/mkdemodirs --clean
|
||||
|
@ -32,6 +32,13 @@
|
||||
} while(0)
|
||||
|
||||
|
||||
static void
|
||||
progress ( void *self, const char *what, int type, int current, int total)
|
||||
{
|
||||
fprintf (stderr, "progress `%s' %d %d %d\n", what, type, current, total);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv )
|
||||
{
|
||||
@ -45,6 +52,8 @@ main (int argc, char **argv )
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
|
||||
gpgme_set_progress_cb (ctx, progress, NULL);
|
||||
|
||||
format = "<GnupgKeyParms format=\"internal\">\n"
|
||||
"Key-Type: DSA\n"
|
||||
"Key-Length: 1024\n"
|
||||
|
Loading…
Reference in New Issue
Block a user