* keybox-dump.c (_keybox_dump_file): New arg STATS_ONLY.
authorWerner Koch <wk@gnupg.org>
Fri, 18 Jun 2004 09:53:56 +0000 (09:53 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 18 Jun 2004 09:53:56 +0000 (09:53 +0000)
(update_stats): New.
* kbxutil.c (main): New command --stats.

kbx/ChangeLog
kbx/kbxutil.c
kbx/keybox-defs.h
kbx/keybox-dump.c

index aa39df8..1c3b9e3 100644 (file)
@@ -1,3 +1,9 @@
+2004-06-18  Werner Koch  <wk@gnupg.org>
+
+       * keybox-dump.c (_keybox_dump_file): New arg STATS_ONLY.
+       (update_stats): New.
+       * kbxutil.c (main): New command --stats.
+
 2004-04-23  Werner Koch  <wk@gnupg.org>
 
        * keybox-blob.c (_keybox_update_header_blob): New.
index 7667861..37c1913 100644 (file)
@@ -47,6 +47,7 @@ enum cmd_and_opt_values {
   aFindByFpr,
   aFindByKid,
   aFindByUid,
+  aStats,
 
   oDebug,
   oDebugAll,
@@ -61,15 +62,16 @@ enum cmd_and_opt_values {
 static ARGPARSE_OPTS opts[] = {
   { 300, NULL, 0, N_("@Commands:\n ") },
 
-  { aFindByFpr,  "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" },
-  { aFindByKid,  "find-by-kid", 0, "|KID| find key using it's keyid" },
-  { aFindByUid,  "find-by-uid", 0, "|NAME| find key by user name" },
+/*   { aFindByFpr,  "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */
+/*   { aFindByKid,  "find-by-kid", 0, "|KID| find key using it's keyid" }, */
+/*   { aFindByUid,  "find-by-uid", 0, "|NAME| find key by user name" }, */
+  { aStats,      "stats",       0, "show key statistics" }, 
   
   { 301, NULL, 0, N_("@\nOptions:\n ") },
   
-  { oArmor, "armor",     0, N_("create ascii armored output")},
-  { oArmor, "armour",     0, "@" },
-  { oOutput, "output",    2, N_("use as output file")},
+/*   { oArmor, "armor",     0, N_("create ascii armored output")}, */
+/*   { oArmor, "armour",     0, "@" }, */
+/*   { oOutput, "output",    2, N_("use as output file")}, */
   { oVerbose, "verbose",   0, N_("verbose") },
   { oQuiet,    "quiet",   0, N_("be somewhat more quiet") },
   { oDryRun, "dry-run",   0, N_("do not make any changes") },
@@ -261,6 +263,7 @@ main( int argc, char **argv )
         case aFindByFpr:
         case aFindByKid:
         case aFindByUid:
+        case aStats:
           cmd = pargs.r_opt;
           break;
           
@@ -275,50 +278,65 @@ main( int argc, char **argv )
   if (!cmd)
       { /* default is to list a KBX file */
        if (!argc) 
-          _keybox_dump_file (NULL, stdout);
+          _keybox_dump_file (NULL, 0, stdout);
        else
           {
            for (; argc; argc--, argv++) 
-              _keybox_dump_file (*argv, stdout);
+              _keybox_dump_file (*argv, 0, stdout);
+          }
+      }
+  else if (cmd == aStats )
+    {
+       if (!argc) 
+          _keybox_dump_file (NULL, 1, stdout);
+       else
+          {
+           for (; argc; argc--, argv++) 
+              _keybox_dump_file (*argv, 1, stdout);
           }
     }
 #if 0
-    else if ( cmd == aFindByFpr ) {
-       char *fpr;
-       if ( argc != 2 )
-           wrong_args ("kbxfile foingerprint");
-       fpr = format_fingerprint ( argv[1] );
-       if ( !fpr )
-           log_error ("invalid formatted fingerprint\n");
-       else {
-           kbxfile_search_by_fpr ( argv[0], fpr );
-           gcry_free ( fpr );
-       }
+  else if ( cmd == aFindByFpr ) 
+    {
+      char *fpr;
+      if ( argc != 2 )
+        wrong_args ("kbxfile foingerprint");
+      fpr = format_fingerprint ( argv[1] );
+      if ( !fpr )
+        log_error ("invalid formatted fingerprint\n");
+      else 
+        {
+          kbxfile_search_by_fpr ( argv[0], fpr );
+          gcry_free ( fpr );
+        }
     }
-    else if ( cmd == aFindByKid ) {
-       u32 kid[2];
-       int mode;
-
-       if ( argc != 2 )
-           wrong_args ("kbxfile short-or-long-keyid");
-       mode = format_keyid ( argv[1], kid );
-       if ( !mode )
-           log_error ("invalid formatted keyID\n");
-       else {
-           kbxfile_search_by_kid ( argv[0], kid, mode );
+  else if ( cmd == aFindByKid ) 
+    {
+      u32 kid[2];
+      int mode;
+      
+      if ( argc != 2 )
+        wrong_args ("kbxfile short-or-long-keyid");
+      mode = format_keyid ( argv[1], kid );
+      if ( !mode )
+        log_error ("invalid formatted keyID\n");
+      else
+        {
+          kbxfile_search_by_kid ( argv[0], kid, mode );
        }
     }
-    else if ( cmd == aFindByUid ) {
-       if ( argc != 2 )
-           wrong_args ("kbxfile userID");
-       kbxfile_search_by_uid ( argv[0], argv[1] );
+  else if ( cmd == aFindByUid ) 
+    {
+      if ( argc != 2 )
+        wrong_args ("kbxfile userID");
+      kbxfile_search_by_uid ( argv[0], argv[1] );
     }
 #endif
-    else
-       log_error ("unsupported action\n");
-
-    myexit(0);
-    return 8; /*NEVER REACHED*/
+  else
+      log_error ("unsupported action\n");
+  
+  myexit(0);
+  return 8; /*NEVER REACHED*/
 }
 
 
index 705762c..759289a 100644 (file)
@@ -122,7 +122,7 @@ gpg_err_code_t _keybox_get_flag_location (const unsigned char *buffer,
 
 /*-- keybox-dump.c --*/
 int _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp);
-int _keybox_dump_file (const char *filename, FILE *outfp);
+int _keybox_dump_file (const char *filename, int stats_only, FILE *outfp);
 
 
 /*-- keybox-util.c --*/
index 2fb0984..495fb24 100644 (file)
@@ -323,14 +323,95 @@ _keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
 }
 
 
+struct file_stats_s
+{
+  unsigned long too_short_blobs;
+  unsigned long too_large_blobs;
+  unsigned long total_blob_count;
+  unsigned long empty_blob_count;
+  unsigned long header_blob_count;
+  unsigned long pgp_blob_count;
+  unsigned long x509_blob_count;
+  unsigned long unknown_blob_count;
+  unsigned long non_flagged;
+  unsigned long secret_flagged;
+  unsigned long ephemeral_flagged;
+};
+
+static int
+update_stats (KEYBOXBLOB blob, struct file_stats_s *s)
+{
+  const unsigned char *buffer;
+  size_t length;
+  int type;
+  unsigned long n;
+
+  buffer = _keybox_get_blob_image (blob, &length);
+  if (length < 32)
+    {
+      s->too_short_blobs++;
+      return -1;
+    }
+
+  n = get32( buffer );
+  if (n > length) 
+    s->too_large_blobs++;
+  else
+    length = n;  /* ignore the rest */
+
+  s->total_blob_count++;
+  type = buffer[4];
+  switch (type)
+    {
+    case BLOBTYPE_EMPTY:
+      s->empty_blob_count++;
+      return 0;
+    case BLOBTYPE_HEADER:
+      s->header_blob_count++;
+      return 0;
+    case BLOBTYPE_PGP:
+      s->pgp_blob_count++;
+      break;
+    case BLOBTYPE_X509:
+      s->x509_blob_count++;
+      break;
+    default:
+      s->unknown_blob_count++;
+      return 0;
+    }
+
+  if (length < 40)
+    {
+      s->too_short_blobs++;
+      return -1;
+    }
+  
+  n = get16 (buffer + 6);
+  if (n)
+    {
+      if ((n & 1))
+        s->secret_flagged++;
+      if ((n & 2))
+        s->ephemeral_flagged++;
+    }
+  else
+    s->non_flagged++;
+
+  return 0;
+}
+
+
 \f
 int
-_keybox_dump_file (const char *filename, FILE *outfp)
+_keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
 {
   FILE *fp;
   KEYBOXBLOB blob;
   int rc;
   unsigned long count = 0;
+  struct file_stats_s stats;
+
+  memset (&stats, 0, sizeof stats);
 
   if (!filename)
     {
@@ -348,10 +429,17 @@ _keybox_dump_file (const char *filename, FILE *outfp)
 
   while ( !(rc = _keybox_read_blob (&blob, fp)) )
     {
-      fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
-      _keybox_dump_blob (blob, outfp);
+      if (stats_only)
+        {
+          update_stats (blob, &stats);
+        }
+      else
+        {
+          fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
+          _keybox_dump_blob (blob, outfp);
+          fprintf (outfp, "END-RECORD\n");
+        }
       _keybox_release_blob (blob);
-      fprintf (outfp, "END-RECORD\n");
       count++;
     }
   if (rc == -1)
@@ -361,5 +449,36 @@ _keybox_dump_file (const char *filename, FILE *outfp)
   
   if (fp != stdin)
     fclose (fp);
+
+  if (stats_only)
+    {
+      fprintf (outfp, 
+               "Total number of blobs: %8lu\n"
+               "               header: %8lu\n"
+               "                empty: %8lu\n"
+               "              openpgp: %8lu\n"
+               "                 x509: %8lu\n"
+               "          non flagged: %8lu\n"
+               "       secret flagged: %8lu\n"
+               "    ephemeral flagged: %8lu\n",
+               stats.total_blob_count,
+               stats.header_blob_count,
+               stats.empty_blob_count,
+               stats.pgp_blob_count,
+               stats.x509_blob_count,
+               stats.non_flagged,
+               stats.secret_flagged,
+               stats.ephemeral_flagged);
+        if (stats.unknown_blob_count)
+          fprintf (outfp, "   unknown blob types: %8lu\n",
+                   stats.unknown_blob_count);
+        if (stats.too_short_blobs)
+          fprintf (outfp, "      too short blobs: %8lu\n",
+                   stats.too_short_blobs);
+        if (stats.too_large_blobs)
+          fprintf (outfp, "      too large blobs: %8lu\n",
+                   stats.too_large_blobs);
+    }
+
   return rc;
 }