More changes and and some new functions

This commit is contained in:
Werner Koch 2001-01-08 20:40:25 +00:00
parent c74adbc096
commit d6cd1f97ca
15 changed files with 736 additions and 93 deletions

View File

@ -0,0 +1,3 @@
2001-01-05 Werner Koch <wk@gnupg.org>
* data.c (gpgme_data_rewind): Allow to rewind data_type_none.

View File

@ -23,6 +23,7 @@ libgpgme_la_SOURCES = \
sign.c \ sign.c \
key.c key.h \ key.c key.h \
keylist.c \ keylist.c \
trustlist.c \
import.c \ import.c \
export.c \ export.c \
genkey.c \ genkey.c \

View File

@ -37,6 +37,10 @@ struct key_queue_item_s {
struct key_queue_item_s *next; struct key_queue_item_s *next;
GpgmeKey key; GpgmeKey key;
}; };
struct trust_queue_item_s {
struct trust_queue_item_s *next;
GpgmeTrustItem item;
};
/* Currently we need it at several places, so we put the definition /* Currently we need it at several places, so we put the definition
@ -57,6 +61,7 @@ struct gpgme_context_s {
int verbosity; /* level of verbosity to use */ int verbosity; /* level of verbosity to use */
int use_armor; int use_armor;
int use_textmode; int use_textmode;
int keylist_mode;
ResultType result_type; ResultType result_type;
union { union {
@ -70,6 +75,7 @@ struct gpgme_context_s {
GpgmeKey tmp_key; /* used by keylist.c */ GpgmeKey tmp_key; /* used by keylist.c */
volatile int key_cond; /* something new is available */ volatile int key_cond; /* something new is available */
struct key_queue_item_s *key_queue; struct key_queue_item_s *key_queue;
struct trust_queue_item_s *trust_queue;
GpgmePassphraseCb passphrase_cb; GpgmePassphraseCb passphrase_cb;
void *passphrase_cb_value; void *passphrase_cb_value;
@ -101,6 +107,9 @@ struct user_id_s {
struct user_id_s *next; struct user_id_s *next;
int validity; /* 0 = undefined, 1 = not, 2 = marginal, int validity; /* 0 = undefined, 1 = not, 2 = marginal,
3 = full, 4 = ultimate */ 3 = full, 4 = ultimate */
const char *name_part; /* all 3 point into strings behind name */
const char *email_part; /* or to read-only strings */
const char *comment_part;
char name[1]; char name[1];
}; };

View File

@ -410,7 +410,8 @@ gpgme_data_rewind ( GpgmeData dh )
if ( !dh ) if ( !dh )
return mk_error (Invalid_Value); return mk_error (Invalid_Value);
if (dh->type == GPGME_DATA_TYPE_MEM ) { if ( dh->type == GPGME_DATA_TYPE_NONE
|| dh->type == GPGME_DATA_TYPE_MEM ) {
dh->readpos = 0; dh->readpos = 0;
} }
else if (dh->type == GPGME_DATA_TYPE_CB) { else if (dh->type == GPGME_DATA_TYPE_CB) {

View File

@ -164,6 +164,24 @@ gpgme_set_textmode ( GpgmeCtx c, int yes )
c->use_textmode = yes; c->use_textmode = yes;
} }
/**
* gpgme_set_keylist_mode:
* @c: the context
* @mode: listing mode
*
* This function changes the default behaviour of the keylisting functions.
* Defines values for @mode are: %0 = normal, %1 = fast listing without
* information about key validity.
**/
void
gpgme_set_keylist_mode ( GpgmeCtx c, int mode )
{
if (c)
return;
c->keylist_mode = mode;
}
/** /**
* gpgme_set_passphrase_cb: * gpgme_set_passphrase_cb:
* @c: the context * @c: the context

View File

@ -58,6 +58,9 @@ typedef struct gpgme_recipients_s *GpgmeRecipients;
struct gpgme_key_s; struct gpgme_key_s;
typedef struct gpgme_key_s *GpgmeKey; typedef struct gpgme_key_s *GpgmeKey;
struct gpgme_trust_item_s;
typedef struct gpgme_trust_item_s *GpgmeTrustItem;
typedef enum { typedef enum {
GPGME_EOF = -1, GPGME_EOF = -1,
@ -107,6 +110,23 @@ typedef enum {
GPGME_SIG_MODE_CLEAR = 2 GPGME_SIG_MODE_CLEAR = 2
} GpgmeSigMode; } GpgmeSigMode;
typedef enum {
GPGME_ATTR_KEYID = 1,
GPGME_ATTR_FPR = 2,
GPGME_ATTR_ALGO = 3,
GPGME_ATTR_LEN = 4,
GPGME_ATTR_CREATED = 5,
GPGME_ATTR_EXPIRE = 6,
GPGME_ATTR_OTRUST = 7,
GPGME_ATTR_USERID = 8,
GPGME_ATTR_NAME = 9,
GPGME_ATTR_EMAIL = 10,
GPGME_ATTR_COMMENT = 11,
GPGME_ATTR_VALIDITY= 12,
GPGME_ATTR_LEVEL = 13,
GPGME_ATTR_TYPE = 14
} GpgmeAttr;
typedef const char *(*GpgmePassphraseCb)(void*, typedef const char *(*GpgmePassphraseCb)(void*,
const char *desc, void *r_hd); const char *desc, void *r_hd);
@ -124,6 +144,7 @@ GpgmeCtx gpgme_wait (GpgmeCtx c, int hang);
char *gpgme_get_notation (GpgmeCtx c); char *gpgme_get_notation (GpgmeCtx c);
void gpgme_set_armor (GpgmeCtx c, int yes); void gpgme_set_armor (GpgmeCtx c, int yes);
void gpgme_set_textmode (GpgmeCtx c, int yes); void gpgme_set_textmode (GpgmeCtx c, int yes);
void gpgme_set_keylist_mode ( GpgmeCtx c, int mode );
void gpgme_set_passphrase_cb (GpgmeCtx c, void gpgme_set_passphrase_cb (GpgmeCtx c,
GpgmePassphraseCb cb, void *cb_value); GpgmePassphraseCb cb, void *cb_value);
void gpgme_set_progress_cb (GpgmeCtx c, GpgmeProgressCb cb, void *cb_value); void gpgme_set_progress_cb (GpgmeCtx c, GpgmeProgressCb cb, void *cb_value);
@ -166,8 +187,21 @@ GpgmeError gpgme_data_write ( GpgmeData dh,
const char *buffer, size_t length ); const char *buffer, size_t length );
/* Key functions */ /* Key and trust functions */
char *gpgme_key_get_as_xml ( GpgmeKey key ); char *gpgme_key_get_as_xml ( GpgmeKey key );
const char *gpgme_key_get_string_attr ( GpgmeKey key, GpgmeAttr what,
const void *reserved, int idx );
unsigned long gpgme_key_get_ulong_attr ( GpgmeKey key, GpgmeAttr what,
const void *reserved, int idx );
void gpgme_trust_item_release ( GpgmeTrustItem item );
const char *gpgme_trust_item_get_string_attr ( GpgmeTrustItem item,
GpgmeAttr what,
const void *reserved, int idx );
int gpgme_trust_item_get_int_attr ( GpgmeTrustItem item, GpgmeAttr what,
const void *reserved, int idx );
/* Basic GnuPG functions */ /* Basic GnuPG functions */
@ -194,6 +228,10 @@ GpgmeError gpgme_op_genkey_start ( GpgmeCtx c, const char *parms,
GpgmeError gpgme_op_keylist_start ( GpgmeCtx c, GpgmeError gpgme_op_keylist_start ( GpgmeCtx c,
const char *pattern, int secret_only ); const char *pattern, int secret_only );
GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key ); GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key );
GpgmeError gpgme_op_trustlist_start ( GpgmeCtx c,
const char *pattern, int max_level );
GpgmeError gpgme_op_trustlist_next ( GpgmeCtx c, GpgmeTrustItem *r_item );
/* Convenience functions for normal usage */ /* Convenience functions for normal usage */
@ -215,7 +253,7 @@ GpgmeError gpgme_op_genkey ( GpgmeCtx c, const char *parms,
/* miscellaneous functions */ /* miscellaneous functions */
const char *gpgme_check_version ( const char *req_version ); const char *gpgme_check_version ( const char *req_version );
const char *gpgme_strerror (GpgmeError err); const char *gpgme_strerror (GpgmeError err);
const char *gpgme_get_prompt ( GpgmeCtx c, int which ); void gpgme_register_idle ( void (*fnc)(void) );
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -31,6 +31,23 @@
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' ) #define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
static const char *
pkalgo_to_string ( int algo )
{
switch (algo) {
case 1:
case 2:
case 3: return "RSA";
case 16:
case 20: return "ElG";
case 17: return "DSA";
default: return "Unknown";
}
}
GpgmeError GpgmeError
_gpgme_key_new( GpgmeKey *r_key ) _gpgme_key_new( GpgmeKey *r_key )
{ {
@ -88,6 +105,97 @@ _gpgme_key_release ( GpgmeKey key )
xfree (key); xfree (key);
} }
static char *
set_user_id_part ( char *tail, const char *buf, size_t len )
{
while ( len && (buf[len-1] == ' ' || buf[len-1] == '\t') )
len--;
for ( ; len; len--)
*tail++ = *buf++;
*tail++ = 0;
return tail;
}
static void
parse_user_id ( struct user_id_s *uid, char *tail )
{
const char *s, *start=NULL;
int in_name = 0;
int in_email = 0;
int in_comment = 0;
for (s=uid->name; *s; s++ ) {
if ( in_email ) {
if ( *s == '<' )
in_email++; /* not legal but anyway */
else if (*s== '>') {
if ( !--in_email ) {
if (!uid->email_part) {
uid->email_part = tail;
tail = set_user_id_part ( tail, start, s-start );
}
}
}
}
else if ( in_comment ) {
if ( *s == '(' )
in_comment++;
else if (*s== ')') {
if ( !--in_comment ) {
if (!uid->comment_part) {
uid->comment_part = tail;
tail = set_user_id_part ( tail, start, s-start );
}
}
}
}
else if ( *s == '<' ) {
if ( in_name ) {
if ( !uid->name_part ) {
uid->name_part = tail;
tail = set_user_id_part (tail, start, s-start );
}
in_name = 0;
}
in_email = 1;
start = s+1;
}
else if ( *s == '(' ) {
if ( in_name ) {
if ( !uid->name_part ) {
uid->name_part = tail;
tail = set_user_id_part (tail, start, s-start );
}
in_name = 0;
}
in_comment = 1;
start = s+1;
}
else if ( !in_name && *s != ' ' && *s != '\t' ) {
in_name = 1;
start = s;
}
}
if ( in_name ) {
if ( !uid->name_part ) {
uid->name_part = tail;
tail = set_user_id_part (tail, start, s-start );
}
}
/* let unused parts point to an EOS */
tail--;
if (!uid->name_part)
uid->name_part = tail;
if (!uid->email_part)
uid->email_part = tail;
if (!uid->comment_part)
uid->comment_part = tail;
}
/* /*
* Take a name from the --with-colon listing, remove certain escape sequences * Take a name from the --with-colon listing, remove certain escape sequences
* sequences and put it into the list of UIDs * sequences and put it into the list of UIDs
@ -99,12 +207,17 @@ _gpgme_key_append_name ( GpgmeKey key, const char *s )
char *d; char *d;
assert (key); assert (key);
/* we can malloc a buffer of the same length, because the converted /* we can malloc a buffer of the same length, because the
* string will never be larger */ * converted string will never be larger. Actually we allocate it
uid = xtrymalloc ( sizeof *uid + strlen (s) ); * twice the size, so that we are able to store the parsed stuff
* there too */
uid = xtrymalloc ( sizeof *uid + 2*strlen (s)+3 );
if ( !uid ) if ( !uid )
return mk_error (Out_Of_Core); return mk_error (Out_Of_Core);
uid->validity = 0; uid->validity = 0;
uid->name_part = NULL;
uid->email_part = NULL;
uid->comment_part = NULL;
d = uid->name; d = uid->name;
while ( *s ) { while ( *s ) {
@ -152,6 +265,8 @@ _gpgme_key_append_name ( GpgmeKey key, const char *s )
*d++ = *s++; *d++ = *s++;
} }
} }
*d++ = 0;
parse_user_id ( uid, d );
uid->next = key->uids; uid->next = key->uids;
key->uids = uid; key->uids = uid;
@ -183,76 +298,6 @@ add_tag_and_string ( GpgmeData d, const char *tag, const char *string )
add_ctag (d, tag); add_ctag (d, tag);
} }
static void
add_user_id_name ( GpgmeData d, const char *buf, size_t len )
{
while ( len && (buf[len-1] == ' ' || buf[len-1] == '\t') )
len--;
if (len) {
add_otag (d, "name" );
_gpgme_data_append_for_xml ( d, buf, len );
add_ctag (d, "name");
}
}
static void
add_user_id ( GpgmeData d, const char *string )
{
const char *s, *start=NULL;
int in_name = 0;
int in_email = 0;
int in_comment = 0;
for (s=string; *s; s++ ) {
if ( in_email ) {
if ( *s == '<' )
in_email++; /* not legal but anyway */
else if (*s== '>') {
if ( !--in_email ) {
_gpgme_data_append_for_xml ( d, start, s-start );
add_ctag (d, "email");
}
}
}
else if ( in_comment ) {
if ( *s == '(' )
in_comment++;
else if (*s== ')') {
if ( !--in_comment ) {
_gpgme_data_append_for_xml ( d, start, s-start );
add_ctag (d, "comment");
}
}
}
else if ( *s == '<' ) {
if ( in_name ) {
add_user_id_name (d, start, s-start );
in_name = 0;
}
in_email = 1;
add_otag ( d, "email" );
start = s+1;
}
else if ( *s == '(' ) {
if ( in_name ) {
add_user_id_name (d, start, s-start );
in_name = 0;
}
in_comment = 1;
add_otag ( d, "comment" );
start = s+1;
}
else if ( !in_name && *s != ' ' && *s != '\t' ) {
in_name = 1;
start = s;
}
}
if ( in_name )
add_user_id_name (d, start, s-start );
}
static void static void
add_tag_and_uint ( GpgmeData d, const char *tag, unsigned int val ) add_tag_and_uint ( GpgmeData d, const char *tag, unsigned int val )
{ {
@ -300,7 +345,12 @@ gpgme_key_get_as_xml ( GpgmeKey key )
for ( u = key->uids; u; u = u->next ) { for ( u = key->uids; u; u = u->next ) {
_gpgme_data_append_string (d, " <userid>\n"); _gpgme_data_append_string (d, " <userid>\n");
add_tag_and_string ( d, "raw", u->name ); add_tag_and_string ( d, "raw", u->name );
add_user_id ( d, u->name ); if ( *u->name_part )
add_tag_and_string ( d, "name", u->name_part );
if ( *u->email_part )
add_tag_and_string ( d, "email", u->email_part );
if ( *u->comment_part )
add_tag_and_string ( d, "comment", u->comment_part );
_gpgme_data_append_string (d, " </userid>\n"); _gpgme_data_append_string (d, " </userid>\n");
} }
@ -320,6 +370,95 @@ gpgme_key_get_as_xml ( GpgmeKey key )
} }
const char *
gpgme_key_get_string_attr ( GpgmeKey key, GpgmeAttr what,
const void *reserved, int idx )
{
const char *val = NULL;
struct user_id_s *u;
if (!key)
return NULL;
if (reserved)
return NULL;
if (idx < 0)
return NULL;
switch (what) {
case GPGME_ATTR_KEYID:
val = key->keys.keyid;
break;
case GPGME_ATTR_FPR:
val = key->keys.fingerprint;
break;
case GPGME_ATTR_ALGO:
val = pkalgo_to_string (key->keys.key_algo);
break;
case GPGME_ATTR_LEN:
case GPGME_ATTR_CREATED:
case GPGME_ATTR_EXPIRE:
break; /* use another get function */
case GPGME_ATTR_OTRUST:
val = "[fixme]";
break;
case GPGME_ATTR_USERID:
for (u=key->uids; u && idx; u=u->next, idx-- )
;
val = u? u->name : NULL;
break;
case GPGME_ATTR_NAME:
for (u=key->uids; u && idx; u=u->next, idx-- )
;
val = u? u->name_part : NULL;
break;
case GPGME_ATTR_EMAIL:
for (u=key->uids; u && idx; u=u->next, idx-- )
;
val = u? u->email_part : NULL;
break;
case GPGME_ATTR_COMMENT:
for (u=key->uids; u && idx; u=u->next, idx-- )
;
val = u? u->comment_part : NULL;
break;
case GPGME_ATTR_VALIDITY:
val = "[foxme]";
break;
case GPGME_ATTR_LEVEL: /* not used here */
case GPGME_ATTR_TYPE:
break;
}
return val;
}
unsigned long
gpgme_key_get_ulong_attr ( GpgmeKey key, GpgmeAttr what,
const void *reserved, int idx )
{
unsigned long val = 0;
if (!key)
return 0;
if (reserved)
return 0;
if (idx < 0)
return 0;
switch (what) {
case GPGME_ATTR_ALGO:
val = (unsigned long)key->keys.key_algo;
break;
case GPGME_ATTR_LEN:
val = (unsigned long)key->keys.key_len;
break;
case GPGME_ATTR_CREATED:
val = key->keys.timestamp < 0? 0L:(unsigned long)key->keys.timestamp;
break;
default:
break;
}
return val;
}

