tools: Minor fix to the usbmon debugging tool.
[gnupg.git] / tools / ccidmon.c
index 03bfc43..92673f4 100644 (file)
 # define PACKAGE_BUGREPORT "devnull@example.org"
 #endif
 #define PGM "ccidmon"
+#ifndef GNUPG_NAME
+# define GNUPG_NAME "GnuPG"
+#endif
 
 /* Option flags. */
 static int verbose;
 static int debug;
 static int skip_escape;
 static int usb_bus, usb_dev;
+static int sniffusb;
+
 
 /* Error counter.  */
 static int any_error;
@@ -92,10 +97,10 @@ enum {
 };
 
 
-#define digitp(p)   ((p) >= '0' && (p) <= '9')
+#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
 #define hexdigitp(a) (digitp (a)                     \
-                      || ((a) >= 'A' && (a) <= 'F')  \
-                      || ((a) >= 'a' && (a) <= 'f'))
+                      || (*(a) >= 'A' && *(a) <= 'F')  \
+                      || (*(a) >= 'a' && *(a) <= 'f'))
 #define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
 #define xtoi_1(p)   ((p) <= '9'? ((p)- '0'): \
                      (p) <= 'F'? ((p)-'A'+10):((p)-'a'+10))
@@ -140,19 +145,19 @@ err (const char *format, ...)
 
 /* Convert a little endian stored 4 byte value into an unsigned
    integer. */
-static unsigned int 
+static unsigned int
 convert_le_u32 (const unsigned char *buf)
 {
-  return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); 
+  return buf[0] | (buf[1] << 8) | (buf[2] << 16) | ((unsigned int)buf[3] << 24);
 }
 
 
 /* Convert a little endian stored 2 byte value into an unsigned
    integer. */
-static unsigned int 
+static unsigned int
 convert_le_u16 (const unsigned char *buf)
 {
-  return buf[0] | (buf[1] << 8); 
+  return buf[0] | (buf[1] << 8);
 }
 
 
@@ -170,7 +175,7 @@ print_pr_data (const unsigned char *data, size_t datalen, size_t off)
         {
           if (needlf)
             putchar ('\n');
-          printf ("  [%04d] ", off);
+          printf ("  [%04lu] ", (unsigned long)off);
         }
       printf (" %02X", data[off]);
       needlf = 1;
@@ -180,7 +185,7 @@ print_pr_data (const unsigned char *data, size_t datalen, size_t off)
     putchar ('\n');
 }
 
+
 static void
 print_p2r_header (const char *name, const unsigned char *msg, size_t msglen)
 {
@@ -355,7 +360,11 @@ print_p2r_setdatarate (const unsigned char *msg, size_t msglen)
 static void
 print_p2r_unknown (const unsigned char *msg, size_t msglen)
 {
-  print_p2r_header ("Unknown PC_to_RDR command", msg, msglen);
+  char buf[100];
+
+  snprintf (buf, sizeof buf, "Unknown PC_to_RDR command 0x%02X",
+            msglen? msg[0]:0);
+  print_p2r_header (buf, msg, msglen);
   if (msglen < 10)
     return;
   print_pr_data (msg, msglen, 0);
@@ -460,7 +469,7 @@ print_r2p_slotstatus (const unsigned char *msg, size_t msglen)
           msg[9] == 3? " (stopped)":"");
   print_pr_data (msg, msglen, 10);
 }
-  
+
 
 static void
 print_r2p_parameters (const unsigned char *msg, size_t msglen)
