[git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-157-g2d91feb

by Werner Koch cvs at cvs.gnupg.org
Wed Dec 14 11:25:20 CET 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  2d91febbd8d30beb7eb33f7aa80ffd5691d1d3cc (commit)
       via  07ea8c56b507b06d4bd70e94fa51914659afac4b (commit)
       via  00c760f628f4cf0fc11e79d305c172f98123f815 (commit)
       via  24e121ef261731069868ca403b818f1168237f53 (commit)
      from  11164662788036c4b15d30555ea33ec0b6f5a670 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 2d91febbd8d30beb7eb33f7aa80ffd5691d1d3cc
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Dec 14 10:30:01 2011 +0100

    scd: Fix resetting and closing of the reader.
    
    * scd/command.c (update_card_removed): Do no act on an invalid VRDR.
    (do_reset): Ignore apdu_reset error codes for no and inactive card.
    Close the reader before setting the slot to -1.
    (update_reader_status_file): Notify the application before closing the
    reader.
    --
    
    With this change the scd now works as it did in the past.  In
    particular there is no more endless loop trying to open the reader by
    the update_reader_status_file ticker function.  That bug basically
    blocked all card operations until the scdaemon was killed.

diff --git a/scd/command.c b/scd/command.c
index 2ade38a..0f57448 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -180,6 +180,19 @@ initialize_module_command (void)
 }
 
 
+/* Helper to return the slot number for a given virtual reader index
+   VRDR.  In case on an error -1 is returned.  */
+static int
+vreader_slot (int vrdr)
+{
+  if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
+    return -1;
+  if (!vreader_table [vrdr].valid)
+    return -1;
+  return vreader_table[vrdr].slot;
+}
+
+
 /* Update the CARD_REMOVED element of all sessions using the virtual
    reader given by VRDR to VALUE.  */
 static void
@@ -187,6 +200,9 @@ update_card_removed (int vrdr, int value)
 {
   struct server_local_s *sl;
 
+  if (vrdr == -1)
+    return;
+
   for (sl=session_list; sl; sl = sl->next_session)
     if (sl->ctrl_backlink
         && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
@@ -195,20 +211,7 @@ update_card_removed (int vrdr, int value)
       }
   /* Let the card application layer know about the removal.  */
   if (value)
-    application_notify_card_reset (vrdr);
-}
-
-
-/* Helper to return the slot number for a given virtual reader index
-   VRDR.  In case on an error -1 is returned.  */
-static int
-vreader_slot (int vrdr)
-{
-  if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
-    return -1;
-  if (!vreader_table [vrdr].valid)
-    return -1;
-  return vreader_table[vrdr].slot;
+    application_notify_card_reset (vreader_slot (vrdr));
 }
 
 
@@ -298,6 +301,7 @@ static void
 do_reset (ctrl_t ctrl, int send_reset)
 {
   int vrdr = ctrl->server_local->vreader_idx;
+  int slot;
 
   if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
     BUG ();
@@ -324,13 +328,22 @@ do_reset (ctrl_t ctrl, int send_reset)
 
   /* If we want a real reset for the card, send the reset APDU and
      tell the application layer about it.  */
-  if (vrdr != -1 && send_reset && !IS_LOCKED (ctrl) )
+  slot = vreader_slot (vrdr);
+  if (slot != -1 && send_reset && !IS_LOCKED (ctrl) )
     {
-      if (apdu_reset (vreader_table[vrdr].slot))
+      application_notify_card_reset (slot);
+      switch (apdu_reset (slot))
         {
-          vreader_table[vrdr].valid = 0;
+        case 0:
+          break;
+        case SW_HOST_NO_CARD:
+        case SW_HOST_CARD_INACTIVE:
+          break;
+        default:
+	  apdu_close_reader (slot);
+          vreader_table[vrdr].slot = slot = -1;
+          break;
         }
-      application_notify_card_reset (vrdr);
     }
 
   /* If we hold a lock, unlock now. */
@@ -1696,11 +1709,7 @@ cmd_getinfo (assuan_context_t ctx, char *line)
 	    BUG ();
 
 	  vr = &vreader_table[vrdr];
-
-	  if (!vr->valid)
-	    BUG ();
-
-	  if (vr->any && (vr->status & 1))
+	  if (vr->valid && vr->any && (vr->status & 1))
 	    flag = 'u';
 	}
       rc = assuan_send_data (ctx, &flag, 1);
@@ -2248,9 +2257,9 @@ update_reader_status_file (int set_card_removed_flag)
       if (sw_apdu == SW_HOST_NO_READER)
         {
           /* Most likely the _reader_ has been unplugged.  */
+          application_notify_card_reset (vr->slot);
 	  apdu_close_reader (vr->slot);
           vr->slot = -1;
-	  vr->valid = 0;
           status = 0;
           changed = vr->changed;
         }

commit 07ea8c56b507b06d4bd70e94fa51914659afac4b
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Dec 14 10:21:15 2011 +0100

    scd: Add debug option for reader function calls.
    
    * scd/scdaemon.h (DBG_READER_VALUE, DBG_READER): New.
    * scd/apdu.c (apdu_open_reader, apdu_close_reader)
    (apdu_shutdown_reader, apdu_connect, apdu_disconnect)
    (apdu_reset, apdu_get_atr, apdu_get_status): Add debug code.
    (apdu_activate): Remove this unused function.

diff --git a/scd/apdu.c b/scd/apdu.c
index ae91082..c37e8c4 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -2772,6 +2772,9 @@ apdu_open_reader (const char *portstr, int *r_no_service)
   static int pcsc_api_loaded, ct_api_loaded;
   int slot;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr);
+
   if (r_no_service)
     *r_no_service = 0;
 