View File

@ -368,7 +368,8 @@ gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" ); _gpgme_gpg_add_arg ( c->gpg, "--verbose" );
_gpgme_gpg_add_arg ( c->gpg, "--with-colons" ); _gpgme_gpg_add_arg ( c->gpg, "--with-colons" );
_gpgme_gpg_add_arg ( c->gpg, "--with-fingerprint" ); _gpgme_gpg_add_arg ( c->gpg, "--with-fingerprint" );
/*_gpgme_gpg_add_arg ( c->gpg, "--fast-list-mode" );*/ if (c->keylist_mode == 1)
_gpgme_gpg_add_arg ( c->gpg, "--no-expensive-trust-checks" );
_gpgme_gpg_add_arg ( c->gpg, secret_only? _gpgme_gpg_add_arg ( c->gpg, secret_only?
"--list-secret-keys":"--list-keys" ); "--list-secret-keys":"--list-keys" );

View File

@ -229,7 +229,7 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
static fd_set readfds; static fd_set readfds;
static fd_set writefds; static fd_set writefds;
int any, i, max_fd, n, count; int any, i, max_fd, n, count;
struct timeval timeout = { 1, 0 }; /* Use a one second timeout */ struct timeval timeout = { 0, 50 }; /* Use a 50ms timeout */
FD_ZERO ( &readfds ); FD_ZERO ( &readfds );
FD_ZERO ( &writefds ); FD_ZERO ( &writefds );