@@ -519,7 +528,11 @@ print_r2p_datarate (const unsigned char *msg, size_t msglen)
 static void
 print_r2p_unknown (const unsigned char *msg, size_t msglen)
 {
-  print_r2p_header ("Unknown RDR_to_PC command", msg, msglen);
+  char buf[100];
+
+  snprintf (buf, sizeof buf, "Unknown RDR_to_PC command 0x%02X",
+            msglen? msg[0]:0);
+  print_r2p_header (buf, msg, msglen);
   if (msglen < 10)
     return;
   printf ("  bMessageType ......: %02X\n", msg[0]);
@@ -561,7 +574,7 @@ flush_data (void)
 {
   if (!databuffer.count)
     return;
-  
+
   if (verbose)
     printf ("Address: %s\n", databuffer.address);
   if (databuffer.is_bi)
@@ -598,14 +611,14 @@ collect_data (char *hexdata, const char *address, unsigned int lineno)
     {
       if (ascii_isspace (*s))
         continue;
-      if (!hexdigitp (*s))
+      if (!hexdigitp (s))
         {
           err ("invalid hex digit in line %u - line skipped", lineno);
           break;
         }
       value = xtoi_1 (*s) * 16;
       s++;
-      if (!hexdigitp (*s))
+      if (!hexdigitp (s))
         {
           err ("invalid hex digit in line %u - line skipped", lineno);
           break;
@@ -631,7 +644,7 @@ parse_line (char *line, unsigned int lineno)
   char *event_type, *address, *data, *status, *datatag;
 
   if (debug)
-    printf ("line[%u] =`%s'\n", lineno, line);
+    printf ("line[%u] ='%s'\n", lineno, line);
 
   p = strtok (line, " ");
   if (!p)
@@ -674,7 +687,7 @@ parse_line (char *line, unsigned int lineno)
   p = strtok (NULL, " ");
   if (!p)
     return; /* No data length.  */
-  
+
   datatag = strtok (NULL, " ");
   if (datatag && *datatag == '=')
     {
@@ -685,6 +698,75 @@ parse_line (char *line, unsigned int lineno)
 
 
 static void
+parse_line_sniffusb (char *line, unsigned int lineno)
+{
+  char *p;
+
+  if (debug)
+    printf ("line[%u] ='%s'\n", lineno, line);
+
+  p = strtok (line, " \t");
+  if (!p)
+    return;
+  p = strtok (NULL, " \t");
+  if (!p)
+    return;
+  p = strtok (NULL, " \t");
+  if (!p)
+    return;
+
+  if (hexdigitp (p+0) && hexdigitp (p+1)
+      && hexdigitp (p+2) && hexdigitp (p+3)
+      && p[4] == ':' && !p[5])
+    {
+      size_t length;
+      unsigned int value;
+
+      length = databuffer.count;
+      while ((p=strtok (NULL, " \t")))
+        {
+          if (!hexdigitp (p+0) || !hexdigitp (p+1))
+            {
+              err ("invalid hex digit in line %u (%s)", lineno,p);
+              break;
+            }
+          value = xtoi_1 (p[0]) * 16 + xtoi_1 (p[1]);
+
+          if (length >= sizeof (databuffer.data))
+            {
+              err ("too much data at line %u - can handle only up to % bytes",
+                   lineno, sizeof (databuffer.data));
+              break;
+            }
+          databuffer.data[length++] = value;
+        }
+      databuffer.count = length;
+
+    }
+  else if (!strcmp (p, "TransferFlags"))
+    {
+      flush_data ();
+
+      *databuffer.address = 0;
+      while ((p=strtok (NULL, " \t(,)")))
+        {
+          if (!strcmp (p, "USBD_TRANSFER_DIRECTION_IN"))
+            {
+              databuffer.is_bi = 1;
+              break;
+            }
+          else if (!strcmp (p, "USBD_TRANSFER_DIRECTION_OUT"))
+            {
+              databuffer.is_bi = 0;
+              break;
+            }
+        }
+    }
+
+}
+
+
+static void
 parse_input (FILE *fp)
 {
   char line[2000];
@@ -701,7 +783,10 @@ parse_input (FILE *fp)
         err ("line number %u too long or last line not terminated", lineno);
       if (length && line[length - 1] == '\r')
        line[--length] = 0;
-      parse_line (line, lineno);
+      if (sniffusb)
+        parse_line_sniffusb (line, lineno);
+      else
+        parse_line (line, lineno);
     }
   flush_data ();
   if (ferror (fp))
@@ -709,11 +794,11 @@ parse_input (FILE *fp)
 }
 
 
-int 
+int
 main (int argc, char **argv)
 {
   int last_argc = -1;
+
   if (argc)
     {
       argc--; argv++;
@@ -728,7 +813,7 @@ main (int argc, char **argv)
         }
       else if (!strcmp (*argv, "--version"))
         {
-          fputs (PGM " (GnuPG) " PACKAGE_VERSION "\n", stdout);
+          fputs (PGM " (" GNUPG_NAME ") " PACKAGE_VERSION "\n", stdout);
           exit (0);
         }
       else if (!strcmp (*argv, "--help"))
@@ -736,6 +821,7 @@ main (int argc, char **argv)
           puts ("Usage: " PGM " [BUS:DEV]\n"
                 "Parse the output of usbmod assuming it is CCID compliant.\n\n"
                 "  --skip-escape  do not show escape packets\n"
+                "  --sniffusb     Assume output from Sniffusb.exe\n"
                 "  --verbose      enable extra informational output\n"
                 "  --debug        enable additional debug output\n"
                 "  --help         display this help and exit\n\n"
@@ -757,15 +843,22 @@ main (int argc, char **argv)
           skip_escape = 1;
           argc--; argv++;
         }
-    }          
-  if (argc > 1)
+      else if (!strcmp (*argv, "--sniffusb"))
+        {
+          sniffusb = 1;
+          argc--; argv++;
+        }
+    }
+
+  if (argc && sniffusb)
+    die ("no arguments expected when using --sniffusb\n");
+  else if (argc > 1)
     die ("usage: " PGM " [BUS:DEV]  (try --help for more information)\n");
 
   if (argc == 1)
     {
       const char *s = strchr (argv[0], ':');
-      
+
       usb_bus = atoi (argv[0]);
       if (s)
         usb_dev =  atoi (s+1);