@@ -2786,6 +2789,8 @@ apdu_open_reader (const char *portstr, int *r_no_service)
       if (slot != -1)
         {
           once_available = 1;
+          if (DBG_READER)
+            log_debug ("leave: apdu_open_reader => slot=%d [ccid]\n", slot);
           return slot; /* got one */
         }
 
@@ -2796,14 +2801,22 @@ apdu_open_reader (const char *portstr, int *r_no_service)
          and over again.  To reset this flag "gpgconf --kill scdaemon"
          can be used.  */
       if (once_available)
-        return -1;
+        {
+          if (DBG_READER)
+            log_debug ("leave: apdu_open_reader => slot=-1 (once_avail)\n");
+          return -1;
+        }
 
       /* If a CCID reader specification has been given, the user does
          not want a fallback to other drivers. */
       if (portstr)
         for (s=portstr, i=0; *s; s++)
           if (*s == ':' && (++i == 3))
-            return -1;
+            {
+              if (DBG_READER)
+                log_debug ("leave: apdu_open_reader => slot=-1 (no ccid)\n");
+              return -1;
+            }
     }
 
 #endif /* HAVE_LIBUSB */
@@ -2928,6 +2941,8 @@ apdu_open_reader (const char *portstr, int *r_no_service)
   if (slot == -1 && r_no_service && pcsc_no_service)
     *r_no_service = 1;
 
+  if (DBG_READER)
+    log_debug ("leave: apdu_open_reader => slot=%d [pc/sc]\n", slot);
   return slot;
 }
 
@@ -2982,13 +2997,31 @@ apdu_close_reader (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_close_reader: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_close_reader => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
   sw = apdu_disconnect (slot);
   if (sw)
-    return sw;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_close_reader => 0x%x (apdu_disconnect)\n", sw);
+      return sw;
+    }
   if (reader_table[slot].close_reader)
-    return reader_table[slot].close_reader (slot);
+    {
+      sw = reader_table[slot].close_reader (slot);
+      if (DBG_READER)
+        log_debug ("leave: apdu_close_reader => 0x%x (close_reader)\n", sw);
+      return sw;
+    }
+  if (DBG_READER)
+    log_debug ("leave: apdu_close_reader => SW_HOST_NOT_SUPPORTED\n");
   return SW_HOST_NOT_SUPPORTED;
 }
 
@@ -3027,13 +3060,32 @@ apdu_shutdown_reader (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_shutdown_reader: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_shutdown_reader => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
   sw = apdu_disconnect (slot);
   if (sw)
-    return sw;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_shutdown_reader => 0x%x (apdu_disconnect)\n",
+                   sw);
+      return sw;
+    }
   if (reader_table[slot].shutdown_reader)
-    return reader_table[slot].shutdown_reader (slot);
+    {
+      sw = reader_table[slot].shutdown_reader (slot);
+      if (DBG_READER)
+        log_debug ("leave: apdu_shutdown_reader => 0x%x (close_reader)\n", sw);
+      return sw;
+    }
+  if (DBG_READER)
+    log_debug ("leave: apdu_shutdown_reader => SW_HOST_NOT_SUPPORTED\n");
   return SW_HOST_NOT_SUPPORTED;
 }
 
@@ -3060,8 +3112,15 @@ apdu_connect (int slot)
   int sw;
   unsigned int status;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_connect: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_connect => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
 
   /* Only if the access method provides a connect function we use it.
      If not, we expect that the card has been implicitly connected by
@@ -3092,6 +3151,8 @@ apdu_connect (int slot)
            || !reader_table[slot].atrlen)
     sw = SW_HOST_CARD_INACTIVE;
 
+  if (DBG_READER)
+    log_debug ("leave: apdu_connect => sw=0x%x\n", sw);
 
   return sw;
 }
@@ -3102,8 +3163,15 @@ apdu_disconnect (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_disconnect: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_disconnect => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
 
   if (reader_table[slot].disconnect_card)
     {
@@ -3116,6 +3184,9 @@ apdu_disconnect (int slot)
     }
   else
     sw = 0;
+
+  if (DBG_READER)
+    log_debug ("leave: apdu_disconnect => sw=0x%x\n", sw);
   return sw;
 }
 
@@ -3151,11 +3222,22 @@ apdu_reset (int slot)
 {
   int sw;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_reset: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_reset => SW_HOST_NO_DRIVER\n");
+      return SW_HOST_NO_DRIVER;
+    }
 
   if ((sw = lock_slot (slot)))
-    return sw;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_reset => sw=0x%x (lock_slot)\n", sw);
+      return sw;
+    }
 
   reader_table[slot].last_status = 0;
   if (reader_table[slot].reset_reader)
@@ -3171,73 +3253,47 @@ apdu_reset (int slot)
     }
 
   unlock_slot (slot);
+  if (DBG_READER)
+    log_debug ("leave: apdu_reset => sw=0x%x\n", sw);
   return sw;
 }
 
 
-/* Activate a card if it has not yet been done.  This is a kind of
-   reset-if-required.  It is useful to test for presence of a card
-   before issuing a bunch of apdu commands.  It does not wait on a
-   locked card. */
-int
-apdu_activate (int slot)
-{
-  int sw;
-  unsigned int s;
-
-  if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return SW_HOST_NO_DRIVER;
-
-  if ((sw = trylock_slot (slot)))
-    return sw;
-
-  if (reader_table[slot].get_status_reader)
-    sw = reader_table[slot].get_status_reader (slot, &s);
-
-  if (!sw)
-    {
-      if (!(s & 2))  /* Card not present.  */
-        sw = SW_HOST_NO_CARD;
-      else if ( ((s & 2) && !(s & 4))
-                || !reader_table[slot].atrlen )
-        {
-          /* We don't have an ATR or a card is present though inactive:
-             do a reset now. */
-          if (reader_table[slot].reset_reader)
-            {
-              reader_table[slot].last_status = 0;
-              sw = reader_table[slot].reset_reader (slot);
-              if (!sw)
-                {
-                  /* If we got to here we know that a card is present
-                     and usable.  Thus remember this.  */
-                  reader_table[slot].last_status = (APDU_CARD_USABLE
-                                                    | APDU_CARD_PRESENT
-                                                    | APDU_CARD_ACTIVE);
-                }
-            }
-        }
-    }
-
-  unlock_slot (slot);
-  return sw;
-}
-
-
+/* Return the ATR or NULL if none is available.  On success the length
+   of the ATR is stored at ATRLEN.  The caller must free the returned
+   value.  */
 unsigned char *
 apdu_get_atr (int slot, size_t *atrlen)
 {
   unsigned char *buf;
 
+  if (DBG_READER)
+    log_debug ("enter: apdu_get_atr: slot=%d\n", slot);
+
   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
-    return NULL;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_get_atr => NULL (bad slot)\n");
+      return NULL;
+    }
   if (!reader_table[slot].atrlen)
-    return NULL;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_get_atr => NULL (no ATR)\n");
+      return NULL;
+    }
+
   buf = xtrymalloc (reader_table[slot].atrlen);
   if (!buf)
-    return NULL;
+    {
+      if (DBG_READER)
+        log_debug ("leave: apdu_get_atr => NULL (out of core)\n");
+      return NULL;
+    }
   memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen);
   *atrlen = reader_table[slot].atrlen;
+  if (DBG_READER)
+    log_debug ("leave: apdu_get_atr => atrlen=%zu\n", *atrlen);
   return buf;
 }
 
@@ -3308,7 +3364,26 @@ int
 apdu_get_status (int slot, int hang,
                  unsigned int *status, unsigned int *changed)
 {
-  return apdu_get_status_internal (slot, hang, 0, status, changed);
+  int sw;
+
+  if (DBG_READER)
+    log_debug ("enter: apdu_get_status: slot=%d hang=%d\n", slot, hang);
+  sw = apdu_get_status_internal (slot, hang, 0, status, changed);
+  if (DBG_READER)
+    {
+      if (status && changed)
+        log_debug ("leave: apdu_get_status => sw=0x%x status=%u changecnt=%u\n",
+                   sw, *status, *changed);
+      else if (status)
+        log_debug ("leave: apdu_get_status => sw=0x%x status=%u\n",
+                   sw, *status);
+      else if (changed)
+        log_debug ("leave: apdu_get_status => sw=0x%x changed=%u\n",
+                   sw, *changed);
+      else
+        log_debug ("leave: apdu_get_status => sw=0x%x\n", sw);
+    }
+  return sw;
 }
 
 
diff --git a/scd/apdu.h b/scd/apdu.h
index ac1eeeb..f704256 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -108,7 +108,6 @@ int apdu_disconnect (int slot);
 
 int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg);
 
-int apdu_activate (int slot);
 int apdu_reset (int slot);
 int apdu_get_status (int slot, int hang,
                      unsigned int *status, unsigned int *changed);
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 4c0a663..74e8b7d 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -72,8 +72,9 @@ struct
 #define DBG_CACHE_VALUE   64	/* debug the caching */
 #define DBG_MEMSTAT_VALUE 128	/* show memory statistics */
 #define DBG_HASHING_VALUE 512	/* debug hashing operations */
-#define DBG_ASSUAN_VALUE 1024
+#define DBG_ASSUAN_VALUE  1024
 #define DBG_CARD_IO_VALUE 2048
+#define DBG_READER_VALUE  4096  /* Trace reader related functions.  */
 
 #define DBG_COMMAND (opt.debug & DBG_COMMAND_VALUE)
 #define DBG_CRYPTO  (opt.debug & DBG_CRYPTO_VALUE)
@@ -82,6 +83,7 @@ struct
 #define DBG_HASHING (opt.debug & DBG_HASHING_VALUE)
 #define DBG_ASSUAN  (opt.debug & DBG_ASSUAN_VALUE)
 #define DBG_CARD_IO (opt.debug & DBG_CARD_IO_VALUE)
+#define DBG_READER  (opt.debug & DBG_READER_VALUE)
 
 struct server_local_s;
 struct app_ctx_s;

commit 00c760f628f4cf0fc11e79d305c172f98123f815
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Dec 13 17:59:00 2011 +0100

    scd: New option --debug-assuan-log-cats.
    
    * scd/scdaemon.c (oDebugAssuanLogCats): New.
    (opts): Add option --debug-assuan-log-cats.
    (main): Implement option.
    * common/asshelp.c (set_libassuan_log_cats): New.
    
    --
    
    The old way of setting the logging categories with an environment
    variable is awkward if sdaemon is spawned from a running gpg-agent.

diff --git a/common/asshelp.c b/common/asshelp.c
index c5d8bdf..7ac6ff0 100644
--- a/common/asshelp.c
+++ b/common/asshelp.c
@@ -97,6 +97,19 @@ setup_libassuan_logging (unsigned int *debug_var_address)
   assuan_set_log_cb (my_libassuan_log_handler, debug_var_address);
 }
 
+/* Change the Libassuan log categories to those given by NEWCATS.
+   NEWCATS is 0 the default category of ASSUAN_LOG_CONTROL is
+   selected.  Note, that setup_libassuan_logging overrides the values
+   given here.  */
+void
+set_libassuan_log_cats (unsigned int newcats)
+{
+  if (newcats)
+    log_cats = newcats;
+  else /* Default to log the control channel.  */
+    log_cats = (1 << (ASSUAN_LOG_CONTROL - 1));
+}
+
 
 
 static gpg_error_t
