gpgscm: Merge 'opexe_2'.
[gnupg.git] / scd / command.c
index cad8c6e..56fdf74 100644 (file)
@@ -40,8 +40,8 @@
 #ifdef HAVE_LIBUSB
 #include "ccid-driver.h"
 #endif
-#include "asshelp.h"
-#include "server-help.h"
+#include "../common/asshelp.h"
+#include "../common/server-help.h"
 
 /* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
 #define MAXLEN_PIN 100
@@ -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, 0);
+
   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);
@@ -900,7 +900,7 @@ cmd_getattr (assuan_context_t ctx, char *line)
 static const char hlp_setattr[] =
   "SETATTR <name> <value> \n"
   "\n"
-  "This command is used to store data on a smartcard.  The allowed\n"
+  "This command is used to store data on a smartcard.  The allowed\n"
   "names and values are depend on the currently selected smartcard\n"
   "application.  NAME and VALUE must be percent and '+' escaped.\n"
   "\n"
@@ -954,7 +954,7 @@ static const char hlp_writecert[] =
   "application. The actual certifciate is requested using the inquiry\n"
   "\"CERTDATA\" and needs to be provided in its raw (e.g. DER) form.\n"
   "\n"
-  "In almost all cases a PIN will be requested.  See the related\n"
+  "In almost all cases a PIN will be requested.  See the related\n"
   "writecert function of the actually used application (app-*.c) for\n"
   "details.";
 static gpg_error_t
@@ -1007,7 +1007,7 @@ cmd_writecert (assuan_context_t ctx, char *line)
 static const char hlp_writekey[] =
   "WRITEKEY [--force] <keyid> \n"
   "\n"
-  "This command is used to store a secret key on a smartcard.  The\n"
+  "This command is used to store a secret key on a smartcard.  The\n"
   "allowed keyids depend on the currently selected smartcard\n"
   "application. The actual keydata is requested using the inquiry\n"
   "\"KEYDATA\" and need to be provided without any protection.  With\n"
@@ -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);
@@ -1492,7 +1495,7 @@ cmd_restart (assuan_context_t ctx, char *line)
   if (app)
     {
       ctrl->app_ctx = NULL;
-      release_application (app);
+      release_application (app, 0);
     }
   if (locked_session && ctrl->server_local == locked_session)
     {
@@ -1919,7 +1922,7 @@ send_client_notifications (app_t app, int removal)
           {
             sl->ctrl_backlink->app_ctx = NULL;
             sl->card_removed = 1;
-            release_application (app);
+            release_application (app, 1);
           }
 
         if (!sl->event_signal || !sl->assuan_ctx)