diff --git a/README b/README
index 080d6bcd..b244fc55 100644
--- a/README
+++ b/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.
diff --git a/configure.in b/configure.in
index 41a8b18c..710b0434 100644
--- a/configure.in
+++ b/configure.in
@@ -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)
diff --git a/gpgme/context.h b/gpgme/context.h
index 6bba5372..86554e04 100644
--- a/gpgme/context.h
+++ b/gpgme/context.h
@@ -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;
};
diff --git a/gpgme/genkey.c b/gpgme/genkey.c
index d0abae99..b002372c 100644
--- a/gpgme/genkey.c
+++ b/gpgme/genkey.c
@@ -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 );
diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c
index 23eef199..97c82504 100644
--- a/gpgme/gpgme.c
+++ b/gpgme/gpgme.c
@@ -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:
+ *
+ * typedef void (*GpgmeProgressCb) (void*cb_value,
+ * const char *what, int type,
+ * int curretn, int total);
+ *
+ * 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;
+}
diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h
index e4f1e95a..7c0e4c47 100644
--- a/gpgme/gpgme.h
+++ b/gpgme/gpgme.h
@@ -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,19 +99,24 @@ 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 */
GpgmeError gpgme_new (GpgmeCtx *r_ctx);
-void gpgme_release ( GpgmeCtx c );
-GpgmeCtx gpgme_wait ( GpgmeCtx c, int hang );
+void gpgme_release (GpgmeCtx c);
+GpgmeCtx gpgme_wait (GpgmeCtx c, int hang);
-char *gpgme_get_notation ( GpgmeCtx c );
-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 );
+char *gpgme_get_notation (GpgmeCtx c);
+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);
diff --git a/gpgme/key.c b/gpgme/key.c
index c58e859d..909b5cff 100644
--- a/gpgme/key.c
+++ b/gpgme/key.c
@@ -45,16 +45,43 @@ _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);
- for ( u = key->uids; u; u = u2 ) {
+ 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, "\n"
" \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, " \n");
- /* No the user IDs */
+ /* Now the user IDs */
for ( u = key->uids; u; u = u->next ) {
_gpgme_data_append_string (d, " \n");
add_tag_and_string ( d, "raw", u->name );
add_user_id ( d, u->name );
_gpgme_data_append_string (d, " \n");
}
- _gpgme_data_append_string (d, " \n");
- _gpgme_data_append_string (d, " \n");
+ for (k=key->keys.next; k; k = k->next ) {
+ _gpgme_data_append_string (d, " \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, " \n");
+ }
_gpgme_data_append_string ( d, "\n" );
return _gpgme_data_release_and_return_string (d);
@@ -285,3 +321,5 @@ gpgme_key_get_as_xml ( GpgmeKey key )
+
+
diff --git a/gpgme/key.h b/gpgme/key.h
index f95c9092..8c68779f 100644
--- a/gpgme/key.h
+++ b/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 );
diff --git a/gpgme/keylist.c b/gpgme/keylist.c
index cbd7cb48..5cb124e4 100644
--- a/gpgme/keylist.c
+++ b/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 */
+ 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,13 +212,11 @@ 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);
- }
+ if ( _gpgme_key_append_name ( key, p) )
+ ctx->out_of_core = 1;
+ else {
+ if (trust_info)
+ set_mainkey_trust_info (key, trust_info);
}
break;
case 11: /* signature class */
@@ -212,6 +226,43 @@ keylist_colon_handler ( GpgmeCtx ctx, char *line )
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;
+ case 12:
+ pend = NULL; /* we can stop here */
+ break;
+ }
+ }
else if ( rectype == RT_UID ) {
switch (field) {
case 2: /* trust info */
@@ -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 )
-
-
-
-
-
-
-
-
-
diff --git a/gpgme/w32-io.c b/gpgme/w32-io.c
index 47736224..237c0386 100644
--- a/gpgme/w32-io.c
+++ b/gpgme/w32-io.c
@@ -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++;
}
diff --git a/gpgme/wait.c b/gpgme/wait.c
index b024b092..edd492ee 100644
--- a/gpgme/wait.c
+++ b/gpgme/wait.c
@@ -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;
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3f5f2349..de7a0456 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
diff --git a/tests/t-genkey.c b/tests/t-genkey.c
index 710dfa0b..d22b95ea 100644
--- a/tests/t-genkey.c
+++ b/tests/t-genkey.c
@@ -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 = "\n"
"Key-Type: DSA\n"
"Key-Length: 1024\n"