diff --git a/common/asshelp.h b/common/asshelp.h
index 0eb6553..728c039 100644
--- a/common/asshelp.h
+++ b/common/asshelp.h
@@ -26,6 +26,7 @@
 #include "session-env.h"
 
 void setup_libassuan_logging (unsigned int *debug_var_address);
+void set_libassuan_log_cats (unsigned int newcats);
 
 
 gpg_error_t
diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi
index 3c84279..9184ce2 100644
--- a/doc/scdaemon.texi
+++ b/doc/scdaemon.texi
@@ -21,16 +21,16 @@
 .IR dir ]
 .RB [ \-\-options
 .IR file ]
-.RI [ options ]  
-.B  \-\-server 
+.RI [ options ]
+.B  \-\-server
 .br
 .B  scdaemon
 .RB [ \-\-homedir
 .IR dir ]
 .RB [ \-\-options
 .IR file ]
-.RI [ options ]  
-.B  \-\-daemon 
+.RI [ options ]
+.B  \-\-daemon
 .RI [ command_line ]
 @end ifset
 
@@ -130,7 +130,7 @@ a numeric value or a keyword:
 @item none
 No debugging at all.  A value of less than 1 may be used instead of
 the keyword.
- at item basic  
+ at item basic
 Some basic debug messages.  A value between 1 and 2 may be used
 instead of the keyword.
 @item advanced
@@ -165,8 +165,8 @@ usual C-Syntax. The currently defined bits are:
 @table @code
 @item 0  (1)
 command I/O
- at item 1  (2)  
-values of big number integers 
+ at item 1  (2)
+values of big number integers
 @item 2  (4)
 low level crypto operations
 @item 5  (32)
@@ -178,7 +178,7 @@ show memory statistics.
 @item 9  (512)
 write hashed data to files named @code{dbgmd-000*}
 @item 10 (1024)
-trace Assuan protocol
+trace Assuan protocol.  See also option @option{--debug-assuan-log-cats}.
 @item 11 (2048)
 trace APDU I/O to the card.  This may reveal sensitive data.
 @end table
@@ -215,6 +215,15 @@ dump.  This options enables it and also changes the working directory to
 @opindex debug-log-tid
 This option appends a thread ID to the PID in the log output.
 
+ at item --debug-assuan-log-cats @var{cats}
+ at opindex debug-assuan-log-cats
+Changes the active Libassuan logging categories to @var{cats}.  The
+value for @var{cats} is an unsigned integer given in usual C-Syntax.
+A value of of 0 switches to a default category.  If this option is not
+used the categories are taken from the environment variable
+ at samp{ASSUAN_DEBUG}.  Note that this option has only an effect if the
+Assuan debug flag has also been with the option @option{--debug}.  For
+a list of categories see the Libassuan manual.
 
 @item --no-detach
 @opindex no-detach
@@ -240,7 +249,7 @@ Use @var{library} to access the smartcard reader.  The current default
 is @file{libtowitoko.so}.  Note that the use of this interface is
 deprecated; it may be removed in future releases.
 
- at item --disable-ccid 
+ at item --disable-ccid
 @opindex disable-ccid
 Disable the integrated support for CCID compliant readers.  This
 allows to fall back to one of the other drivers even if the internal
@@ -325,7 +334,7 @@ stripping off the two leading dashes.
 
 This application is currently only used by @command{gpg} but may in
 future also be useful with @command{gpgsm}.  Version 1 and version 2 of
