scd: Fix regression tracking the connection count.
[gnupg.git] / scd / command.c
index cad8c6e..bd7e803 100644 (file)
@@ -217,6 +217,7 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
   gpg_error_t err;
   unsigned char *serialno_bin = NULL;
   size_t serialno_bin_len = 0;
+  app_t app = ctrl->app_ctx;
 
   /* If we are already initialized for one specific application we
      need to check that the client didn't requested a specific
@@ -224,6 +225,10 @@ open_card_with_request (ctrl_t ctrl, const char *apptype, const char *serialno)
   if (apptype && ctrl->app_ctx)
     return check_application_conflict (apptype, ctrl->app_ctx);
 
+  /* Re-scan USB devices.  Release APP, before the scan.  */
+  ctrl->app_ctx = NULL;
+  release_application (app);
+
   if (serialno)
     serialno_bin = hex_to_buffer (serialno, &serialno_bin_len);
 
@@ -264,7 +269,6 @@ cmd_serialno (assuan_context_t ctx, char *line)
   struct server_local_s *sl;
   int rc = 0;
   char *serial;
-  time_t stamp;
   const char *demand;
 
   if ( IS_LOCKED (ctrl) )
@@ -302,12 +306,11 @@ cmd_serialno (assuan_context_t ctx, char *line)
         c->server_local->card_removed = 0;
     }
 
-  rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
-  if (rc)
-    return rc;
+  serial = app_get_serialno (ctrl->app_ctx);
+  if (!serial)
+    return gpg_error (GPG_ERR_INV_VALUE);
 
-  rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
-                            serial, (unsigned long)stamp);
+  rc = assuan_write_status (ctx, "SERIALNO", serial);
   xfree (serial);
   return rc;
 }
@@ -320,7 +323,7 @@ static const char hlp_learn[] =
   "used without the force options, the command might do an INQUIRE\n"
   "like this:\n"
   "\n"
-  "   INQUIRE KNOWNCARDP <hexstring_with_serialNumber> <timestamp>\n"
+  "   INQUIRE KNOWNCARDP <hexstring_with_serialNumber>\n"
   "\n"
   "The client should just send an \"END\" if the processing should go on\n"
   "or a \"CANCEL\" to force the function to terminate with a Cancel\n"
@@ -400,7 +403,6 @@ cmd_learn (assuan_context_t ctx, char *line)
     {
       const char *reader;
       char *serial;
-      time_t stamp;
       app_t app = ctrl->app_ctx;
 
       if (!app)
@@ -412,12 +414,11 @@ cmd_learn (assuan_context_t ctx, char *line)
       send_status_direct (ctrl, "READER", reader);
       /* No need to free the string of READER.  */
 
-      rc = app_get_serial_and_stamp (ctrl->app_ctx, &serial, &stamp);
-      if (rc)
-        return rc;
+      serial = app_get_serialno (ctrl->app_ctx);
+      if (!serial)
+       return gpg_error (GPG_ERR_INV_VALUE);
 
-      rc = print_assuan_status (ctx, "SERIALNO", "%s %lu",
-                                serial, (unsigned long)stamp);
+      rc = assuan_write_status (ctx, "SERIALNO", serial);
       if (rc < 0)
         {
           xfree (serial);
@@ -428,8 +429,7 @@ cmd_learn (assuan_context_t ctx, char *line)
         {
           char *command;
 
-          rc = gpgrt_asprintf (&command, "KNOWNCARDP %s %lu",
-                               serial, (unsigned long)stamp);
+          rc = gpgrt_asprintf (&command, "KNOWNCARDP %s", serial);
           if (rc < 0)
             {
               xfree (serial);
@@ -1372,30 +1372,26 @@ static const char hlp_getinfo[] =
   "Multi purpose command to return certain information.  \n"
   "Supported values of WHAT are:\n"
   "\n"
-  "version     - Return the version of the program.\n"
-  "pid         - Return the process id of the server.\n"
-  "\n"
-  "socket_name - Return the name of the socket.\n"
-  "\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"
-  "These flags are exclusive.\n"
-  "\n"
-  "reader_list - Return a list of detected card readers.  Does\n"
-  "              currently only work with the internal CCID driver.\n"
-  "\n"
-  "deny_admin  - Returns OK if admin commands are not allowed or\n"
-  "              GPG_ERR_GENERAL if admin commands are allowed.\n"
-  "\n"
-  "app_list    - Return a list of supported applications.  One\n"
-  "              application per line, fields delimited by colons,\n"
-  "              first field is the name.\n"
-  "\n"
-  "card_list   - Return a list of serial numbers of active cards,\n"
-  "              using a status response.";
+  "  version     - Return the version of the program.\n"
+  "  pid         - Return the process id of the server.\n"
+  "  socket_name - Return the name of the socket.\n"
+  "  connections - Return number of active connections.\n"
+  "  status      - Return the status of the current reader (in the future,\n"
+  "                may also return the status of all readers).  The status\n"
+  "                is a list of one-character flags.  The following flags\n"
+  "                are currently defined:\n"
+  "                  'u'  Usable card present.\n"
+  "                  'r'  Card removed.  A reset is necessary.\n"
+  "                These flags are exclusive.\n"
+  "  reader_list - Return a list of detected card readers.  Does\n"
+  "                currently only work with the internal CCID driver.\n"
+  "  deny_admin  - Returns OK if admin commands are not allowed or\n"
+  "                GPG_ERR_GENERAL if admin commands are allowed.\n"
+  "  app_list    - Return a list of supported applications.  One\n"
+  "                application per line, fields delimited by colons,\n"
+  "                first field is the name.\n"
+  "  card_list   - Return a list of serial numbers of active cards,\n"
+  "                using a status response.";
 static gpg_error_t
 cmd_getinfo (assuan_context_t ctx, char *line)
 {
@@ -1422,6 +1418,13 @@ cmd_getinfo (assuan_context_t ctx, char *line)
       else
         rc = gpg_error (GPG_ERR_NO_DATA);
     }
+  else if (!strcmp (line, "connections"))
+    {
+      char numbuf[20];
+
+      snprintf (numbuf, sizeof numbuf, "%d", get_active_connection_count ());
+      rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
+    }
   else if (!strcmp (line, "status"))
     {
       ctrl_t ctrl = assuan_get_pointer (ctx);