View File

@ -57,6 +57,9 @@ gpgme_recipients_add_name (GpgmeRecipients rset, const char *name )
r = xtrymalloc ( sizeof *r + strlen (name) ); r = xtrymalloc ( sizeof *r + strlen (name) );
if (!r) if (!r)
return mk_error (Out_Of_Core); return mk_error (Out_Of_Core);
r->name_part = "";
r->email_part = "";
r->comment_part = "";
strcpy (r->name, name ); strcpy (r->name, name );
r->next = rset->list; r->next = rset->list;
rset->list = r; rset->list = r;

309
gpgme/trustlist.c Normal file
View File

@ -0,0 +1,309 @@
/* trustlist.c - key listing
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GPGME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
struct gpgme_trust_item_s {
int level;
char keyid[16+1];
int type;
char ot[2];
char val[2];
char *name;
};
static GpgmeTrustItem
trust_item_new (void)
{
GpgmeTrustItem item;
item = xtrycalloc (1, sizeof *item);
return item;
}
static void
trustlist_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
{
if ( ctx->out_of_core )
return;
switch (code) {
case STATUS_EOF:
break;
default:
break;
}
}
/*
* This handler is used to parse the output of --list-trust-path:
* Format:
* level:keyid:type:recno:ot:val:mc:cc:name:
* With TYPE = U for a user ID
* K for a key
* The RECNO is either the one of the dir record or the one of the uid record.
* OT is the the usual trust letter and only availabel on K lines.
* VAL is the calcualted validity
* MC is the marginal trust counter and only available on U lines
* CC is the same for the complete count
* NAME ist the username and only printed on U lines
*/
static void
trustlist_colon_handler ( GpgmeCtx ctx, char *line )
{
char *p, *pend;
int field = 0;
GpgmeTrustItem item = NULL;
struct trust_queue_item_s *q, *q2;
if ( ctx->out_of_core )
return;
if (!line)
return; /* EOF */
for (p = line; p; p = pend) {
field++;
pend = strchr (p, ':');
if (pend)
*pend++ = 0;
switch (field) {
case 1: /* level */
q = xtrymalloc ( sizeof *q );
if ( !q ) {
ctx->out_of_core = 1;
return;
}
q->next = NULL;
q->item = item = trust_item_new ();
if (!q->item) {
xfree (q);
ctx->out_of_core = 1;
return;
}
/* fixme: lock queue, keep a tail pointer */
if ( !(q2 = ctx->trust_queue) )
ctx->trust_queue = q;
else {
for ( ; q2->next; q2 = q2->next )
;
q2->next = q;
}
/* fixme: unlock queue */
item->level = atoi (p);
break;
case 2: /* long keyid */
if ( strlen (p) == DIM(item->keyid)-1 )
strcpy (item->keyid, p);
break;
case 3: /* type */
item->type = *p == 'K'? 1 : *p == 'U'? 2 : 0;
break;
case 5: /* owner trust */
item->ot[0] = *p;
item->ot[1] = 0;
break;
case 6: /* validity */
item->val[0] = *p;
item->val[1] = 0;
break;
case 10: /* user ID */
item->name = xtrystrdup (p);
if (!item->name)
ctx->out_of_core = 1;
break;
}
}
if (field)
ctx->key_cond = 1;
}
GpgmeError
gpgme_op_trustlist_start ( GpgmeCtx c, const char *pattern, int max_level )
{
GpgmeError rc = 0;
fail_on_pending_request( c );
if ( !pattern || !*pattern ) {
return mk_error (Invalid_Value);
}
c->pending = 1;
_gpgme_release_result (c);
c->out_of_core = 0;
if ( c->gpg ) {
_gpgme_gpg_release ( c->gpg );
c->gpg = NULL;
}
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, trustlist_status_handler, c );
rc = _gpgme_gpg_set_colon_line_handler ( c->gpg,
trustlist_colon_handler, c );
if (rc)
goto leave;
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--with-colons" );
_gpgme_gpg_add_arg ( c->gpg, "--list-trust-path" );
/* Tell the gpg object about the data */
_gpgme_gpg_add_arg ( c->gpg, "--" );
_gpgme_gpg_add_arg ( c->gpg, pattern );
/* and kick off the process */
rc = _gpgme_gpg_spawn ( c->gpg, c );
leave:
if (rc) {
c->pending = 0;
_gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
}
return rc;
}
GpgmeError
gpgme_op_trustlist_next ( GpgmeCtx c, GpgmeTrustItem *r_item )
{
struct trust_queue_item_s *q;
if (!r_item)
return mk_error (Invalid_Value);
*r_item = NULL;
if (!c)
return mk_error (Invalid_Value);
if ( !c->pending )
return mk_error (No_Request);
if ( c->out_of_core )
return mk_error (Out_Of_Core);
if ( !c->trust_queue ) {
_gpgme_wait_on_condition (c, 1, &c->key_cond );
if ( c->out_of_core )
return mk_error (Out_Of_Core);
if ( !c->key_cond )
return mk_error (EOF);
c->key_cond = 0;
assert ( c->trust_queue );
}
q = c->trust_queue;
c->trust_queue = q->next;
*r_item = q->item;
xfree (q);
return 0;
}
void
gpgme_trust_item_release ( GpgmeTrustItem item )
{
if (!item)
return;
xfree (item->name);
xfree (item);
}
const char *
gpgme_trust_item_get_string_attr ( GpgmeTrustItem item, GpgmeAttr what,
const void *reserved, int idx )
{
const char *val = NULL;
if (!item)
return NULL;
if (reserved)
return NULL;
if (idx)
return NULL;
switch (what) {
case GPGME_ATTR_KEYID:
val = item->keyid;
break;
case GPGME_ATTR_OTRUST:
val = item->ot;
break;
case GPGME_ATTR_VALIDITY:
val = item->val;
break;
case GPGME_ATTR_USERID:
val = item->name;
break;
default:
break;
}
return val;
}
int
gpgme_trust_item_get_int_attr ( GpgmeTrustItem item, GpgmeAttr what,
const void *reserved, int idx )
{
int val = 0;
if (!item)
return 0;
if (reserved)
return 0;
if (idx)
return 0;
switch (what) {
case GPGME_ATTR_LEVEL:
val = item->level;
break;
case GPGME_ATTR_TYPE:
val = item->type;
break;
default:
break;
}
return val;
}

