diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 626f3e5c3..728168db2 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -54,7 +54,7 @@ typedef struct keyboxblob *KEYBOXBLOB; typedef struct keybox_name *KB_NAME; typedef struct keybox_name const *CONST_KB_NAME; -struct keybox_name +struct keybox_name { /* Link to the next resources, so that we can walk all resources. */ @@ -70,7 +70,7 @@ struct keybox_name entrues are set to NULL. HANDLE_TABLE may be NULL. */ KEYBOX_HANDLE *handle_table; size_t handle_table_size; - + /* Not yet used. */ int is_locked; @@ -82,6 +82,14 @@ struct keybox_name }; +struct keybox_found_s +{ + KEYBOXBLOB blob; + off_t offset; + size_t pk_no; + size_t uid_no; + unsigned int n_packets; /*used for delete and update*/ +}; struct keybox_handle { CONST_KB_NAME kb; @@ -89,14 +97,9 @@ struct keybox_handle { FILE *fp; int eof; int error; - int ephemeral; - struct { - KEYBOXBLOB blob; - off_t offset; - size_t pk_no; - size_t uid_no; - unsigned int n_packets; /*used for delete and update*/ - } found; + int ephemeral; + struct keybox_found_s found; + struct keybox_found_s saved_found; struct { char *name; char *pattern; @@ -215,7 +218,7 @@ void _keybox_free (void *p); #define STR2(v) STR(v) /* - a couple of handy macros + a couple of handy macros */ #define return_if_fail(expr) do { \ diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index e4138647e..53c1c5060 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -148,6 +148,7 @@ keybox_release (KEYBOX_HANDLE hd) hd->kb->handle_table[idx] = NULL; } _keybox_release_blob (hd->found.blob); + _keybox_release_blob (hd->saved_found.blob); if (hd->fp) { fclose (hd->fp); @@ -159,6 +160,35 @@ keybox_release (KEYBOX_HANDLE hd) } +/* Save the current found state in HD for later retrieval by + keybox_restore_found_state. Only one state may be saved. */ +void +keybox_push_found_state (KEYBOX_HANDLE hd) +{ + if (hd->saved_found.blob) + { + _keybox_release_blob (hd->saved_found.blob); + hd->saved_found.blob = NULL; + } + hd->saved_found = hd->found; + hd->found.blob = NULL; +} + + +/* Restore the saved found state in HD. */ +void +keybox_pop_found_state (KEYBOX_HANDLE hd) +{ + if (hd->found.blob) + { + _keybox_release_blob (hd->found.blob); + hd->found.blob = NULL; + } + hd->found = hd->saved_found; + hd->saved_found.blob = NULL; +} + + const char * keybox_get_resource_name (KEYBOX_HANDLE hd) { diff --git a/kbx/keybox.h b/kbx/keybox.h index 43306947f..e0d8c530a 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -68,6 +68,8 @@ int keybox_is_writable (void *token); KEYBOX_HANDLE keybox_new (void *token, int secret); void keybox_release (KEYBOX_HANDLE hd); +void keybox_push_found_state (KEYBOX_HANDLE hd); +void keybox_pop_found_state (KEYBOX_HANDLE hd); const char *keybox_get_resource_name (KEYBOX_HANDLE hd); int keybox_set_ephemeral (KEYBOX_HANDLE hd, int yes); diff --git a/sm/keydb.c b/sm/keydb.c index 37f791e6b..554740547 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -56,6 +56,7 @@ static int used_resources; struct keydb_handle { int locked; int found; + int saved_found; int current; int is_ephemeral; int used; /* items in active */ @@ -265,6 +266,7 @@ keydb_new (int secret) hd = xcalloc (1, sizeof *hd); hd->found = -1; + hd->saved_found = -1; assert (used_resources <= MAX_KEYDB_RESOURCES); for (i=j=0; i < used_resources; i++) @@ -476,6 +478,58 @@ unlock_all (KEYDB_HANDLE hd) hd->locked = 0; } + + +/* Push the last found state if any. */ +void +keydb_push_found_state (KEYDB_HANDLE hd) +{ + if (!hd) + return; + + if (hd->found < 0 || hd->found >= hd->used) + { + hd->saved_found = -1; + return; + } + + switch (hd->active[hd->found].type) + { + case KEYDB_RESOURCE_TYPE_NONE: + break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + keybox_push_found_state (hd->active[hd->found].u.kr); + break; + } + + hd->saved_found = hd->found; + hd->found = -1; +} + + +/* Pop the last found state. */ +void +keydb_pop_found_state (KEYDB_HANDLE hd) +{ + if (!hd) + return; + + hd->found = hd->saved_found; + hd->saved_found = -1; + if (hd->found < 0 || hd->found >= hd->used) + return; + + switch (hd->active[hd->found].type) + { + case KEYDB_RESOURCE_TYPE_NONE: + break; + case KEYDB_RESOURCE_TYPE_KEYBOX: + keybox_pop_found_state (hd->active[hd->found].u.kr); + break; + } +} + + #if 0 /* diff --git a/sm/keydb.h b/sm/keydb.h index a440c5047..f51d79d1a 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -49,6 +49,8 @@ gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value); gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value); +void keydb_push_found_state (KEYDB_HANDLE hd); +void keydb_pop_found_state (KEYDB_HANDLE hd); int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert); int keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert); int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert);