aboutsummaryrefslogtreecommitdiffstats
path: root/g10/ringedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/ringedit.c')
-rw-r--r--g10/ringedit.c242
1 files changed, 141 insertions, 101 deletions
diff --git a/g10/ringedit.c b/g10/ringedit.c
index de05ba6e2..6d5b3e0e4 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -460,112 +460,152 @@ unlock_keyblock( KBPOS kbpos )
}
+static int
+enum_keyrings_open_helper( KBPOS kbpos, int where )
+{
+ int i = where;
+ RESTBL *rentry;
+
+ for(; i < MAX_RESOURCES; i++ )
+ if( resource_table[i].used
+ && !resource_table[i].secret == !kbpos->secret )
+ break;
+ if( i == MAX_RESOURCES )
+ return -1; /* no resources */
+ kbpos->resno = i;
+ rentry = check_pos( kbpos );
+ kbpos->rt = resource_table[i].rt;
+ kbpos->valid = 0;
+ switch( kbpos->rt ) {
+ case rt_RING:
+ case rt_KBXF:
+ kbpos->fp = iobuf_open( rentry->fname );
+ if ( !kbpos->fp ) {
+ log_error("can't open `%s'\n", rentry->fname );
+ return GPGERR_OPEN_FILE;
+ }
+ break;
+
+ default: BUG();
+ }
+ kbpos->pkt = NULL;
+ return 0;
+}
+
+
/****************
- * This functions can be used to read through a complete keyring.
- * Mode is: 0 = open
- * 1 = read
- * 2 = close
- * 5 = open secret keyrings
+ * This set of functions is used to scan over all keyrings.
+ * The mode in enum_keyblocks_next() is used liek this:
+ * Mode is: 1 = read
* 11 = read but skip signature and comment packets.
- * all others are reserved!
*/
int
-enum_keyblocks( int mode, KBPOS kbpos, KBNODE *ret_root )
+enum_keyblocks_begin( KBPOS *rkbpos, int use_secret )
{
- int rc = 0;
- RESTBL *rentry;
+ int rc, i;
+ KBPOS kbpos;
+
+ *rkbpos = NULL;
+
+ kbpos = gcry_xcalloc( 1, sizeof *kbpos );
+ kbpos->fp = NULL;
+ kbpos->rt = rt_UNKNOWN;
+ if( !use_secret ) {
+ kbpos->secret = 0;
+ i = 0;
+ }
+ else {
+ kbpos->secret = 1;
+ i = 0;
+ }
+
+ rc = enum_keyrings_open_helper( kbpos, i );
+ if ( rc ) {
+ gcry_free( kbpos );
+ return rc;
+ }
+ /* return the handle */
+ *rkbpos = kbpos;
+ return 0;
+}
- if( !mode || mode == 5 || mode == 100 ) {
- int i;
+void
+enum_keyblocks_end( KBPOS kbpos )
+{
+ if ( !kbpos )
+ return;
+ switch( kbpos->rt ) {
+ case rt_RING:
+ case rt_KBXF:
+ if( kbpos->fp ) {
+ iobuf_close( kbpos->fp );
+ kbpos->fp = NULL;
+ }
+ break;
+ case rt_UNKNOWN:
+ /* this happens when we have no keyring at all */
+ gcry_free( kbpos );
+ return;
+
+ default:
+ BUG();
+ }
+ /* release pending packet */
+ free_packet( kbpos->pkt );
+ gcry_free( kbpos->pkt );
+ gcry_free( kbpos );
+}
- kbpos->fp = NULL;
- kbpos->rt = rt_UNKNOWN;
- if( !mode ) {
- kbpos->secret = 0;
- i = 0;
- }
- else if( mode == 5 ) {
- kbpos->secret = 1;
- mode = 0;
- i = 0;
- }
- else
- i = kbpos->resno+1;
- for(; i < MAX_RESOURCES; i++ )
- if( resource_table[i].used
- && !resource_table[i].secret == !kbpos->secret )
- break;
- if( i == MAX_RESOURCES )
- return -1; /* no resources */
- kbpos->resno = i;
- rentry = check_pos( kbpos );
- kbpos->rt = resource_table[i].rt;
- kbpos->valid = 0;
- switch( kbpos->rt ) {
- case rt_RING:
- case rt_KBXF:
- kbpos->fp = iobuf_open( rentry->fname );
- if( !kbpos->fp ) {
- log_error("can't open `%s'\n", rentry->fname );
- return GPGERR_OPEN_FILE;
- }
- break;
+int
+enum_keyblocks_next( KBPOS kbpos, int mode, KBNODE *ret_root )
+{
+ int cont, rc = 0;
+ RESTBL *rentry;
- default: BUG();
- }
- kbpos->pkt = NULL;
- }
- else if( mode == 1 || mode == 11 ) {
- int cont;
- do {
- cont = 0;
- switch( kbpos->rt ) {
- case rt_RING:
- if( !kbpos->fp )
- return GPGERR_GENERAL;
- rc = keyring_enum( kbpos, ret_root, mode == 11 );
- break;
- case rt_KBXF:
- if( !kbpos->fp )
- return GPGERR_GENERAL;
- rc = do_kbxf_enum( kbpos, ret_root, mode == 11 );
- break;
- default: BUG();
- }
+ if( mode != 1 && mode != 11 )
+ return GPGERR_INV_ARG;
+
+ do {
+ cont = 0;
+ switch( kbpos->rt ) {
+ case rt_RING:
+ if( !kbpos->fp )
+ return GPGERR_GENERAL;
+ rc = keyring_enum( kbpos, ret_root, mode == 11 );
+ break;
+ case rt_KBXF:
+ if( !kbpos->fp )
+ return GPGERR_GENERAL;
+ rc = do_kbxf_enum( kbpos, ret_root, mode == 11 );
+ break;
+ default: BUG();
+ }
- if( rc == -1 ) {
- assert( !kbpos->pkt );
- rentry = check_pos( kbpos );
- assert(rentry);
- /* close */
- enum_keyblocks(2, kbpos, ret_root );
- /* and open the next one */
- rc = enum_keyblocks(100, kbpos, ret_root );
- if( !rc )
- cont = 1;
- }
- } while(cont);
- }
- else {
- switch( kbpos->rt ) {
- case rt_RING:
- case rt_KBXF:
- if( kbpos->fp ) {
- iobuf_close( kbpos->fp );
- kbpos->fp = NULL;
- }
- break;
- case rt_UNKNOWN:
- /* this happens when we have no keyring at all */
- return rc;
+ if( rc == -1 ) {
+ RESTBL *rentry;
+ int i;
+
+ assert( !kbpos->pkt );
+ rentry = check_pos( kbpos );
+ assert(rentry);
+ i = kbpos->resno+1;
+ /* first close */
+ if( kbpos->fp ) {
+ iobuf_close( kbpos->fp );
+ kbpos->fp = NULL;
+ }
+ free_packet( kbpos->pkt );
+ gcry_free( kbpos->pkt );
+ kbpos->pkt = NULL;
+ /* and then open the next one */
+ rc = enum_keyrings_open_helper( kbpos, i );
+ if ( !rc )
+ cont = 1;
+ /* hmm, that is not really correct: if we got an error kbpos
+ * might be not well anymore */
+ }
+ } while(cont);
- default:
- BUG();
- }
- /* release pending packet */
- free_packet( kbpos->pkt );
- gcry_free( kbpos->pkt );
- }
return rc;
}
@@ -632,7 +672,7 @@ int
update_keyblock( KBNODE root )
{
int rc;
- struct WORK WORK WORK KBPOS kbpos;
+ struct keyblock_pos_struct kbpos;
/* We need to get the file position of original keyblock first */
if ( root->pkt->pkttype == PKT_PUBLIC_KEY )
@@ -668,7 +708,7 @@ update_keyblock( KBNODE root )
****************************************************************/
static int
-keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
+keyring_enum( KBPOS kbpos, KBNODE *ret_root, int skipsigs )
{
PACKET *pkt;
int rc;
@@ -767,7 +807,7 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
* 3 = update
*/
static int
-keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
+keyring_copy( KBPOS kbpos, int mode, KBNODE root )
{
RESTBL *rentry;
IOBUF fp, newfp;
@@ -1003,7 +1043,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
****************************************************************/
static int
-do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
+do_kbxf_enum( KBPOS kbpos, KBNODE *ret_root, int skipsigs )
{
PACKET *pkt;
int rc;
@@ -1092,7 +1132,7 @@ do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
* 3 = update
*/
static int
-do_kbxf_copy( KBPOS *kbpos, int mode, KBNODE root )
+do_kbxf_copy( KBPOS kbpos, int mode, KBNODE root )
{
RESTBL *rentry;
IOBUF fp, newfp;