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