More changes and and some new functions
This commit is contained in:
parent
c74adbc096
commit
d6cd1f97ca
@ -0,0 +1,3 @@
|
||||
2001-01-05 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* data.c (gpgme_data_rewind): Allow to rewind data_type_none.
|
@ -23,6 +23,7 @@ libgpgme_la_SOURCES = \
|
||||
sign.c \
|
||||
key.c key.h \
|
||||
keylist.c \
|
||||
trustlist.c \
|
||||
import.c \
|
||||
export.c \
|
||||
genkey.c \
|
||||
|
@ -37,6 +37,10 @@ struct key_queue_item_s {
|
||||
struct key_queue_item_s *next;
|
||||
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
|
||||
@ -57,6 +61,7 @@ struct gpgme_context_s {
|
||||
int verbosity; /* level of verbosity to use */
|
||||
int use_armor;
|
||||
int use_textmode;
|
||||
int keylist_mode;
|
||||
|
||||
ResultType result_type;
|
||||
union {
|
||||
@ -70,6 +75,7 @@ struct gpgme_context_s {
|
||||
GpgmeKey tmp_key; /* used by keylist.c */
|
||||
volatile int key_cond; /* something new is available */
|
||||
struct key_queue_item_s *key_queue;
|
||||
struct trust_queue_item_s *trust_queue;
|
||||
|
||||
GpgmePassphraseCb passphrase_cb;
|
||||
void *passphrase_cb_value;
|
||||
@ -101,6 +107,9 @@ struct user_id_s {
|
||||
struct user_id_s *next;
|
||||
int validity; /* 0 = undefined, 1 = not, 2 = marginal,
|
||||
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];
|
||||
};
|
||||
|
||||
|
@ -410,7 +410,8 @@ gpgme_data_rewind ( GpgmeData dh )
|
||||
if ( !dh )
|
||||
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;
|
||||
}
|
||||
else if (dh->type == GPGME_DATA_TYPE_CB) {
|
||||
|
@ -164,6 +164,24 @@ gpgme_set_textmode ( GpgmeCtx c, int 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:
|
||||
* @c: the context
|
||||
|
@ -58,6 +58,9 @@ typedef struct gpgme_recipients_s *GpgmeRecipients;
|
||||
struct gpgme_key_s;
|
||||
typedef struct gpgme_key_s *GpgmeKey;
|
||||
|
||||
struct gpgme_trust_item_s;
|
||||
typedef struct gpgme_trust_item_s *GpgmeTrustItem;
|
||||
|
||||
|
||||
typedef enum {
|
||||
GPGME_EOF = -1,
|
||||
@ -107,6 +110,23 @@ typedef enum {
|
||||
GPGME_SIG_MODE_CLEAR = 2
|
||||
} 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*,
|
||||
const char *desc, void *r_hd);
|
||||
@ -124,6 +144,7 @@ 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_keylist_mode ( GpgmeCtx c, int mode );
|
||||
void gpgme_set_passphrase_cb (GpgmeCtx c,
|
||||
GpgmePassphraseCb 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 );
|
||||
|
||||
|
||||
/* Key functions */
|
||||
/* Key and trust functions */
|
||||
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 */
|
||||
@ -194,6 +228,10 @@ GpgmeError gpgme_op_genkey_start ( GpgmeCtx c, const char *parms,
|
||||
GpgmeError gpgme_op_keylist_start ( GpgmeCtx c,
|
||||
const char *pattern, int secret_only );
|
||||
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 */
|
||||
@ -215,7 +253,7 @@ GpgmeError gpgme_op_genkey ( GpgmeCtx c, const char *parms,
|
||||
/* miscellaneous functions */
|
||||
const char *gpgme_check_version ( const char *req_version );
|
||||
const char *gpgme_strerror (GpgmeError err);
|
||||
const char *gpgme_get_prompt ( GpgmeCtx c, int which );
|
||||
void gpgme_register_idle ( void (*fnc)(void) );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
287
gpgme/key.c
287
gpgme/key.c
@ -31,6 +31,23 @@
|
||||
#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
|
||||
_gpgme_key_new( GpgmeKey *r_key )
|
||||
{
|
||||
@ -88,6 +105,97 @@ _gpgme_key_release ( GpgmeKey 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
|
||||
* sequences and put it into the list of UIDs
|
||||
@ -99,12 +207,17 @@ _gpgme_key_append_name ( GpgmeKey key, const char *s )
|
||||
char *d;
|
||||
|
||||
assert (key);
|
||||
/* we can malloc a buffer of the same length, because the converted
|
||||
* string will never be larger */
|
||||
uid = xtrymalloc ( sizeof *uid + strlen (s) );
|
||||
/* we can malloc a buffer of the same length, because the
|
||||
* converted string will never be larger. Actually we allocate it
|
||||
* 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 )
|
||||
return mk_error (Out_Of_Core);
|
||||
uid->validity = 0;
|
||||
uid->name_part = NULL;
|
||||
uid->email_part = NULL;
|
||||
uid->comment_part = NULL;
|
||||
d = uid->name;
|
||||
|
||||
while ( *s ) {
|
||||
@ -152,6 +265,8 @@ _gpgme_key_append_name ( GpgmeKey key, const char *s )
|
||||
*d++ = *s++;
|
||||
}
|
||||
}
|
||||
*d++ = 0;
|
||||
parse_user_id ( uid, d );
|
||||
|
||||
uid->next = key->uids;
|
||||
key->uids = uid;
|
||||
@ -183,76 +298,6 @@ add_tag_and_string ( GpgmeData d, const char *tag, const char *string )
|
||||
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
|
||||
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 ) {
|
||||
_gpgme_data_append_string (d, " <userid>\n");
|
||||
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");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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, "--with-colons" );
|
||||
_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?
|
||||
"--list-secret-keys":"--list-keys" );
|
||||
|
||||
|
@ -229,7 +229,7 @@ _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds )
|
||||
static fd_set readfds;
|
||||
static fd_set writefds;
|
||||
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 ( &writefds );
|
||||
|
@ -57,6 +57,9 @@ gpgme_recipients_add_name (GpgmeRecipients rset, const char *name )
|
||||
r = xtrymalloc ( sizeof *r + strlen (name) );
|
||||
if (!r)
|
||||
return mk_error (Out_Of_Core);
|
||||
r->name_part = "";
|
||||
r->email_part = "";
|
||||
r->comment_part = "";
|
||||
strcpy (r->name, name );
|
||||
r->next = rset->list;
|
||||
rset->list = r;
|
||||
|
309
gpgme/trustlist.c
Normal file
309
gpgme/trustlist.c
Normal 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;
|
||||
}
|
||||
|
35
gpgme/wait.c
35
gpgme/wait.c
@ -62,7 +62,10 @@ struct wait_item_s {
|
||||
static int fd_table_size;
|
||||
static struct io_select_fd_s *fd_table;
|
||||
|
||||
static void (*idle_function) (void);
|
||||
|
||||
static int do_select ( void );
|
||||
static void run_idle (void);
|
||||
|
||||
|
||||
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);
|
||||
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 ();
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
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 \
|
||||
|
@ -42,12 +42,32 @@ doit ( GpgmeCtx ctx, const char *pattern )
|
||||
|
||||
while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
|
||||
char *p;
|
||||
const char *s;
|
||||
int i;
|
||||
|
||||
printf ("<!-- Begin key object (%p) -->\n", key );
|
||||
p = gpgme_key_get_as_xml ( key );
|
||||
if ( p )
|
||||
if ( p ) {
|
||||
fputs ( p, stdout );
|
||||
free (p);
|
||||
}
|
||||
else
|
||||
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 );
|
||||
}
|
||||
if ( err != GPGME_EOF )
|
||||
|
89
tests/t-trustlist.c
Normal file
89
tests/t-trustlist.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user