aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-06-25 07:23:38 +0000
committerWerner Koch <[email protected]>2019-06-25 07:23:38 +0000
commitc8e62965bc90eabff5c4b7cb349bd8e41584c01b (patch)
tree1f01486a5ec2780a13b9b03c5344b9270a43db4f
parentscd: Add an re-select mechanism to switch apps. (diff)
downloadgnupg-c8e62965bc90eabff5c4b7cb349bd8e41584c01b.tar.gz
gnupg-c8e62965bc90eabff5c4b7cb349bd8e41584c01b.zip
scd: Return a stable list with "getinfo card_list".
* scd/app.c (compare_card_list_items): New. (app_send_card_list): Sort the card objects by slot. -- This is required so that in gpg-card a "list N" command always returns the expected card. Sorting by slot should be sufficient. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--scd/app-common.h2
-rw-r--r--scd/app.c41
-rw-r--r--scd/command.c2
3 files changed, 39 insertions, 6 deletions
diff --git a/scd/app-common.h b/scd/app-common.h
index 97b9b39ef..460046f89 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -223,7 +223,7 @@ const char *strcardtype (cardtype_t t);
const char *strapptype (apptype_t t);
void app_update_priority_list (const char *arg);
-void app_send_card_list (ctrl_t ctrl);
+gpg_error_t app_send_card_list (ctrl_t ctrl);
char *card_get_serialno (card_t card);
char *app_get_serialno (app_t app);
diff --git a/scd/app.c b/scd/app.c
index c568b636b..1ad6b9ed6 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -1601,22 +1601,55 @@ initialize_module_command (void)
}
-void
+/* Sort helper for app_send_card_list. */
+static int
+compare_card_list_items (const void *arg_a, const void *arg_b)
+{
+ const card_t a = *(const card_t *)arg_a;
+ const card_t b = *(const card_t *)arg_b;
+
+ return a->slot - b->slot;
+}
+
+
+/* Send status lines with the serialno of all inserted cards. */
+gpg_error_t
app_send_card_list (ctrl_t ctrl)
{
+ gpg_error_t err;
card_t c;
char buf[65];
+ card_t *cardlist = NULL;
+ int n, ncardlist;
npth_mutex_lock (&card_list_lock);
- for (c = card_top; c; c = c->next)
+ for (n=0, c = card_top; c; c = c->next)
+ n++;
+ cardlist = xtrycalloc (n, sizeof *cardlist);
+ if (!cardlist)
{
- if (DIM (buf) < 2 * c->serialnolen + 1)
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ for (ncardlist=0, c = card_top; c; c = c->next)
+ cardlist[ncardlist++] = c;
+ qsort (cardlist, ncardlist, sizeof *cardlist, compare_card_list_items);
+
+ for (n=0; n < ncardlist; n++)
+ {
+ if (DIM (buf) < 2 * cardlist[n]->serialnolen + 1)
continue;
- bin2hex (c->serialno, c->serialnolen, buf);
+ bin2hex (cardlist[n]->serialno, cardlist[n]->serialnolen, buf);
send_status_direct (ctrl, "SERIALNO", buf);
}
+
+ err = 0;
+
+ leave:
npth_mutex_unlock (&card_list_lock);
+ xfree (cardlist);
+ return err;
}
diff --git a/scd/command.c b/scd/command.c
index 2b851c5fd..f341b6ae2 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1630,7 +1630,7 @@ cmd_getinfo (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
- app_send_card_list (ctrl);
+ rc = app_send_card_list (ctrl);
}
else
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");