* plaintext.c (handle_plaintext): Properly handle a --max-output of zero
[gnupg.git] / g10 / keyring.c
index 3160b1c..093bb00 100644 (file)
@@ -1,5 +1,5 @@
 /* keyring.c - keyring file handling
- * Copyright (C) 2001 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -190,25 +190,28 @@ update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off)
     }
 }
 
-
-
-\f
 /* 
- * Register a filename for plain keyring files.  Returns a pointer to
- * be used to create a handles etc or NULL to indicate that it has
- * already been registered */
-void *
-keyring_register_filename (const char *fname, int secret)
+ * Register a filename for plain keyring files.  ptr is set to a
+ * pointer to be used to create a handles etc, or the already-issued
+ * pointer if it has already been registered.  The function returns 1
+ * if a new keyring was registered.
+*/
+int
+keyring_register_filename (const char *fname, int secret, void **ptr)
 {
     KR_NAME kr;
 
     if (active_handles)
         BUG (); /* We don't allow that */
 
-    for (kr=kr_names; kr; kr = kr->next) {
+    for (kr=kr_names; kr; kr = kr->next)
+      {
         if ( !compare_filenames (kr->fname, fname) )
-            return NULL; /* already registered */
-    }
+         {
+            *ptr=kr;
+           return 0; /* already registered */
+         }
+      }
 
     kr = m_alloc (sizeof *kr + strlen (fname));
     strcpy (kr->fname, fname);
@@ -224,7 +227,9 @@ keyring_register_filename (const char *fname, int secret)
     if (!kr_offtbl)
       kr_offtbl = new_offset_hash_table ();
 
-    return kr;
+    *ptr=kr;
+
+    return 1;
 }
 
 int
@@ -847,7 +852,8 @@ compare_name (int mode, const char *name, const char *uid, size_t uidlen)
  * for a keyblock which contains one of the keys described in the DESC array.
  */
 int 
-keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
+keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
+               size_t ndesc, size_t *descindex)
 {
   int rc;
   PACKET pkt;
@@ -861,6 +867,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
   PKT_user_id *uid = NULL;
   PKT_public_key *pk = NULL;
   PKT_secret_key *sk = NULL;
+  u32 aki[2];
 
   /* figure out what information we need */
   need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
@@ -963,7 +970,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
     {
       byte afp[MAX_FINGERPRINT_LEN];
       size_t an;
-      u32 aki[2];
 
       if (pkt.pkttype == PKT_PUBLIC_KEY  || pkt.pkttype == PKT_SECRET_KEY) 
         {
@@ -1069,11 +1075,15 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
        }
       free_packet (&pkt);
       continue;
-    found:  
+    found:
+      /* Record which desc we matched on.  Note this value is only
+        meaningful if this function returns with no errors. */
+      if(descindex)
+       *descindex=n;
       for (n=any_skip?0:ndesc; n < ndesc; n++) 
         {
           if (desc[n].skipfnc
-              && desc[n].skipfnc (desc[n].skipfncvalue, aki))
+              && desc[n].skipfnc (desc[n].skipfncvalue, aki, uid))
             break;
         }
       if (n == ndesc)
@@ -1300,7 +1310,7 @@ write_keyblock (IOBUF fp, KBNODE keyblock)
  * This is only done for the public keyrings.
  */
 int
-keyring_rebuild_cache (void *token)
+keyring_rebuild_cache (void *token,int noisy)
 {
   KEYRING_HANDLE hd;
   KEYDB_SEARCH_DESC desc;
@@ -1316,7 +1326,11 @@ keyring_rebuild_cache (void *token)
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_FIRST;
 
-  while ( !(rc = keyring_search (hd, &desc, 1)) )
+  rc=keyring_lock (hd, 1);
+  if(rc)
+    goto leave;
+
+  while ( !(rc = keyring_search (hd, &desc, 1, NULL)) )
     {
       desc.mode = KEYDB_SEARCH_MODE_NEXT;
       resname = keyring_get_resource_name (hd);
@@ -1342,8 +1356,8 @@ keyring_rebuild_cache (void *token)
           if (rc)
             goto leave;
           lastresname = resname;
-          if (!opt.quiet)
-            log_info (_("checking keyring `%s'\n"), resname);
+          if (noisy && !opt.quiet)
+            log_info (_("caching keyring `%s'\n"), resname);
           rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp);
           if (rc)
             goto leave;
@@ -1361,9 +1375,24 @@ keyring_rebuild_cache (void *token)
       /* check all signature to set the signature's cache flags */
       for (node=keyblock; node; node=node->next)
         {
+         /* Note that this doesn't cache the result of a revocation
+            issued by a designated revoker.  This is because the pk
+            in question does not carry the revkeys as we haven't
+            merged the key and selfsigs.  It is questionable whether
+            this matters very much since there are very very few
+            designated revoker revocation packets out there. */
+
           if (node->pkt->pkttype == PKT_SIGNATURE)
             {
-              check_key_signature (keyblock, node, NULL);
+             PKT_signature *sig=node->pkt->pkt.signature;
+
+             if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
+                && (check_digest_algo(sig->digest_algo)
+                    || check_pubkey_algo(sig->pubkey_algo)))
+               sig->flags.checked=sig->flags.valid=0;
+             else
+               check_key_signature (keyblock, node, NULL);
+
               sigcount++;
             }
         }
@@ -1373,8 +1402,8 @@ keyring_rebuild_cache (void *token)
       if (rc)
         goto leave;
 
-      if ( !(++count % 50) && !opt.quiet)
-        log_info(_("%lu keys checked so far (%lu signatures)\n"),
+      if ( !(++count % 50) && noisy && !opt.quiet)
+        log_info(_("%lu keys cached so far (%lu signatures)\n"),
                  count, sigcount );
 
     } /* end main loop */ 
@@ -1385,7 +1414,8 @@ keyring_rebuild_cache (void *token)
       log_error ("keyring_search failed: %s\n", g10_errstr(rc));
       goto leave;
     }
-  log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount );
+  if(noisy || opt.verbose)
+    log_info(_("%lu keys cached (%lu signatures)\n"), count, sigcount );
   if (tmpfp)
     {
       if (iobuf_close (tmpfp))
@@ -1410,6 +1440,7 @@ keyring_rebuild_cache (void *token)
   m_free (tmpfilename);  
   m_free (bakfilename);  
   release_kbnode (keyblock);
+  keyring_lock (hd, 0);
   keyring_release (hd);
   return rc;
 }