-the card is supported. 
+the card is supported.
 
 The specifications for these cards are available at
 @uref{http://g10code.com/docs/openpgp-card-1.0.pdf} and
@@ -395,7 +404,7 @@ about reader status changes.  Its use is now deprecated in favor of
 @end table
 
 
- at c 
+ at c
 @c  Examples
 @c
 @mansect examples
@@ -410,7 +419,7 @@ $ scdaemon --server -v
 
 @c man end
 
- at c 
+ at c
 @c  Assuan Protocol
 @c
 @manpause
@@ -447,7 +456,7 @@ synchronizing access to a token between sessions.
 * Scdaemon APDU::         Send a verbatim APDU to the card
 @end menu
 
- at node Scdaemon SERIALNO 
+ at node Scdaemon SERIALNO
 @subsection Return the serial number
 
 This command should be used to check for the presence of a card.  It is
@@ -470,7 +479,7 @@ Return the serial number of the card using a status response like:
 @end example
 
 The trailing 0 should be ignored for now, it is reserved for a future
-extension.  The serial number is the hex encoded value identified by 
+extension.  The serial number is the hex encoded value identified by
 the @code{0x5A} tag in the GDO file (FIX=0x2F02).
 
 
@@ -522,7 +531,7 @@ READKEY @var{hexified_certid}
 @end example
 
 Return the public key for the given cert or key ID as an standard
-S-Expression. 
+S-Expression.
 
 
 
@@ -619,7 +628,7 @@ TO BE WRITTEN.
 @example
    PASSWD [--reset] [--nullpin] @var{chvno}
 @end example
-  
+
 Change the PIN or reset the retry counter of the card holder
 verification vector number @var{chvno}.  The option @option{--nullpin}
 is used to initialize the PIN of TCOS cards (6 byte NullPIN only).
@@ -663,11 +672,11 @@ and only if the retry counter is still at 3.
 
 Restart the current connection; this is a kind of warm reset.  It
 deletes the context used by this connection but does not actually
-reset the card. 
+reset the card.
 
 This is used by gpg-agent to reuse a primary pipe connection and
 may be used by clients to backup from a conflict in the serial
-command; i.e. to select another application. 
+command; i.e. to select another application.
 
 
 
@@ -704,7 +713,7 @@ length up to N bytes.  If N is not given a default value is used
 @mansect see also
 @ifset isman
 @command{gpg-agent}(1),
- at command{gpgsm}(1), 
+ at command{gpgsm}(1),
 @command{gpg2}(1)
 @end ifset
 @include see-also-note.texi
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index b4eee39..c8905d4 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -72,6 +72,7 @@ enum cmd_and_opt_values
   oDebugAllowCoreDump,
   oDebugCCIDDriver,
   oDebugLogTid,
+  oDebugAssuanLogCats,
   oNoGreeting,
   oNoOptions,
   oHomedir,
@@ -121,6 +122,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"),
   ARGPARSE_s_n (oDebugDisableTicker, "debug-disable-ticker", "@"),
   ARGPARSE_s_n (oDebugLogTid, "debug-log-tid", "@"),
+  ARGPARSE_p_u (oDebugAssuanLogCats, "debug-assuan-log-cats", "@"),
   ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
   ARGPARSE_s_s (oLogFile,  "log-file", N_("|FILE|write a log to FILE")),
   ARGPARSE_s_s (oReaderPort, "reader-port",
@@ -553,6 +555,9 @@ main (int argc, char **argv )
         case oDebugLogTid:
           log_set_pid_suffix_cb (tid_log_callback);
           break;
+        case oDebugAssuanLogCats:
+          set_libassuan_log_cats (pargs.r.ret_ulong);
+          break;
 
         case oOptions:
           /* config files may not be nested (silently ignore them) */

commit 24e121ef261731069868ca403b818f1168237f53
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Dec 13 16:55:42 2011 +0100

    scd: Introduce a virtual reader table.
    
    The vreader table makes the code more clear by explicitly talking
    about APDU slots and reader indices.  It also accommodates for future
    extensions.
    
    * scd/scdaemon.h (server_control_s): Remove READER_SLOT.
    * scd/scdaemon.c (scd_init_default_ctrl): Do not init READER_SLOT.
    * scd/app.c (check_application_conflict): Add arg SLOT.
    * scd/command.c (slot_status_s): Rename to vreader_s.
    (server_local_s): Add field VREADER_IDX as replacement for
    the READER_SLOT in server_control_s.  Change all users.
    (slot_table): Rename to vreader_table.  Change all users.
    (vreader_slot): New.
    (do_reset, cmd_apdu): Map vreader to apdu slot.
    (get_reader_slot): Rename to get_current_reader.  Return -1 on error.
    (open_card): Map vreader toapdu slot.  Pass slot to
    check_application_conflict.
    (scd_command_handler): Init VREADER_IDX.
    (update_reader_status_file): Reset SLOT field on error.

diff --git a/scd/app-common.h b/scd/app-common.h
index 6a1e2a7..e3d23c2 100644
--- a/scd/app-common.h
+++ b/scd/app-common.h
@@ -143,7 +143,8 @@ size_t app_help_read_length_of_cert (int slot, int fid, size_t *r_certoff);
 /*-- app.c --*/
 void app_dump_state (void);
 void application_notify_card_reset (int slot);
-gpg_error_t check_application_conflict (ctrl_t ctrl, const char *name);
+gpg_error_t check_application_conflict (ctrl_t ctrl, int slot,
+                                        const char *name);
 gpg_error_t select_application (ctrl_t ctrl, int slot, const char *name,
                                 app_t *r_app);
 char *get_supported_applications (void);
diff --git a/scd/app.c b/scd/app.c
index 6d65236..6f0d756 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -213,18 +213,19 @@ application_notify_card_reset (int slot)
    used to request a specific application and the connection has
    already done a select_application. */
 gpg_error_t
-check_application_conflict (ctrl_t ctrl, const char *name)
+check_application_conflict (ctrl_t ctrl, int slot, const char *name)
 {
-  int slot = ctrl->reader_slot;
   app_t app;
 
+  (void)ctrl;
+
   if (slot < 0 || slot >= DIM (lock_table))
     return gpg_error (GPG_ERR_INV_VALUE);
 
   app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
   if (app && app->apptype && name)
     if ( ascii_strcasecmp (app->apptype, name))
-        return gpg_error (GPG_ERR_CONFLICT);
+      return gpg_error (GPG_ERR_CONFLICT);
   return 0;
 }
 
diff --git a/scd/command.c b/scd/command.c
index b2a504c..2ade38a 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1,6 +1,6 @@
 /* command.c - SCdaemon command handler
  * Copyright (C) 2001, 2002, 2003, 2004, 2005,
- *               2007, 2008, 2009  Free Software Foundation, Inc.
+ *               2007, 2008, 2009, 2011  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -62,32 +62,37 @@
               || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED  \
               || gpg_err_code (_r) == GPG_ERR_CARD_RESET    \
               || gpg_err_code (_r) == GPG_ERR_ENODEV )      \
-            update_card_removed ((c)->reader_slot, 1);      \
+            update_card_removed ((c)->server_local->vreader_idx, 1);      \
        } while (0)
 
-#define IS_LOCKED(c)                                                     \
-     (locked_session && locked_session != (c)->server_local              \
-      && (c)->reader_slot != -1 && locked_session->ctrl_backlink         \
-      && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
+#define IS_LOCKED(c)                                                    \
+  (locked_session                                                       \
+   && locked_session != (c)->server_local                               \
+   && (c)->server_local->vreader_idx != -1                              \
+   && locked_session->ctrl_backlink                                     \
+   && ((c)->server_local->vreader_idx                                   \
+       == locked_session->ctrl_backlink->server_local->vreader_idx))
 
 
 /* Flag indicating that the reader has been disabled.  */
 static int reader_disabled;
 
 
-/* This structure is used to keep track of open readers (slots). */
-struct slot_status_s
+/* This structure is used to keep track of user readers.  To
+   eventually accommodate this structure for RFID cards, where more
+   than one card is used per reader, we name it virtual reader.  */
+struct vreader_s
 {
   int valid;  /* True if the other objects are valid. */
-  int slot;   /* Slot number of the reader or -1 if not open. */
+  int slot;   /* APDU slot number of the reader or -1 if not open. */
 
   int reset_failed; /* A reset failed. */
 
   int any;    /* Flag indicating whether any status check has been
                  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 the slot. */
+  unsigned int status;  /* Last status of the reader. */
+  unsigned int changed; /* Last change counter of the reader. */
 };
 
 
@@ -114,6 +119,9 @@ struct server_local_s
   int event_signal;             /* Or 0 if not used. */
 #endif
 
+  /* Index into the vreader table (command.c) or -1 if not open. */
+  int vreader_idx;
+
   /* True if the card has been removed and a reset is required to
      continue operation. */
   int card_removed;
@@ -132,10 +140,8 @@ struct server_local_s
 };
 
 
-/* The table with information on all used slots.  FIXME: This is a
-   different slot number than the one used by the APDU layer, and
-   should be renamed.  */
-static struct slot_status_s slot_table[10];
+/* The table with information on all used virtual readers.  */
+static struct vreader_s vreader_table[10];
 
 
 /* To keep track of all running sessions, we link all active server
@@ -174,25 +180,37 @@ initialize_module_command (void)
 }
 
 
-/* Update the CARD_REMOVED element of all sessions using the reader
-   given by SLOT to VALUE.  */
+/* Update the CARD_REMOVED element of all sessions using the virtual
+   reader given by VRDR to VALUE.  */
 static void
-update_card_removed (int slot, int value)
+update_card_removed (int vrdr, int value)
 {
   struct server_local_s *sl;
 
   for (sl=session_list; sl; sl = sl->next_session)
     if (sl->ctrl_backlink
-        && sl->ctrl_backlink->reader_slot == slot)
+        && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
       {
         sl->card_removed = value;
       }
   /* Let the card application layer know about the removal.  */
   if (value)
-    application_notify_card_reset (slot);
+    application_notify_card_reset (vrdr);
 }
 
 
+/* Helper to return the slot number for a given virtual reader index
+   VRDR.  In case on an error -1 is returned.  */
+static int
+vreader_slot (int vrdr)
+{
+  if (vrdr == -1 || !(vrdr >= 0 && vrdr < DIM(vreader_table)))
+    return -1;
+  if (!vreader_table [vrdr].valid)
+    return -1;
+  return vreader_table[vrdr].slot;
+}
+
 
 /* Check whether the option NAME appears in LINE.  Returns 1 or 0. */
 static int
@@ -279,9 +297,9 @@ hex_to_buffer (const char *string, size_t *r_length)
 static void
 do_reset (ctrl_t ctrl, int send_reset)
 {
-  int slot = ctrl->reader_slot;
+  int vrdr = ctrl->server_local->vreader_idx;
 
-  if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
+  if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
     BUG ();
 
   /* If there is an active application, release it.  Tell all other
@@ -297,7 +315,7 @@ do_reset (ctrl_t ctrl, int send_reset)
 
           for (sl=session_list; sl; sl = sl->next_session)
             if (sl->ctrl_backlink
-                && sl->ctrl_backlink->reader_slot == slot)
+                && sl->ctrl_backlink->server_local->vreader_idx == vrdr)
               {
                 sl->app_ctx_marked_for_release = 1;
               }
@@ -306,13 +324,13 @@ do_reset (ctrl_t ctrl, int send_reset)
 
   /* 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 (vrdr != -1 && send_reset && !IS_LOCKED (ctrl) )
     {
-      if (apdu_reset (slot))
+      if (apdu_reset (vreader_table[vrdr].slot))
         {
-          slot_table[slot].valid = 0;
+          vreader_table[vrdr].valid = 0;
         }
-      application_notify_card_reset (slot);
+      application_notify_card_reset (vrdr);
     }
 
   /* If we hold a lock, unlock now. */
@@ -325,21 +343,21 @@ do_reset (ctrl_t ctrl, int send_reset)
   /* 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
+     required to get hold of the new status of the card in the vreader
      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;
+      log_error ("failed to acquire status_file_update lock\n");
+      ctrl->server_local->vreader_idx = -1;
       return;
     }
   update_reader_status_file (0);  /* Update slot status table.  */
-  update_card_removed (slot, 0);  /* Clear card_removed flag.  */
+  update_card_removed (vrdr, 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 the update_card_removed above does its job.  */
-  ctrl->reader_slot = -1;
+  ctrl->server_local->vreader_idx = -1;
 }
 
 
@@ -379,35 +397,38 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
 }
 
 
-/* Return the slot of the current reader or open the reader if no
-   other sessions are using a reader.  Note, that we currently support
+/* Return the index of the current reader or open the reader if no
+   other sessions are using that reader.  If it is not possible to
+   open the reader -1 is returned.  Note, that we currently support
    only one reader but most of the code (except for this function)
    should be able to cope with several readers.  */
 static int
-get_reader_slot (void)
+get_current_reader (void)
 {
-  struct slot_status_s *ss;
+  struct vreader_s *vr;
 
-  ss = &slot_table[0]; /* One reader for now. */
+  /* We only support one reader for now.  */
+  vr = &vreader_table[0];
 
-  /* Initialize the item if needed. */
-  if (!ss->valid)
+  /* Initialize the vreader item if not yet done. */
+  if (!vr->valid)
     {
-      ss->slot = -1;
-      ss->valid = 1;
+      vr->slot = -1;
+      vr->valid = 1;
     }
 
   /* Try to open the reader. */
-  if (ss->slot == -1)
+  if (vr->slot == -1)
     {
       int no_service_flag;
-      ss->slot = apdu_open_reader (opt.reader_port, &no_service_flag);
+
+      vr->slot = apdu_open_reader (opt.reader_port, &no_service_flag);
 
       /* If we still don't have a slot, we have no readers.
 	 Invalidate for now until a reader is attached. */
-      if(ss->slot == -1)
+      if (vr->slot == -1)
 	{
-	  ss->valid = 0;
+	  vr->valid = 0;
 	}
 
       if (no_service_flag)
@@ -417,8 +438,8 @@ get_reader_slot (void)
         }
     }
 
-  /* Return the slot_table index.  */
-  return 0;
+  /* Return the vreader index or -1.  */
+  return vr->valid ? 0 : -1;
 }
 
 