View File

@ -62,7 +62,10 @@ struct wait_item_s {
static int fd_table_size; static int fd_table_size;
static struct io_select_fd_s *fd_table; static struct io_select_fd_s *fd_table;
static void (*idle_function) (void);
static int do_select ( void ); static int do_select ( void );
static void run_idle (void);
static struct wait_item_s * static struct wait_item_s *
@ -208,6 +211,8 @@ _gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond )
} }
} }
} }
if (hang)
run_idle ();
} while (hang); } while (hang);
return c; return c;
} }
@ -352,17 +357,23 @@ _gpgme_thaw_fd ( int fd )
} }
/**
* gpgme_register_idle:
* @fnc: Callers idle function
*
* Register a function with GPGME called by GPGME whenever it feels
* that is is idle. NULL may be used to remove this function.
**/
void
gpgme_register_idle ( void (*fnc)(void) )
{
idle_function = fnc;
}
static void
run_idle ()
{
if (idle_function)
idle_function ();
}

View File

@ -2,7 +2,8 @@
TESTS_ENVIRONMENT = GNUPGHOME=. TESTS_ENVIRONMENT = GNUPGHOME=.
TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist t-export t-import TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist t-export t-import \
t-trustlist
EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \ EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \

View File

@ -42,12 +42,32 @@ doit ( GpgmeCtx ctx, const char *pattern )
while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) { while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
char *p; char *p;
const char *s;
int i;
printf ("<!-- Begin key object (%p) -->\n", key ); printf ("<!-- Begin key object (%p) -->\n", key );
p = gpgme_key_get_as_xml ( key ); p = gpgme_key_get_as_xml ( key );
if ( p ) if ( p ) {
fputs ( p, stdout ); fputs ( p, stdout );
free (p);
}
else else
fputs("<!-- Ooops: gpgme_key_get_as_xml failed -->\n", stdout ); fputs("<!-- Ooops: gpgme_key_get_as_xml failed -->\n", stdout );
s = gpgme_key_get_string_attr (key, GPGME_ATTR_KEYID, NULL, 0 );
printf ("<!-- keyid=%s -->\n", s );
s = gpgme_key_get_string_attr (key, GPGME_ATTR_ALGO, NULL, 0 );
printf ("<!-- algo=%s -->\n", s );
for (i=0; ; i++ ) {
s = gpgme_key_get_string_attr (key, GPGME_ATTR_NAME, NULL, i );
if (!s)
break;
printf ("<!-- name.%d=%s -->\n", i, s );
s = gpgme_key_get_string_attr (key, GPGME_ATTR_EMAIL, NULL, i );
printf ("<!-- email.%d=%s -->\n", i, s );
s = gpgme_key_get_string_attr (key, GPGME_ATTR_COMMENT, NULL, i );
printf ("<!-- comment.%d=%s -->\n", i, s );
}
printf ("<!-- End key object (%p) -->\n", key ); printf ("<!-- End key object (%p) -->\n", key );
} }
if ( err != GPGME_EOF ) if ( err != GPGME_EOF )

