diff options
author | Werner Koch <[email protected]> | 2008-11-03 19:09:34 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2008-11-03 19:09:34 +0000 |
commit | 4019792423f4f3f2eb9d4d3ca173ffe286f801d8 (patch) | |
tree | a8a8f14012fb62257b486c8c936a7b50e6f2a22f /scd/command.c | |
parent | Use bin2hex if possible. (diff) | |
download | gnupg-4019792423f4f3f2eb9d4d3ca173ffe286f801d8.tar.gz gnupg-4019792423f4f3f2eb9d4d3ca173ffe286f801d8.zip |
Fixed the card removed with cached app bug. (Famous last fix).
Diffstat (limited to 'scd/command.c')
-rw-r--r-- | scd/command.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/scd/command.c b/scd/command.c index 849c9e33d..9385cbd9c 100644 --- a/scd/command.c +++ b/scd/command.c @@ -81,7 +81,7 @@ struct slot_status_s done. This is set once to indicate that the status tracking for the slot has been initialized. */ unsigned int status; /* Last status of the slot. */ - unsigned int changed; /* Last change counter of teh slot. */ + unsigned int changed; /* Last change counter of the slot. */ }; @@ -134,7 +134,7 @@ static pth_mutex_t status_file_update_lock; /*-- Local prototypes --*/ -static void update_reader_status_file (void); +static void update_reader_status_file (int set_card_removed_flag); @@ -171,7 +171,7 @@ update_card_removed (int slot, int value) } /* Let the card application layer know about the removal. */ if (value) - application_notify_card_removed (slot); + application_notify_card_reset (slot); } @@ -256,7 +256,8 @@ hex_to_buffer (const char *string, size_t *r_length) /* Reset the card and free the application context. With SEND_RESET - set to true actually send a RESET to the reader. */ + set to true actually send a RESET to the reader; this is the normal + way of calling the function. */ static void do_reset (ctrl_t ctrl, int send_reset) { @@ -265,18 +266,22 @@ do_reset (ctrl_t ctrl, int send_reset) if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table)))) BUG (); + /* If there is an active application, release it. */ if (ctrl->app_ctx) { release_application (ctrl->app_ctx); ctrl->app_ctx = NULL; } + /* If we want a real reset for the card, send the reset APDU and + tell the application layer about it. */ if (slot != -1 && send_reset && !IS_LOCKED (ctrl) ) { if (apdu_reset (slot)) { slot_table[slot].reset_failed = 1; } + application_notify_card_reset (slot); } /* If we hold a lock, unlock now. */ @@ -286,23 +291,23 @@ do_reset (ctrl_t ctrl, int send_reset) log_info ("implicitly unlocking due to RESET\n"); } - /* Reset card removed flag for the current reader. We need to take - the lock here so that the ticker thread won't concurrently try to - update the file. Note that the update function will set the card - removed flag and we will later reset it - not a particualar nice - way of implementing it but it works. */ + /* Reset the card removed flag for the current reader. We need to + take the lock here so that the ticker thread won't concurrently + try to update the file. Calling update_reader_status_file is + required to get hold of the new status of the card in the slot + table. */ if (!pth_mutex_acquire (&status_file_update_lock, 0, NULL)) { log_error ("failed to acquire status_fle_update lock\n"); ctrl->reader_slot = -1; return; } - update_reader_status_file (); - update_card_removed (slot, 0); + update_reader_status_file (0); /* Update slot status table. */ + update_card_removed (slot, 0); /* Clear card_removed flag. */ if (!pth_mutex_release (&status_file_update_lock)) log_error ("failed to release status_file_update lock\n"); - /* Do this last, so that update_card_removed does its job. */ + /* Do this last, so that the update_card_removed above does its job. */ ctrl->reader_slot = -1; } @@ -1875,7 +1880,7 @@ scd_command_handler (ctrl_t ctrl, int fd) } } - /* Cleanup. */ + /* Cleanup. We don't send an explicit reset to the card. */ do_reset (ctrl, 0); /* Release the server object. */ @@ -1951,9 +1956,9 @@ send_status_info (ctrl_t ctrl, const char *keyword, ...) /* This is the core of scd_update_reader_status_file but the caller - needs to take care of the locking. */ + needs to take care of the locking. */ static void -update_reader_status_file (void) +update_reader_status_file (int set_card_removed_flag) { int idx; unsigned int status, changed; @@ -1990,7 +1995,7 @@ update_reader_status_file (void) /* FIXME: Should this be IDX instead of ss->slot? This depends on how client sessions will associate the reader status with their session. */ - sprintf (templ, "reader_%d.status", ss->slot); + snprintf (templ, sizeof templ, "reader_%d.status", ss->slot); fname = make_filename (opt.homedir, templ, NULL ); fp = fopen (fname, "w"); if (fp) @@ -2047,7 +2052,7 @@ update_reader_status_file (void) /* Set the card removed flag for all current sessions. We will set this on any card change because a reset or SERIALNO request must be done in any case. */ - if (ss->any) + if (ss->any && set_card_removed_flag) update_card_removed (idx, 1); ss->any = 1; @@ -2090,7 +2095,7 @@ scd_update_reader_status_file (void) { if (!pth_mutex_acquire (&status_file_update_lock, 1, NULL)) return; /* locked - give up. */ - update_reader_status_file (); + update_reader_status_file (1); if (!pth_mutex_release (&status_file_update_lock)) log_error ("failed to release status_file_update lock\n"); } |