Moved 1.9 branch to trunk
[gnupg.git] / g10 / keyring.c
1 /* keyring.c - keyring file handling
2  * Copyright (C) 2001, 2004 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31
32 #include "gpg.h"
33 #include "util.h"
34 #include "keyring.h"
35 #include "packet.h"
36 #include "keydb.h" 
37 #include "options.h"
38 #include "main.h" /*for check_key_signature()*/
39 #include "i18n.h"
40
41 /* off_item is a funny named for an object used to keep track of known
42  * keys.  The idea was to use the offset to seek to the known keyblock, but
43  * this is not possible if more than one process is using the keyring.
44  */
45 struct off_item {
46   struct off_item *next;
47   u32 kid[2];
48   /*off_t off;*/
49 };
50
51 typedef struct off_item **OffsetHashTable; 
52
53
54 typedef struct keyring_name *KR_NAME;
55 struct keyring_name {
56   struct keyring_name *next;
57   int secret;
58   DOTLOCK lockhd;
59   int is_locked;
60   int did_full_scan;
61   char fname[1];
62 };
63 typedef struct keyring_name const * CONST_KR_NAME;
64
65 static KR_NAME kr_names;
66 static int active_handles;
67
68 static OffsetHashTable kr_offtbl;
69 static int kr_offtbl_ready;
70
71
72 struct keyring_handle {
73   CONST_KR_NAME resource;
74   int secret;             /* this is for a secret keyring */
75   struct {
76     CONST_KR_NAME kr;
77     IOBUF iobuf;
78     int eof;
79     int error;
80   } current;
81   struct {
82     CONST_KR_NAME kr; 
83     off_t offset;
84     size_t pk_no;
85     size_t uid_no;
86     unsigned int n_packets; /*used for delete and update*/
87   } found;
88   struct {
89     char *name;
90     char *pattern;
91   } word_match;
92 };
93
94
95
96 static int do_copy (int mode, const char *fname, KBNODE root, int secret,
97                     off_t start_offset, unsigned int n_packets );
98
99
100 \f
101 static struct off_item *
102 new_offset_item (void)
103 {
104   struct off_item *k;
105   
106   k = xmalloc_clear (sizeof *k);
107   return k;
108 }
109
110 #if 0
111 static void
112 release_offset_items (struct off_item *k)
113 {
114   struct off_item *k2;
115
116   for (; k; k = k2)
117     {
118       k2 = k->next;
119       xfree (k);
120     }
121 }
122 #endif
123
124 static OffsetHashTable 
125 new_offset_hash_table (void)
126 {
127   struct off_item **tbl;
128
129   tbl = xmalloc_clear (2048 * sizeof *tbl);
130   return tbl;
131 }
132
133 #if 0
134 static void
135 release_offset_hash_table (OffsetHashTable tbl)
136 {
137   int i;
138
139   if (!tbl)
140     return;
141   for (i=0; i < 2048; i++)
142     release_offset_items (tbl[i]);
143   xfree (tbl);
144 }
145 #endif
146
147 static struct off_item *
148 lookup_offset_hash_table (OffsetHashTable tbl, u32 *kid)
149 {
150   struct off_item *k;
151
152   for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next)
153     if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
154       return k;
155   return NULL;
156 }
157
158 static void
159 update_offset_hash_table (OffsetHashTable tbl, u32 *kid, off_t off)
160 {
161   struct off_item *k;
162
163   for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next)
164     {
165       if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) 
166         {
167           /*k->off = off;*/
168           return;
169         }
170     }
171
172   k = new_offset_item ();
173   k->kid[0] = kid[0];
174   k->kid[1] = kid[1];
175   /*k->off = off;*/
176   k->next = tbl[(kid[1] & 0x07ff)];
177   tbl[(kid[1] & 0x07ff)] = k;
178 }
179
180 static void
181 update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off)
182 {
183   for (; node; node = node->next)
184     {
185       if (node->pkt->pkttype == PKT_PUBLIC_KEY
186           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
187         {
188           u32 aki[2];
189           keyid_from_pk (node->pkt->pkt.public_key, aki);
190           update_offset_hash_table (tbl, aki, off);
191         }
192     }
193 }
194
195 /* 
196  * Register a filename for plain keyring files.  ptr is set to a
197  * pointer to be used to create a handles etc, or the already-issued
198  * pointer if it has already been registered.  The function returns 1
199  * if a new keyring was registered.
200 */
201 int
202 keyring_register_filename (const char *fname, int secret, void **ptr)
203 {
204     KR_NAME kr;
205
206     if (active_handles)
207         BUG (); /* We don't allow that */
208
209     for (kr=kr_names; kr; kr = kr->next)
210       {
211         if ( !compare_filenames (kr->fname, fname) )
212           {
213             *ptr=kr;
214             return 0; /* already registered */
215           }
216       }
217
218     if (secret)
219       register_secured_file (fname);
220
221     kr = xmalloc (sizeof *kr + strlen (fname));
222     strcpy (kr->fname, fname);
223     kr->secret = !!secret;
224     kr->lockhd = NULL;
225     kr->is_locked = 0;
226     kr->did_full_scan = 0;
227     /* keep a list of all issued pointers */
228     kr->next = kr_names;
229     kr_names = kr;
230
231     /* create the offset table the first time a function here is used */
232     if (!kr_offtbl)
233       kr_offtbl = new_offset_hash_table ();
234
235     *ptr=kr;
236
237     return 1;
238 }
239
240 int
241 keyring_is_writable (void *token)
242 {
243   KR_NAME r = token;
244
245   return r? !access (r->fname, W_OK) : 0;
246 }
247     
248
249 \f
250 /* Create a new handle for the resource associated with TOKEN.  SECRET
251    is just just as a cross-check.
252    
253    The returned handle must be released using keyring_release (). */
254 KEYRING_HANDLE
255 keyring_new (void *token, int secret)
256 {
257   KEYRING_HANDLE hd;
258   KR_NAME resource = token;
259
260   assert (resource && !resource->secret == !secret);
261   
262   hd = xmalloc_clear (sizeof *hd);
263   hd->resource = resource;
264   hd->secret = !!secret;
265   active_handles++;
266   return hd;
267 }
268
269 void 
270 keyring_release (KEYRING_HANDLE hd)
271 {
272     if (!hd)
273         return;
274     assert (active_handles > 0);
275     active_handles--;
276     xfree (hd->word_match.name);
277     xfree (hd->word_match.pattern);
278     iobuf_close (hd->current.iobuf);
279     xfree (hd);
280 }
281
282
283 const char *
284 keyring_get_resource_name (KEYRING_HANDLE hd)
285 {
286     if (!hd || !hd->resource)
287       return NULL;
288     return hd->resource->fname;
289 }
290
291
292 /*
293  * Lock the keyring with the given handle, or unlok if yes is false.
294  * We ignore the handle and lock all registered files.
295  */
296 int 
297 keyring_lock (KEYRING_HANDLE hd, int yes)
298 {
299     KR_NAME kr;
300     int rc = 0;
301
302     if (yes) {
303         /* first make sure the lock handles are created */
304         for (kr=kr_names; kr; kr = kr->next) {
305             if (!keyring_is_writable(kr))
306                 continue;
307             if (!kr->lockhd) {
308                 kr->lockhd = create_dotlock( kr->fname );
309                 if (!kr->lockhd) {
310                     log_info ("can't allocate lock for `%s'\n", kr->fname );
311                     rc = G10ERR_GENERAL;
312                 }
313             }
314         }
315         if (rc)
316             return rc;
317         
318         /* and now set the locks */
319         for (kr=kr_names; kr; kr = kr->next) {
320             if (!keyring_is_writable(kr))
321                 continue;
322             if (kr->is_locked)
323                 ;
324             else if (make_dotlock (kr->lockhd, -1) ) {
325                 log_info ("can't lock `%s'\n", kr->fname );
326                 rc = G10ERR_GENERAL;
327             }
328             else 
329                 kr->is_locked = 1;
330         }
331     }
332
333     if (rc || !yes) {
334         for (kr=kr_names; kr; kr = kr->next) {
335             if (!keyring_is_writable(kr))
336                 continue;
337             if (!kr->is_locked)
338                 ;
339             else if (release_dotlock (kr->lockhd))
340                 log_info ("can't unlock `%s'\n", kr->fname );
341             else 
342                 kr->is_locked = 0;
343         }
344     } 
345
346     return rc;
347 }
348
349
350 \f
351 /*
352  * Return the last found keyring.  Caller must free it.
353  * The returned keyblock has the kbode flag bit 0 set for the node with
354  * the public key used to locate the keyblock or flag bit 1 set for 
355  * the user ID node.
356  */
357 int
358 keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
359 {
360     PACKET *pkt;
361     int rc;
362     KBNODE keyblock = NULL, node, lastnode;
363     IOBUF a;
364     int in_cert = 0;
365     int pk_no = 0;
366     int uid_no = 0;
367     int save_mode;
368
369     if (ret_kb)
370         *ret_kb = NULL;
371
372     if (!hd->found.kr)
373         return -1; /* no successful search */
374
375     a = iobuf_open (hd->found.kr->fname);
376     if (!a)
377       {
378         log_error(_("can't open `%s'\n"), hd->found.kr->fname);
379         return G10ERR_KEYRING_OPEN;
380       }
381
382     if (iobuf_seek (a, hd->found.offset) ) {
383         log_error ("can't seek `%s'\n", hd->found.kr->fname);
384         iobuf_close(a);
385         return G10ERR_KEYRING_OPEN;
386     }
387
388     pkt = xmalloc (sizeof *pkt);
389     init_packet (pkt);
390     hd->found.n_packets = 0;;
391     lastnode = NULL;
392     save_mode = set_packet_list_mode(0);
393     while ((rc=parse_packet (a, pkt)) != -1) {
394         hd->found.n_packets++;
395         if (rc == G10ERR_UNKNOWN_PACKET) {
396             free_packet (pkt);
397             init_packet (pkt);
398             continue;
399         }
400         if (rc) {  
401             log_error ("keyring_get_keyblock: read error: %s\n",
402                        g10_errstr(rc) );
403             rc = G10ERR_INV_KEYRING;
404             break;
405         }
406         if (pkt->pkttype == PKT_COMPRESSED) {
407             log_error ("skipped compressed packet in keyring\n");
408             free_packet(pkt);
409             init_packet(pkt);
410             continue;
411         }
412
413         if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY
414                         || pkt->pkttype == PKT_SECRET_KEY)) {
415             hd->found.n_packets--; /* fix counter */
416             break; /* ready */
417         }
418
419         in_cert = 1;
420         if (pkt->pkttype == PKT_RING_TRUST) {
421             /*(this code is duplicated after the loop)*/
422             if ( lastnode 
423                  && lastnode->pkt->pkttype == PKT_SIGNATURE
424                  && (pkt->pkt.ring_trust->sigcache & 1) ) {
425                 /* this is a ring trust packet with a checked signature 
426                  * status cache following directly a signature paket.
427                  * Set the cache status into that signature packet */
428                 PKT_signature *sig = lastnode->pkt->pkt.signature;
429                 
430                 sig->flags.checked = 1;
431                 sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
432             }
433             /* reset lastnode, so that we set the cache status only from
434              * the ring trust packet immediately folling a signature */
435             lastnode = NULL;
436         }
437         else {
438             node = lastnode = new_kbnode (pkt);
439             if (!keyblock)
440                 keyblock = node;
441             else
442                 add_kbnode (keyblock, node);
443
444             if ( pkt->pkttype == PKT_PUBLIC_KEY
445                  || pkt->pkttype == PKT_PUBLIC_SUBKEY
446                  || pkt->pkttype == PKT_SECRET_KEY
447                  || pkt->pkttype == PKT_SECRET_SUBKEY) {
448                 if (++pk_no == hd->found.pk_no)
449                     node->flag |= 1;
450             }
451             else if ( pkt->pkttype == PKT_USER_ID) {
452                 if (++uid_no == hd->found.uid_no)
453                     node->flag |= 2;
454             }
455         }
456
457         pkt = xmalloc (sizeof *pkt);
458         init_packet(pkt);
459     }
460     set_packet_list_mode(save_mode);
461
462     if (rc == -1 && keyblock) 
463         rc = 0; /* got the entire keyblock */
464
465     if (rc || !ret_kb)
466         release_kbnode (keyblock);
467     else {
468         /*(duplicated form the loop body)*/
469         if ( pkt && pkt->pkttype == PKT_RING_TRUST
470              && lastnode 
471              && lastnode->pkt->pkttype == PKT_SIGNATURE
472              && (pkt->pkt.ring_trust->sigcache & 1) ) {
473             PKT_signature *sig = lastnode->pkt->pkt.signature;
474             sig->flags.checked = 1;
475             sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
476         }
477         *ret_kb = keyblock;
478     }
479     free_packet (pkt);
480     xfree (pkt);
481     iobuf_close(a);
482
483     /* Make sure that future search operations fail immediately when
484      * we know that we are working on a invalid keyring 
485      */
486     if (rc == G10ERR_INV_KEYRING)
487         hd->current.error = rc;
488
489     return rc;
490 }
491
492 int
493 keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb)
494 {
495     int rc;
496
497     if (!hd->found.kr)
498         return -1; /* no successful prior search */
499
500     if (!hd->found.n_packets) {
501         /* need to know the number of packets - do a dummy get_keyblock*/
502         rc = keyring_get_keyblock (hd, NULL);
503         if (rc) {
504             log_error ("re-reading keyblock failed: %s\n", g10_errstr (rc));
505             return rc;
506         }
507         if (!hd->found.n_packets)
508             BUG ();
509     }
510
511     /* The open iobuf isn't needed anymore and in fact is a problem when
512        it comes to renaming the keyring files on some operating systems,
513        so close it here */
514     iobuf_close(hd->current.iobuf);
515     hd->current.iobuf = NULL;
516
517     /* do the update */
518     rc = do_copy (3, hd->found.kr->fname, kb, hd->secret,
519                   hd->found.offset, hd->found.n_packets );
520     if (!rc) {
521       if (!hd->secret && kr_offtbl)
522         {
523           update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
524         }
525       /* better reset the found info */
526       hd->found.kr = NULL;
527       hd->found.offset = 0;
528     }
529     return rc;
530 }
531
532 int
533 keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
534 {
535     int rc;
536     const char *fname;
537
538     if (!hd)
539         fname = NULL;
540     else if (hd->found.kr)
541         fname = hd->found.kr->fname;
542     else if (hd->current.kr)
543         fname = hd->current.kr->fname;
544     else 
545         fname = hd->resource? hd->resource->fname:NULL;
546
547     if (!fname)
548         return G10ERR_GENERAL; 
549
550     /* close this one otherwise we will lose the position for
551      * a next search.  Fixme: it would be better to adjust the position
552      * after the write opertions.
553      */
554     iobuf_close (hd->current.iobuf);
555     hd->current.iobuf = NULL;
556
557     /* do the insert */
558     rc = do_copy (1, fname, kb, hd->secret, 0, 0 );
559     if (!rc && !hd->secret && kr_offtbl)
560       {
561         update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
562       }
563       
564     return rc;
565 }
566
567
568 int
569 keyring_delete_keyblock (KEYRING_HANDLE hd)
570 {
571     int rc;
572
573     if (!hd->found.kr)
574         return -1; /* no successful prior search */
575
576     if (!hd->found.n_packets) {
577         /* need to know the number of packets - do a dummy get_keyblock*/
578         rc = keyring_get_keyblock (hd, NULL);
579         if (rc) {
580             log_error ("re-reading keyblock failed: %s\n", g10_errstr (rc));
581             return rc;
582         }
583         if (!hd->found.n_packets)
584             BUG ();
585     }
586
587     /* close this one otherwise we will lose the position for
588      * a next search.  Fixme: it would be better to adjust the position
589      * after the write opertions.
590      */
591     iobuf_close (hd->current.iobuf);
592     hd->current.iobuf = NULL;
593
594     /* do the delete */
595     rc = do_copy (2, hd->found.kr->fname, NULL, hd->secret,
596                   hd->found.offset, hd->found.n_packets );
597     if (!rc) {
598         /* better reset the found info */
599         hd->found.kr = NULL;
600         hd->found.offset = 0;
601         /* Delete is a rare operations, so we don't remove the keys
602          * from the offset table */
603     }
604     return rc;
605 }
606
607
608 \f
609 /* 
610  * Start the next search on this handle right at the beginning
611  */
612 int 
613 keyring_search_reset (KEYRING_HANDLE hd)
614 {
615     assert (hd);
616
617     hd->current.kr = NULL;
618     iobuf_close (hd->current.iobuf);
619     hd->current.iobuf = NULL;
620     hd->current.eof = 0;
621     hd->current.error = 0;
622     
623     hd->found.kr = NULL;
624     hd->found.offset = 0;
625     return 0; 
626 }
627
628
629 static int
630 prepare_search (KEYRING_HANDLE hd)
631 {
632     if (hd->current.error)  
633         return hd->current.error; /* still in error state */
634
635     if (hd->current.kr && !hd->current.eof) {
636         if ( !hd->current.iobuf )
637             return G10ERR_GENERAL; /* position invalid after a modify */
638         return 0; /* okay */
639     }
640
641     if (!hd->current.kr && hd->current.eof)  
642         return -1; /* still EOF */
643
644     if (!hd->current.kr) { /* start search with first keyring */
645         hd->current.kr = hd->resource;
646         if (!hd->current.kr) {
647             hd->current.eof = 1;
648             return -1; /* keyring not available */
649         }
650         assert (!hd->current.iobuf);
651     }
652     else { /* EOF */
653         iobuf_close (hd->current.iobuf); 
654         hd->current.iobuf = NULL;
655         hd->current.kr = NULL;
656         hd->current.eof = 1;
657         return -1;
658     }
659
660     hd->current.eof = 0;
661     hd->current.iobuf = iobuf_open (hd->current.kr->fname);
662     if (!hd->current.iobuf)
663       {
664         hd->current.error = gpg_error_from_errno (errno);
665         log_error(_("can't open `%s'\n"), hd->current.kr->fname );
666         return hd->current.error;
667       }
668
669     return 0;
670 }
671
672 \f
673 /* A map of the all characters valid used for word_match()
674  * Valid characters are in in this table converted to uppercase.
675  * because the upper 128 bytes have special meaning, we assume
676  * that they are all valid.
677  * Note: We must use numerical values here in case that this program
678  * will be converted to those little blue HAL9000s with their strange
679  * EBCDIC character set (user ids are UTF-8).
680  * wk 2000-04-13: Hmmm, does this really make sense, given the fact that
681  * we can run gpg now on a S/390 running GNU/Linux, where the code
682  * translation is done by the device drivers?
683  */
684 static const byte word_match_chars[256] = {
685   /* 00 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686   /* 08 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687   /* 10 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688   /* 18 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689   /* 20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690   /* 28 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691   /* 30 */  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
692   /* 38 */  0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693   /* 40 */  0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
694   /* 48 */  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
695   /* 50 */  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
696   /* 58 */  0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
697   /* 60 */  0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
698   /* 68 */  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
699   /* 70 */  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
700   /* 78 */  0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
701   /* 80 */  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
702   /* 88 */  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
703   /* 90 */  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
704   /* 98 */  0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
705   /* a0 */  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
706   /* a8 */  0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
707   /* b0 */  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
708   /* b8 */  0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
709   /* c0 */  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
710   /* c8 */  0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
711   /* d0 */  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
712   /* d8 */  0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
713   /* e0 */  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
714   /* e8 */  0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
715   /* f0 */  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
716   /* f8 */  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
717 };
718
719 /****************
720  * Do a word match (original user id starts with a '+').
721  * The pattern is already tokenized to a more suitable format:
722  * There are only the real words in it delimited by one space
723  * and all converted to uppercase.
724  *
725  * Returns: 0 if all words match.
726  *
727  * Note: This algorithm is a straightforward one and not very
728  *       fast.  It works for UTF-8 strings.  The uidlen should
729  *       be removed but due to the fact that old versions of
730  *       pgp don't use UTF-8 we still use the length; this should
731  *       be fixed in parse-packet (and replace \0 by some special
732  *       UTF-8 encoding)
733  */
734 static int
735 word_match( const byte *uid, size_t uidlen, const byte *pattern )
736 {
737     size_t wlen, n;
738     const byte *p;
739     const byte *s;
740
741     for( s=pattern; *s; ) {
742         do {
743             /* skip leading delimiters */
744             while( uidlen && !word_match_chars[*uid] )
745                 uid++, uidlen--;
746             /* get length of the word */
747             n = uidlen; p = uid;
748             while( n && word_match_chars[*p] )
749                 p++, n--;
750             wlen = p - uid;
751             /* and compare against the current word from pattern */
752             for(n=0, p=uid; n < wlen && s[n] != ' ' && s[n] ; n++, p++ ) {
753                 if( word_match_chars[*p] != s[n] )
754                     break;
755             }
756             if( n == wlen && (s[n] == ' ' || !s[n]) )
757                 break; /* found */
758             uid += wlen;
759             uidlen -= wlen;
760         } while( uidlen );
761         if( !uidlen )
762             return -1; /* not found */
763
764         /* advance to next word in pattern */
765         for(; *s != ' ' && *s ; s++ )
766             ;
767         if( *s )
768             s++ ;
769     }
770     return 0; /* found */
771 }
772
773 /****************
774  * prepare word word_match; that is parse the name and
775  * build the pattern.
776  * caller has to free the returned pattern
777  */
778 static char*
779 prepare_word_match (const byte *name)
780 {
781     byte *pattern, *p;
782     int c;
783
784     /* the original length is always enough for the pattern */
785     p = pattern = xmalloc(strlen(name)+1);
786     do {
787         /* skip leading delimiters */
788         while( *name && !word_match_chars[*name] )
789             name++;
790         /* copy as long as we don't have a delimiter and convert
791          * to uppercase.
792          * fixme: how can we handle utf8 uppercasing */
793         for( ; *name &&  (c=word_match_chars[*name]); name++ )
794             *p++ = c;
795         *p++ = ' '; /* append pattern delimiter */
796     } while( *name );
797     p[-1] = 0; /* replace last pattern delimiter by EOS */
798
799     return pattern;
800 }
801
802
803
804
805 static int
806 compare_name (int mode, const char *name, const char *uid, size_t uidlen)
807 {
808     int i;
809     const char *s, *se;
810
811     if (mode == KEYDB_SEARCH_MODE_EXACT) { 
812         for (i=0; name[i] && uidlen; i++, uidlen--)
813             if (uid[i] != name[i])
814                 break;
815         if (!uidlen && !name[i])
816             return 0; /* found */
817     }
818     else if (mode == KEYDB_SEARCH_MODE_SUBSTR) {
819         if (ascii_memistr( uid, uidlen, name ))
820             return 0;
821     }
822     else if (   mode == KEYDB_SEARCH_MODE_MAIL 
823              || mode == KEYDB_SEARCH_MODE_MAILSUB
824              || mode == KEYDB_SEARCH_MODE_MAILEND) {
825         for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++)
826             ;
827         if (i < uidlen)  {
828             /* skip opening delim and one char and look for the closing one*/
829             s++; i++;
830             for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++)
831                 ;
832             if (i < uidlen) {
833                 i = se - s;
834                 if (mode == KEYDB_SEARCH_MODE_MAIL) { 
835                     if( strlen(name)-2 == i
836                         && !ascii_memcasecmp( s, name+1, i) )
837                         return 0;
838                 }
839                 else if (mode == KEYDB_SEARCH_MODE_MAILSUB) {
840                     if( ascii_memistr( s, i, name ) )
841                         return 0;
842                 }
843                 else { /* email from end */
844                     /* nyi */
845                 }
846             }
847         }
848     }
849     else if (mode == KEYDB_SEARCH_MODE_WORDS)
850         return word_match (uid, uidlen, name);
851     else
852         BUG();
853
854     return -1; /* not found */
855 }
856
857 \f
858 /* 
859  * Search through the keyring(s), starting at the current position,
860  * for a keyblock which contains one of the keys described in the DESC array.
861  */
862 int 
863 keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
864                 size_t ndesc, size_t *descindex)
865 {
866   int rc;
867   PACKET pkt;
868   int save_mode;
869   off_t offset, main_offset;
870   size_t n;
871   int need_uid, need_words, need_keyid, need_fpr, any_skip;
872   int pk_no, uid_no;
873   int initial_skip;
874   int use_offtbl;
875   PKT_user_id *uid = NULL;
876   PKT_public_key *pk = NULL;
877   PKT_secret_key *sk = NULL;
878   u32 aki[2];
879
880   /* figure out what information we need */
881   need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
882   for (n=0; n < ndesc; n++) 
883     {
884       switch (desc[n].mode) 
885         {
886         case KEYDB_SEARCH_MODE_EXACT: 
887         case KEYDB_SEARCH_MODE_SUBSTR:
888         case KEYDB_SEARCH_MODE_MAIL:
889         case KEYDB_SEARCH_MODE_MAILSUB:
890         case KEYDB_SEARCH_MODE_MAILEND:
891           need_uid = 1;
892           break;
893         case KEYDB_SEARCH_MODE_WORDS: 
894           need_uid = 1;
895           need_words = 1;
896           break;
897         case KEYDB_SEARCH_MODE_SHORT_KID: 
898         case KEYDB_SEARCH_MODE_LONG_KID:
899           need_keyid = 1;
900           break;
901         case KEYDB_SEARCH_MODE_FPR16: 
902         case KEYDB_SEARCH_MODE_FPR20:
903         case KEYDB_SEARCH_MODE_FPR: 
904           need_fpr = 1;
905           break;
906         case KEYDB_SEARCH_MODE_FIRST:
907           /* always restart the search in this mode */
908           keyring_search_reset (hd);
909           break;
910         default: break;
911         }
912       if (desc[n].skipfnc) 
913         {
914           any_skip = 1;
915           need_keyid = 1;
916         }
917     }
918
919   rc = prepare_search (hd);
920   if (rc)
921     return rc;
922
923   use_offtbl = !hd->secret && kr_offtbl;
924   if (!use_offtbl)
925     ;
926   else if (!kr_offtbl_ready)
927     need_keyid = 1;
928   else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID)
929     {
930       struct off_item *oi;
931             
932       oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid);
933       if (!oi)
934         { /* We know that we don't have this key */
935           hd->found.kr = NULL;
936           hd->current.eof = 1;
937           return -1;
938         }
939       /* We could now create a positive search status and return.
940        * However the problem is that another instance of gpg may 
941        * have changed the keyring so that the offsets are not valid
942        * anymore - therefore we don't do it 
943        */
944     }
945
946   if (need_words)
947     {
948       const char *name = NULL;
949
950       log_debug ("word search mode does not yet work\n");
951       /* FIXME: here is a long standing bug in our function and in addition we
952          just use the first search description */
953       for (n=0; n < ndesc && !name; n++) 
954         {
955           if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS) 
956             name = desc[n].u.name;
957         }
958       assert (name);
959       if ( !hd->word_match.name || strcmp (hd->word_match.name, name) ) 
960         {
961           /* name changed */
962           xfree (hd->word_match.name);
963           xfree (hd->word_match.pattern);
964           hd->word_match.name = xstrdup (name);
965           hd->word_match.pattern = prepare_word_match (name);
966         }
967       name = hd->word_match.pattern;
968     }
969
970   init_packet(&pkt);
971   save_mode = set_packet_list_mode(0);
972
973   hd->found.kr = NULL;
974   main_offset = 0;
975   pk_no = uid_no = 0;
976   initial_skip = 1; /* skip until we see the start of a keyblock */
977   while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid))) 
978     {
979       byte afp[MAX_FINGERPRINT_LEN];
980       size_t an;
981
982       if (pkt.pkttype == PKT_PUBLIC_KEY  || pkt.pkttype == PKT_SECRET_KEY) 
983         {
984           main_offset = offset;
985           pk_no = uid_no = 0;
986           initial_skip = 0;
987         }
988       if (initial_skip) 
989         {
990           free_packet (&pkt);
991           continue;
992         }
993         
994       pk = NULL;
995       sk = NULL;
996       uid = NULL;
997       if (   pkt.pkttype == PKT_PUBLIC_KEY
998              || pkt.pkttype == PKT_PUBLIC_SUBKEY)
999         {
1000           pk = pkt.pkt.public_key;
1001           ++pk_no;
1002
1003           if (need_fpr) {
1004             fingerprint_from_pk (pk, afp, &an);
1005             while (an < 20) /* fill up to 20 bytes */
1006               afp[an++] = 0;
1007           }
1008           if (need_keyid)
1009             keyid_from_pk (pk, aki);
1010
1011           if (use_offtbl && !kr_offtbl_ready)
1012             update_offset_hash_table (kr_offtbl, aki, main_offset);
1013         }
1014       else if (pkt.pkttype == PKT_USER_ID) 
1015         {
1016           uid = pkt.pkt.user_id;
1017           ++uid_no;
1018         }
1019       else if (    pkt.pkttype == PKT_SECRET_KEY
1020                    || pkt.pkttype == PKT_SECRET_SUBKEY) 
1021         {
1022           sk = pkt.pkt.secret_key;
1023           ++pk_no;
1024
1025           if (need_fpr) {
1026             fingerprint_from_sk (sk, afp, &an);
1027             while (an < 20) /* fill up to 20 bytes */
1028               afp[an++] = 0;
1029           }
1030           if (need_keyid)
1031             keyid_from_sk (sk, aki);
1032             
1033         }
1034
1035       for (n=0; n < ndesc; n++) 
1036         {
1037           switch (desc[n].mode) {
1038           case KEYDB_SEARCH_MODE_NONE: 
1039             BUG ();
1040             break;
1041           case KEYDB_SEARCH_MODE_EXACT: 
1042           case KEYDB_SEARCH_MODE_SUBSTR:
1043           case KEYDB_SEARCH_MODE_MAIL:
1044           case KEYDB_SEARCH_MODE_MAILSUB:
1045           case KEYDB_SEARCH_MODE_MAILEND:
1046           case KEYDB_SEARCH_MODE_WORDS: 
1047             if ( uid && !compare_name (desc[n].mode,
1048                                        desc[n].u.name,
1049                                        uid->name, uid->len)) 
1050               goto found;
1051             break;
1052                 
1053           case KEYDB_SEARCH_MODE_SHORT_KID: 
1054             if ((pk||sk) && desc[n].u.kid[1] == aki[1])
1055               goto found;
1056             break;
1057           case KEYDB_SEARCH_MODE_LONG_KID:
1058             if ((pk||sk) && desc[n].u.kid[0] == aki[0]
1059                 && desc[n].u.kid[1] == aki[1])
1060               goto found;
1061             break;
1062           case KEYDB_SEARCH_MODE_FPR16:
1063             if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
1064               goto found;
1065             break;
1066           case KEYDB_SEARCH_MODE_FPR20:
1067           case KEYDB_SEARCH_MODE_FPR: 
1068             if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
1069               goto found;
1070             break;
1071           case KEYDB_SEARCH_MODE_FIRST: 
1072             if (pk||sk)
1073               goto found;
1074             break;
1075           case KEYDB_SEARCH_MODE_NEXT: 
1076             if (pk||sk)
1077               goto found;
1078             break;
1079           default: 
1080             rc = G10ERR_INV_ARG;
1081             goto found;
1082           }
1083         }
1084       free_packet (&pkt);
1085       continue;
1086     found:
1087       /* Record which desc we matched on.  Note this value is only
1088          meaningful if this function returns with no errors. */
1089       if(descindex)
1090         *descindex=n;
1091       for (n=any_skip?0:ndesc; n < ndesc; n++) 
1092         {
1093           if (desc[n].skipfnc
1094               && desc[n].skipfnc (desc[n].skipfncvalue, aki, uid))
1095             break;
1096         }
1097       if (n == ndesc)
1098         goto real_found;
1099       free_packet (&pkt);
1100     }
1101  real_found:
1102   if (!rc)
1103     {
1104       hd->found.offset = main_offset;
1105       hd->found.kr = hd->current.kr;
1106       hd->found.pk_no = (pk||sk)? pk_no : 0;
1107       hd->found.uid_no = uid? uid_no : 0;
1108     }
1109   else if (rc == -1)
1110     {
1111       hd->current.eof = 1;
1112       /* if we scanned all keyrings, we are sure that
1113        * all known key IDs are in our offtbl, mark that. */
1114       if (use_offtbl && !kr_offtbl_ready)
1115         {
1116           KR_NAME kr;
1117           
1118           /* First set the did_full_scan flag for this keyring (ignore
1119              secret keyrings) */
1120           for (kr=kr_names; kr; kr = kr->next)
1121             {
1122               if (!kr->secret && hd->resource == kr) 
1123                 {
1124                   kr->did_full_scan = 1;
1125                   break;
1126                 }
1127             }
1128           /* Then check whether all flags are set and if so, mark the
1129              offtbl ready */
1130           for (kr=kr_names; kr; kr = kr->next)
1131             {
1132               if (!kr->secret && !kr->did_full_scan) 
1133                 break;
1134             }
1135           if (!kr)
1136             kr_offtbl_ready = 1;
1137         }
1138     }
1139   else 
1140     hd->current.error = rc;
1141
1142   free_packet(&pkt);
1143   set_packet_list_mode(save_mode);
1144   return rc;
1145 }
1146
1147
1148 static int
1149 create_tmp_file (const char *template,
1150                  char **r_bakfname, char **r_tmpfname, IOBUF *r_fp)
1151 {  
1152   char *bakfname, *tmpfname;
1153   mode_t oldmask;
1154
1155   *r_bakfname = NULL;
1156   *r_tmpfname = NULL;
1157
1158 # ifdef USE_ONLY_8DOT3
1159   /* Here is another Windoze bug?:
1160    * you cant rename("pubring.gpg.tmp", "pubring.gpg");
1161    * but        rename("pubring.gpg.tmp", "pubring.aaa");
1162    * works.  So we replace .gpg by .bak or .tmp
1163    */
1164   if (strlen (template) > 4
1165       && !strcmp (template+strlen(template)-4, EXTSEP_S "gpg") )
1166     {
1167       bakfname = xmalloc (strlen (template) + 1);
1168       strcpy (bakfname, template);
1169       strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak");
1170
1171       tmpfname = xmalloc (strlen( template ) + 1 );
1172       strcpy (tmpfname,template);
1173       strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp");
1174     }
1175     else 
1176       { /* file does not end with gpg; hmmm */
1177         bakfname = xmalloc (strlen( template ) + 5);
1178         strcpy (stpcpy(bakfname, template), EXTSEP_S "bak");
1179
1180         tmpfname = xmalloc (strlen( template ) + 5);
1181         strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp");
1182     }
1183 # else /* Posix file names */
1184     bakfname = xmalloc (strlen( template ) + 2);
1185     strcpy (stpcpy (bakfname,template),"~");
1186
1187     tmpfname = xmalloc (strlen( template ) + 5);
1188     strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp");
1189 # endif /* Posix filename */
1190
1191     /* Create the temp file with limited access */
1192     oldmask=umask(077);
1193     if (is_secured_filename (tmpfname))
1194       {
1195         *r_fp = NULL;
1196         errno = EPERM;
1197       }
1198     else
1199       *r_fp = iobuf_create (tmpfname);
1200     umask(oldmask);
1201     if (!*r_fp)
1202       {
1203         int rc = gpg_error_from_errno (errno);
1204         log_error(_("can't create `%s': %s\n"), tmpfname, strerror(errno) );
1205         xfree (tmpfname);
1206         xfree (bakfname);
1207         return rc;
1208       }
1209     
1210     *r_bakfname = bakfname;
1211     *r_tmpfname = tmpfname;
1212     return 0;
1213 }
1214
1215
1216 static int
1217 rename_tmp_file (const char *bakfname, const char *tmpfname,
1218                  const char *fname, int secret )
1219 {
1220   int rc=0;
1221
1222   /* invalidate close caches*/
1223   iobuf_ioctl (NULL, 2, 0, (char*)tmpfname );
1224   iobuf_ioctl (NULL, 2, 0, (char*)bakfname );
1225   iobuf_ioctl (NULL, 2, 0, (char*)fname );
1226
1227   /* first make a backup file except for secret keyrings */
1228   if (!secret)
1229     { 
1230 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1231       remove (bakfname);
1232 #endif
1233       if (rename (fname, bakfname) )
1234         {
1235           rc = gpg_error_from_errno (errno);
1236           log_error ("renaming `%s' to `%s' failed: %s\n",
1237                      fname, bakfname, strerror(errno) );
1238           return rc;
1239         }
1240     }
1241   
1242   /* then rename the file */
1243 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1244   remove( fname );
1245 #endif
1246   if (secret)
1247     unregister_secured_file (fname);
1248   if (rename (tmpfname, fname) )
1249     {
1250       rc = gpg_error_from_errno (errno);
1251       log_error (_("renaming `%s' to `%s' failed: %s\n"),
1252                  tmpfname, fname, strerror(errno) );
1253       register_secured_file (fname);
1254       if (secret)
1255         {
1256           log_info(_("WARNING: 2 files with confidential"
1257                      " information exists.\n"));
1258           log_info(_("%s is the unchanged one\n"), fname );
1259           log_info(_("%s is the new one\n"), tmpfname );
1260           log_info(_("Please fix this possible security flaw\n"));
1261         }
1262       return rc;
1263     }
1264
1265   /* Now make sure the file has the same permissions as the original */
1266
1267 #ifndef HAVE_DOSISH_SYSTEM
1268   {
1269     struct stat statbuf;
1270
1271     statbuf.st_mode=S_IRUSR | S_IWUSR;
1272
1273     if(((secret && !opt.preserve_permissions) ||
1274         (stat(bakfname,&statbuf)==0)) &&
1275        (chmod(fname,statbuf.st_mode)==0))
1276       ;
1277     else
1278       log_error("WARNING: unable to restore permissions to `%s': %s",
1279                 fname,strerror(errno));
1280   }
1281 #endif
1282
1283   return 0;
1284 }
1285
1286
1287 static int
1288 write_keyblock (IOBUF fp, KBNODE keyblock)
1289 {
1290   KBNODE kbctx = NULL, node;
1291   int rc;
1292   
1293   while ( (node = walk_kbnode (keyblock, &kbctx, 0)) ) 
1294     {
1295       if (node->pkt->pkttype == PKT_RING_TRUST) 
1296         continue; /* we write it later on our own */
1297
1298       if ( (rc = build_packet (fp, node->pkt) ))
1299         {
1300           log_error ("build_packet(%d) failed: %s\n",
1301                      node->pkt->pkttype, g10_errstr(rc) );
1302           return rc;
1303         }
1304       if (node->pkt->pkttype == PKT_SIGNATURE) 
1305         { /* always write a signature cache packet */
1306           PKT_signature *sig = node->pkt->pkt.signature;
1307           unsigned int cacheval = 0;
1308           
1309           if (sig->flags.checked) 
1310             {
1311               cacheval |= 1;
1312               if (sig->flags.valid)
1313                 cacheval |= 2;
1314             }
1315           iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/
1316           iobuf_put (fp, 2);    /* 2 bytes */
1317           iobuf_put (fp, 0);    /* unused */
1318           if (iobuf_put (fp, cacheval)) 
1319             {
1320               rc = gpg_error_from_errno (errno);
1321               log_error ("writing sigcache packet failed\n");
1322               return rc;
1323             }
1324         }
1325     }
1326   return 0;
1327 }
1328
1329 /* 
1330  * Walk over all public keyrings, check the signatures and replace the
1331  * keyring with a new one where the signature cache is then updated.
1332  * This is only done for the public keyrings.
1333  */
1334 int
1335 keyring_rebuild_cache (void *token,int noisy)
1336 {
1337   KEYRING_HANDLE hd;
1338   KEYDB_SEARCH_DESC desc;
1339   KBNODE keyblock = NULL, node;
1340   const char *lastresname = NULL, *resname;
1341   IOBUF tmpfp = NULL;
1342   char *tmpfilename = NULL;
1343   char *bakfilename = NULL;
1344   int rc;
1345   ulong count = 0, sigcount = 0;
1346
1347   hd = keyring_new (token, 0);
1348   memset (&desc, 0, sizeof desc);
1349   desc.mode = KEYDB_SEARCH_MODE_FIRST;
1350
1351   rc=keyring_lock (hd, 1);
1352   if(rc)
1353     goto leave;
1354
1355   while ( !(rc = keyring_search (hd, &desc, 1, NULL)) )
1356     {
1357       desc.mode = KEYDB_SEARCH_MODE_NEXT;
1358       resname = keyring_get_resource_name (hd);
1359       if (lastresname != resname )
1360         { /* we have switched to a new keyring - commit changes */
1361           if (tmpfp)
1362             {
1363               if (iobuf_close (tmpfp))
1364                 {
1365                   rc = gpg_error_from_errno (errno);
1366                   log_error ("error closing `%s': %s\n",
1367                              tmpfilename, strerror (errno));
1368                   goto leave;
1369                 }
1370               /* because we have switched resources, we can be sure that
1371                * the original file is closed */
1372               tmpfp = NULL;
1373             }
1374           rc = lastresname? rename_tmp_file (bakfilename, tmpfilename, 
1375                                              lastresname, 0) : 0;
1376           xfree (tmpfilename);  tmpfilename = NULL;
1377           xfree (bakfilename);  bakfilename = NULL;
1378           if (rc)
1379             goto leave;
1380           lastresname = resname;
1381           if (noisy && !opt.quiet)
1382             log_info (_("caching keyring `%s'\n"), resname);
1383           rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp);
1384           if (rc)
1385             goto leave;
1386         }
1387       
1388       release_kbnode (keyblock);
1389       rc = keyring_get_keyblock (hd, &keyblock);
1390       if (rc) 
1391         {
1392           log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc));
1393           goto leave;
1394         }
1395       assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
1396
1397       /* check all signature to set the signature's cache flags */
1398       for (node=keyblock; node; node=node->next)
1399         {
1400           /* Note that this doesn't cache the result of a revocation
1401              issued by a designated revoker.  This is because the pk
1402              in question does not carry the revkeys as we haven't
1403              merged the key and selfsigs.  It is questionable whether
1404              this matters very much since there are very very few
1405              designated revoker revocation packets out there. */
1406
1407           if (node->pkt->pkttype == PKT_SIGNATURE)
1408             {
1409               PKT_signature *sig=node->pkt->pkt.signature;
1410
1411               if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
1412                  && (openpgp_md_test_algo(sig->digest_algo)
1413                      || openpgp_pk_test_algo(sig->pubkey_algo)))
1414                 sig->flags.checked=sig->flags.valid=0;
1415               else
1416                 check_key_signature (keyblock, node, NULL);
1417
1418               sigcount++;
1419             }
1420         }
1421       
1422       /* write the keyblock to the temporary file */
1423       rc = write_keyblock (tmpfp, keyblock);
1424       if (rc)
1425         goto leave;
1426
1427       if ( !(++count % 50) && noisy && !opt.quiet)
1428         log_info(_("%lu keys cached so far (%lu signatures)\n"),
1429                  count, sigcount );
1430
1431     } /* end main loop */ 
1432   if (rc == -1)
1433     rc = 0;
1434   if (rc) 
1435     {
1436       log_error ("keyring_search failed: %s\n", g10_errstr(rc));
1437       goto leave;
1438     }
1439   if(noisy || opt.verbose)
1440     log_info(_("%lu keys cached (%lu signatures)\n"), count, sigcount );
1441   if (tmpfp)
1442     {
1443       if (iobuf_close (tmpfp))
1444         {
1445           rc = gpg_error_from_errno (errno);
1446           log_error ("error closing `%s': %s\n",
1447                      tmpfilename, strerror (errno));
1448           goto leave;
1449         }
1450       /* because we have switched resources, we can be sure that
1451        * the original file is closed */
1452       tmpfp = NULL;
1453     }
1454   rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
1455                                      lastresname, 0) : 0;
1456   xfree (tmpfilename);  tmpfilename = NULL;
1457   xfree (bakfilename);  bakfilename = NULL;
1458
1459  leave:
1460   if (tmpfp)
1461     iobuf_cancel (tmpfp);
1462   xfree (tmpfilename);  
1463   xfree (bakfilename);  
1464   release_kbnode (keyblock);
1465   keyring_lock (hd, 0);
1466   keyring_release (hd);
1467   return rc;
1468 }
1469
1470 \f
1471 /****************
1472  * Perform insert/delete/update operation.
1473  * mode 1 = insert
1474  *      2 = delete
1475  *      3 = update
1476  */
1477 static int
1478 do_copy (int mode, const char *fname, KBNODE root, int secret,
1479          off_t start_offset, unsigned int n_packets )
1480 {
1481     IOBUF fp, newfp;
1482     int rc=0;
1483     char *bakfname = NULL;
1484     char *tmpfname = NULL;
1485
1486     /* Open the source file. Because we do a rename, we have to check the 
1487        permissions of the file */
1488     if (access (fname, W_OK))
1489       return gpg_error_from_errno (errno);
1490
1491     fp = iobuf_open (fname);
1492     if (mode == 1 && !fp && errno == ENOENT) { 
1493         /* insert mode but file does not exist: create a new file */
1494         KBNODE kbctx, node;
1495         mode_t oldmask;
1496
1497         oldmask=umask(077);
1498         if (!secret && is_secured_filename (fname)) {
1499             newfp = NULL;
1500             errno = EPERM;
1501         }
1502         else
1503             newfp = iobuf_create (fname);
1504         umask(oldmask);
1505         if( !newfp )
1506           {
1507             rc = gpg_error_from_errno (errno);
1508             log_error (_("can't create `%s': %s\n"), fname, strerror(errno));
1509             return rc;
1510           }
1511         if( !opt.quiet )
1512             log_info(_("%s: keyring created\n"), fname );
1513
1514         kbctx=NULL;
1515         while ( (node = walk_kbnode( root, &kbctx, 0 )) ) {
1516             if( (rc = build_packet( newfp, node->pkt )) ) {
1517                 log_error("build_packet(%d) failed: %s\n",
1518                             node->pkt->pkttype, g10_errstr(rc) );
1519                 iobuf_cancel(newfp);
1520                 return rc;
1521             }
1522         }
1523         if( iobuf_close(newfp) ) {
1524             rc = gpg_error_from_errno (errno);
1525             log_error ("%s: close failed: %s\n", fname, strerror(errno));
1526             return rc;
1527         }
1528         return 0; /* ready */
1529     }
1530
1531     if( !fp )
1532       {
1533         rc = gpg_error_from_errno (errno);
1534         log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
1535         goto leave;
1536       }
1537
1538     /* Create the new file.  */
1539     rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
1540     if (rc) {
1541         iobuf_close(fp);
1542         goto leave;
1543     }
1544     if (secret)
1545       register_secured_file (tmpfname);
1546
1547     if( mode == 1 ) { /* insert */
1548         /* copy everything to the new file */
1549         rc = copy_all_packets (fp, newfp);
1550         if( rc != -1 ) {
1551             log_error("%s: copy to `%s' failed: %s\n",
1552                       fname, tmpfname, g10_errstr(rc) );
1553             iobuf_close(fp);
1554             if (secret)
1555               unregister_secured_file (tmpfname);
1556             iobuf_cancel(newfp);
1557             goto leave;
1558         }
1559         rc = 0;
1560     }
1561
1562     if( mode == 2 || mode == 3 ) { /* delete or update */
1563         /* copy first part to the new file */
1564         rc = copy_some_packets( fp, newfp, start_offset );
1565         if( rc ) { /* should never get EOF here */
1566             log_error ("%s: copy to `%s' failed: %s\n",
1567                        fname, tmpfname, g10_errstr(rc) );
1568             iobuf_close(fp);
1569             if (secret)
1570               unregister_secured_file (tmpfname);
1571             iobuf_cancel(newfp);
1572             goto leave;
1573         }
1574         /* skip this keyblock */
1575         assert( n_packets );
1576         rc = skip_some_packets( fp, n_packets );
1577         if( rc ) {
1578             log_error("%s: skipping %u packets failed: %s\n",
1579                             fname, n_packets, g10_errstr(rc));
1580             iobuf_close(fp);
1581             if (secret)
1582               unregister_secured_file (tmpfname);
1583             iobuf_cancel(newfp);
1584             goto leave;
1585         }
1586     }
1587
1588     if( mode == 1 || mode == 3 ) { /* insert or update */
1589         rc = write_keyblock (newfp, root);
1590         if (rc) {
1591           iobuf_close(fp);
1592           if (secret)
1593             unregister_secured_file (tmpfname);
1594           iobuf_cancel(newfp);
1595           goto leave;
1596         }
1597     }
1598
1599     if( mode == 2 || mode == 3 ) { /* delete or update */
1600         /* copy the rest */
1601         rc = copy_all_packets( fp, newfp );
1602         if( rc != -1 ) {
1603             log_error("%s: copy to `%s' failed: %s\n",
1604                       fname, tmpfname, g10_errstr(rc) );
1605             iobuf_close(fp);
1606             if (secret)
1607               unregister_secured_file (tmpfname);
1608             iobuf_cancel(newfp);
1609             goto leave;
1610         }
1611         rc = 0;
1612     }
1613
1614     /* close both files */
1615     if( iobuf_close(fp) ) {
1616         rc = gpg_error_from_errno (errno);
1617         log_error("%s: close failed: %s\n", fname, strerror(errno) );
1618         goto leave;
1619     }
1620     if( iobuf_close(newfp) ) {
1621         rc = gpg_error_from_errno (errno);
1622         log_error("%s: close failed: %s\n", tmpfname, strerror(errno) );
1623         goto leave;
1624     }
1625
1626     rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
1627
1628   leave:
1629     xfree(bakfname);
1630     xfree(tmpfname);
1631     return rc;
1632 }