89
tests/t-trustlist.c Normal file
View File

@ -0,0 +1,89 @@
/* t-trustlist.c - regression test
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GPGME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../gpgme/gpgme.h"
#define fail_if_err(a) do { if(a) { \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
__FILE__, __LINE__, gpgme_strerror(a)); \
exit (1); } \
} while(0)
static void
doit ( GpgmeCtx ctx, const char *pattern )
{
GpgmeError err;
GpgmeTrustItem item;
err = gpgme_op_trustlist_start (ctx, pattern, 0 );
fail_if_err (err);
while ( !(err = gpgme_op_trustlist_next ( ctx, &item )) ) {
printf ("l=%d k=%s t=%d o=%s v=%s u=%s\n",
gpgme_trust_item_get_int_attr (item, GPGME_ATTR_LEVEL, NULL, 0 ),
gpgme_trust_item_get_string_attr (item, GPGME_ATTR_KEYID, NULL, 0 ),
gpgme_trust_item_get_int_attr (item, GPGME_ATTR_TYPE, NULL, 0 ),
gpgme_trust_item_get_string_attr (item, GPGME_ATTR_OTRUST, NULL, 0 ),
gpgme_trust_item_get_string_attr (item, GPGME_ATTR_VALIDITY, NULL, 0 ),
gpgme_trust_item_get_string_attr (item, GPGME_ATTR_USERID, NULL, 0 )
);
gpgme_trust_item_release (item);
}
if ( err != GPGME_EOF )
fail_if_err (err);
}
int
main (int argc, char **argv )
{
GpgmeCtx ctx;
GpgmeError err;
int loop = 0;
const char *pattern;
if( argc ) {
argc--; argv++;
}
if (argc && !strcmp( *argv, "--loop" ) ) {
loop = 1;
argc--; argv++;
}
pattern = argc? *argv : NULL;
err = gpgme_new (&ctx);
fail_if_err (err);
do {
fprintf (stderr, "** pattern=`%s'\n", pattern );
doit ( ctx, pattern );
} while ( loop );
gpgme_release (ctx);
return 0;
}