@@ -427,7 +448,7 @@ static gpg_error_t
 open_card (ctrl_t ctrl, const char *apptype)
 {
   gpg_error_t err;
-  int slot;
+  int vrdr;
 
   if (reader_disabled)
     return gpg_error (GPG_ERR_NOT_OPERATIONAL);
@@ -455,21 +476,25 @@ open_card (ctrl_t ctrl, const char *apptype)
      need to check that the client didn't requested a specific
      application different from the one in use before we continue. */
   if (ctrl->app_ctx)
-    return check_application_conflict (ctrl, apptype);
+    {
+      return check_application_conflict
+        (ctrl, vreader_slot (ctrl->server_local->vreader_idx), apptype);
+    }
 
-  /* Setup the slot and select the application.  */
-  if (ctrl->reader_slot != -1)
-    slot = ctrl->reader_slot;
+  /* Setup the vreader and select the application.  */
+  if (ctrl->server_local->vreader_idx != -1)
+    vrdr = ctrl->server_local->vreader_idx;
   else
-    slot = get_reader_slot ();
-  ctrl->reader_slot = slot;
-  if (slot == -1)
+    vrdr = get_current_reader ();
+  ctrl->server_local->vreader_idx = vrdr;
+  if (vrdr == -1)
     err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD);
   else
     {
       /* Fixme: We should move the apdu_connect call to
          select_application.  */
       int sw;
+      int slot = vreader_slot (vrdr);
 
       ctrl->server_local->disconnect_allowed = 0;
       sw = apdu_connect (slot);
@@ -1615,8 +1640,8 @@ static const char hlp_getinfo[] =
   "\n"
   "socket_name - Return the name of the socket.\n"
   "\n"
-  "status - Return the status of the current slot (in the future, may\n"
-  "also return the status of all slots).  The status is a list of\n"
+  "status - Return the status of the current reader (in the future, may\n"
+  "also return the status of all readers).  The status is a list of\n"
   "one-character flags.  The following flags are currently defined:\n"
   "  'u'  Usable card present.  This is the normal state during operation.\n"
   "  'r'  Card removed.  A reset is necessary.\n"
@@ -1660,22 +1685,22 @@ cmd_getinfo (assuan_context_t ctx, char *line)
   else if (!strcmp (line, "status"))
     {
       ctrl_t ctrl = assuan_get_pointer (ctx);
-      int slot = ctrl->reader_slot;
+      int vrdr = ctrl->server_local->vreader_idx;
       char flag = 'r';
 
-      if (!ctrl->server_local->card_removed && slot != -1)
+      if (!ctrl->server_local->card_removed && vrdr != -1)
 	{
-	  struct slot_status_s *ss;
+	  struct vreader_s *vr;
 
-	  if (!(slot >= 0 && slot < DIM(slot_table)))
+	  if (!(vrdr >= 0 && vrdr < DIM(vreader_table)))
 	    BUG ();
 
-	  ss = &slot_table[slot];
+	  vr = &vreader_table[vrdr];
 
-	  if (!ss->valid)
+	  if (!vr->valid)
 	    BUG ();
 
-	  if (ss->any && (ss->status & 1))
+	  if (vr->any && (vr->status & 1))
 	    flag = 'u';
 	}
       rc = assuan_send_data (ctx, &flag, 1);
@@ -1790,6 +1815,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
   int handle_more;
   const char *s;
   size_t exlen;
+  int slot;
 
   with_atr = has_option (line, "--atr");
   handle_more = has_option (line, "--more");
@@ -1812,13 +1838,15 @@ cmd_apdu (assuan_context_t ctx, char *line)
   if ((rc = open_card (ctrl, NULL)))
     return rc;
 
+  slot = vreader_slot (ctrl->server_local->vreader_idx);
+
   if (with_atr)
     {
       unsigned char *atr;
       size_t atrlen;
       char hexbuf[400];
 
-      atr = apdu_get_atr (ctrl->reader_slot, &atrlen);
+      atr = apdu_get_atr (slot, &atrlen);
       if (!atr || atrlen > sizeof hexbuf - 2 )
         {
           rc = gpg_error (GPG_ERR_INV_CARD);
@@ -1840,7 +1868,7 @@ cmd_apdu (assuan_context_t ctx, char *line)
       unsigned char *result = NULL;
       size_t resultlen;
 
-      rc = apdu_send_direct (ctrl->reader_slot, exlen,
+      rc = apdu_send_direct (slot, exlen,
                              apdu, apdulen, handle_more,
                              &result, &resultlen);
       if (rc)
@@ -1990,12 +2018,13 @@ scd_command_handler (ctrl_t ctrl, int fd)
   session_list = ctrl->server_local;
   ctrl->server_local->ctrl_backlink = ctrl;
   ctrl->server_local->assuan_ctx = ctx;
+  ctrl->server_local->vreader_idx = -1;
 
   /* We open the reader right at startup so that the ticker is able to
      update the status file. */
-  if (ctrl->reader_slot == -1)
+  if (ctrl->server_local->vreader_idx == -1)
     {
-      ctrl->reader_slot = get_reader_slot ();
+      ctrl->server_local->vreader_idx = get_current_reader ();
     }
 
   /* Command processing loop. */
@@ -2197,32 +2226,33 @@ update_reader_status_file (int set_card_removed_flag)
   int idx;
   unsigned int status, changed;
 
-  /* Make sure that the reader has been opened.  Like get_reader_slot,
+  /* Make sure that a reader has been opened.  Like get_current_reader,
      this part of the code assumes that there is only one reader.  */
-  if (!slot_table[0].valid)
-    (void)get_reader_slot ();
+  if (!vreader_table[0].valid)
+    (void)get_current_reader ();
 
   /* Note, that we only try to get the status, because it does not
      make sense to wait here for a operation to complete.  If we are
      busy working with a card, delays in the status file update should
      be acceptable. */
-  for (idx=0; idx < DIM(slot_table); idx++)
+  for (idx=0; idx < DIM(vreader_table); idx++)
     {
-      struct slot_status_s *ss = slot_table + idx;
+      struct vreader_s *vr = vreader_table + idx;
       struct server_local_s *sl;
       int sw_apdu;
 
-      if (!ss->valid || ss->slot == -1)
+      if (!vr->valid || vr->slot == -1)
         continue; /* Not valid or reader not yet open. */
 
-      sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed);
+      sw_apdu = apdu_get_status (vr->slot, 0, &status, &changed);
       if (sw_apdu == SW_HOST_NO_READER)
         {
           /* Most likely the _reader_ has been unplugged.  */
-	  apdu_close_reader(ss->slot);
-	  ss->valid = 0;
+	  apdu_close_reader (vr->slot);
+          vr->slot = -1;
+	  vr->valid = 0;
           status = 0;
-          changed = ss->changed;
+          changed = vr->changed;
         }
       else if (sw_apdu)
         {
@@ -2230,21 +2260,21 @@ update_reader_status_file (int set_card_removed_flag)
           continue;
         }
 
-      if (!ss->any || ss->status != status || ss->changed != changed )
+      if (!vr->any || vr->status != status || vr->changed != changed )
         {
           char *fname;
           char templ[50];
           FILE *fp;
 
-          log_info ("updating slot %d status: 0x%04X->0x%04X (%u->%u)\n",
-                    ss->slot, ss->status, status, ss->changed, changed);
-          ss->status = status;
-          ss->changed = changed;
+          log_info ("updating reader %d (%d) status: 0x%04X->0x%04X (%u->%u)\n",
+                    idx, vr->slot, vr->status, status, vr->changed, changed);
+          vr->status = status;
+          vr->changed = changed;
 
-	  /* FIXME: Should this be IDX instead of ss->slot?  This
+	  /* FIXME: Should this be IDX instead of vr->slot?  This
 	     depends on how client sessions will associate the reader
 	     status with their session.  */
-          snprintf (templ, sizeof templ, "reader_%d.status", ss->slot);
+          snprintf (templ, sizeof templ, "reader_%d.status", vr->slot);
           fname = make_filename (opt.homedir, templ, NULL );
           fp = fopen (fname, "w");
           if (fp)
@@ -2272,8 +2302,8 @@ update_reader_status_file (int set_card_removed_flag)
                 envs[0] = envstr;
                 envs[1] = NULL;
 
-                sprintf (numbuf1, "%d", ss->slot);
-                sprintf (numbuf2, "0x%04X", ss->status);
+                sprintf (numbuf1, "%d", vr->slot);
+                sprintf (numbuf2, "0x%04X", vr->status);
                 sprintf (numbuf3, "0x%04X", status);
                 args[0] = "--reader-port";
                 args[1] = numbuf1;
@@ -2301,10 +2331,10 @@ update_reader_status_file (int set_card_removed_flag)
           /* 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 && set_card_removed_flag)
+          if (vr->any && set_card_removed_flag)
             update_card_removed (idx, 1);
 
-          ss->any = 1;
+          vr->any = 1;
 
           /* Send a signal to all clients who applied for it.  */
           send_client_notifications ();
@@ -2320,8 +2350,9 @@ update_reader_status_file (int set_card_removed_flag)
             {
               /* FIXME: Use a real timeout.  */
               /* At least one connection and all allow a disconnect.  */
-              log_info ("disconnecting card in slot %d\n", ss->slot);
-              apdu_disconnect (ss->slot);
+              log_info ("disconnecting card in reader %d (%d)\n",
+                        idx, vr->slot);
+              apdu_disconnect (vr->slot);
             }
         }
 
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 0999847..b4eee39 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -913,7 +913,7 @@ scd_exit (int rc)
 static void
 scd_init_default_ctrl (ctrl_t ctrl)
 {
-  ctrl->reader_slot = -1;
+  (void)ctrl;
 }
 
 static void
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 0cf2f24..4c0a663 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -97,9 +97,6 @@ struct server_control_s
   /* Local data of the server; used only in command.c. */
   struct server_local_s *server_local;
 
-  /* Slot of the open reader or -1 if not open. */
-  int reader_slot;
-
   /* The application context used with this connection or NULL if none
      associated.  Note that this is shared with the other connections:
      All connections accessing the same reader are using the same

-----------------------------------------------------------------------

Summary of changes:
 common/asshelp.c  |   13 +++
 common/asshelp.h  |    1 +
 doc/scdaemon.texi |   47 +++++++-----
 scd/apdu.c        |  205 ++++++++++++++++++++++++++++++++---------------
 scd/apdu.h        |    1 -
 scd/app-common.h  |    3 +-
 scd/app.c         |    7 +-
 scd/command.c     |  228 +++++++++++++++++++++++++++++++----------------------
 scd/scdaemon.c    |    7 ++-
 scd/scdaemon.h    |    7 +-
 10 files changed, 331 insertions(+), 188 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list