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 <wk@gnupg.org>
This commit is contained in:
Werner Koch 2019-06-25 09:23:38 +02:00
parent d803b3bb3c
commit c8e62965bc
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 39 additions and 6 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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");