gpg: Improve the keyblock cache's transparency.
[gnupg.git] / common / iobuf.c
1 /* iobuf.c  -  File Handling for OpenPGP.
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
3  *               2009, 2010, 2011  Free Software Foundation, Inc.
4  * Copyright (C) 2015  g10 Code GmbH
5  *
6  * This file is part of GnuPG.
7  *
8  * This file is free software; you can redistribute it and/or modify
9  * it under the terms of either
10  *
11  *   - the GNU Lesser General Public License as published by the Free
12  *     Software Foundation; either version 3 of the License, or (at
13  *     your option) any later version.
14  *
15  * or
16  *
17  *   - the GNU General Public License as published by the Free
18  *     Software Foundation; either version 2 of the License, or (at
19  *     your option) any later version.
20  *
21  * or both in parallel, as here.
22  *
23  * This file is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, see <http://www.gnu.org/licenses/>.
30  */
31
32 #include <config.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <ctype.h>
38 #include <assert.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <fcntl.h>
42 #include <unistd.h>
43 #ifdef HAVE_W32_SYSTEM
44 # ifdef HAVE_WINSOCK2_H
45 #  include <winsock2.h>
46 # endif
47 # include <windows.h>
48 #endif
49 #ifdef __riscos__
50 # include <kernel.h>
51 # include <swis.h>
52 #endif /* __riscos__ */
53
54 #include <assuan.h>
55
56 #include "util.h"
57 #include "sysutils.h"
58 #include "iobuf.h"
59
60 /*-- Begin configurable part.  --*/
61
62 /* The size of the internal buffers.
63    NOTE: If you change this value you MUST also adjust the regression
64    test "armored_key_8192" in armor.test! */
65 #define IOBUF_BUFFER_SIZE  8192
66
67 /* To avoid a potential DoS with compression packets we better limit
68    the number of filters in a chain.  */
69 #define MAX_NESTING_FILTER 64
70
71 /*-- End configurable part.  --*/
72
73
74 #ifdef HAVE_W32_SYSTEM
75 # ifdef HAVE_W32CE_SYSTEM
76 #  define FD_FOR_STDIN  (es_fileno (es_stdin))
77 #  define FD_FOR_STDOUT (es_fileno (es_stdout))
78 # else
79 #  define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
80 #  define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
81 # endif
82 #else /*!HAVE_W32_SYSTEM*/
83 # define FD_FOR_STDIN  (0)
84 # define FD_FOR_STDOUT (1)
85 #endif /*!HAVE_W32_SYSTEM*/
86
87
88 /* The context used by the file filter.  */
89 typedef struct
90 {
91   gnupg_fd_t fp;       /* Open file pointer or handle.  */
92   int keep_open;
93   int no_cache;
94   int eof_seen;
95   int print_only_name; /* Flags indicating that fname is not a real file.  */
96   char fname[1];       /* Name of the file.  */
97 } file_filter_ctx_t;
98
99 /* The context used by the estream filter.  */
100 typedef struct
101 {
102   estream_t fp;        /* Open estream handle.  */
103   int keep_open;
104   int no_cache;
105   int eof_seen;
106   int print_only_name; /* Flags indicating that fname is not a real file.  */
107   char fname[1];       /* Name of the file.  */
108 } file_es_filter_ctx_t;
109
110
111 /* Object to control the "close cache".  */
112 struct close_cache_s
113 {
114   struct close_cache_s *next;
115   gnupg_fd_t fp;
116   char fname[1];
117 };
118 typedef struct close_cache_s *close_cache_t;
119 static close_cache_t close_cache;
120
121
122
123 #ifdef HAVE_W32_SYSTEM
124 typedef struct
125 {
126   int sock;
127   int keep_open;
128   int no_cache;
129   int eof_seen;
130   int print_only_name;  /* Flag indicating that fname is not a real file.  */
131   char fname[1];        /* Name of the file */
132
133 } sock_filter_ctx_t;
134 #endif /*HAVE_W32_SYSTEM*/
135
136 /* The first partial length header block must be of size 512 to make
137  * it easier (and more efficient) we use a min. block size of 512 for
138  * all chunks (but the last one) */
139 #define OP_MIN_PARTIAL_CHUNK      512
140 #define OP_MIN_PARTIAL_CHUNK_2POW 9
141
142 /* The context we use for the block filter (used to handle OpenPGP
143    length information header).  */
144 typedef struct
145 {
146   int use;
147   size_t size;
148   size_t count;
149   int partial;     /* 1 = partial header, 2 in last partial packet.  */
150   char *buffer;    /* Used for partial header.  */
151   size_t buflen;   /* Used size of buffer.  */
152   int first_c;     /* First character of a partial header (which is > 0).  */
153   int eof;
154 }
155 block_filter_ctx_t;
156
157
158 /* Global flag to tell whether special file names are enabled.  See
159    gpg.c for an explanation of these file names.  FIXME: This does not
160    belong in the iobuf subsystem. */
161 static int special_names_enabled;
162
163 /* Local prototypes.  */
164 static int underflow (iobuf_t a, int clear_pending_eof);
165 static int translate_file_handle (int fd, int for_write);
166
167 /* Sends any pending data to the filter's FILTER function.  Note: this
168    works on the filter and not on the whole pipeline.  That is,
169    iobuf_flush doesn't necessarily cause data to be written to any
170    underlying file; it just causes any data buffered at the filter A
171    to be sent to A's filter function.
172
173    If A is a IOBUF_OUTPUT_TEMP filter, then this also enlarges the
174    buffer by IOBUF_BUFFER_SIZE.
175
176    May only be called on an IOBUF_OUTPUT or IOBUF_OUTPUT_TEMP filters.  */
177 static int filter_flush (iobuf_t a);
178
179
180 \f
181 /* This is a replacement for strcmp.  Under W32 it does not
182    distinguish between backslash and slash.  */
183 static int
184 fd_cache_strcmp (const char *a, const char *b)
185 {
186 #ifdef HAVE_DOSISH_SYSTEM
187   for (; *a && *b; a++, b++)
188     {
189       if (*a != *b && !((*a == '/' && *b == '\\')
190                         || (*a == '\\' && *b == '/')) )
191         break;
192     }
193   return *(const unsigned char *)a - *(const unsigned char *)b;
194 #else
195   return strcmp (a, b);
196 #endif
197 }
198
199 /*
200  * Invalidate (i.e. close) a cached iobuf
201  */
202 static int
203 fd_cache_invalidate (const char *fname)
204 {
205   close_cache_t cc;
206   int rc = 0;
207
208   assert (fname);
209   if (DBG_IOBUF)
210     log_debug ("fd_cache_invalidate (%s)\n", fname);
211
212   for (cc = close_cache; cc; cc = cc->next)
213     {
214       if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
215         {
216           if (DBG_IOBUF)
217             log_debug ("                did (%s)\n", cc->fname);
218 #ifdef HAVE_W32_SYSTEM
219           if (!CloseHandle (cc->fp))
220             rc = -1;
221 #else
222           rc = close (cc->fp);
223 #endif
224           cc->fp = GNUPG_INVALID_FD;
225         }
226     }
227   return rc;
228 }
229
230
231 /* Try to sync changes to the disk.  This is to avoid data loss during
232    a system crash in write/close/rename cycle on some file
233    systems.  */
234 static int
235 fd_cache_synchronize (const char *fname)
236 {
237   int err = 0;
238
239 #ifdef HAVE_FSYNC
240   close_cache_t cc;
241
242   if (DBG_IOBUF)
243     log_debug ("fd_cache_synchronize (%s)\n", fname);
244
245   for (cc=close_cache; cc; cc = cc->next )
246     {
247       if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
248         {
249           if (DBG_IOBUF)
250             log_debug ("                 did (%s)\n", cc->fname);
251
252           err = fsync (cc->fp);
253         }
254     }
255 #else
256   (void)fname;
257 #endif /*HAVE_FSYNC*/
258
259   return err;
260 }
261
262
263 static gnupg_fd_t
264 direct_open (const char *fname, const char *mode, int mode700)
265 {
266 #ifdef HAVE_W32_SYSTEM
267   unsigned long da, cd, sm;
268   HANDLE hfile;
269
270   (void)mode700;
271   /* Note, that we do not handle all mode combinations */
272
273   /* According to the ReactOS source it seems that open() of the
274    * standard MSW32 crt does open the file in shared mode which is
275    * something new for MS applications ;-)
276    */
277   if (strchr (mode, '+'))
278     {
279       if (fd_cache_invalidate (fname))
280         return GNUPG_INVALID_FD;
281       da = GENERIC_READ | GENERIC_WRITE;
282       cd = OPEN_EXISTING;
283       sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
284     }
285   else if (strchr (mode, 'w'))
286     {
287       if (fd_cache_invalidate (fname))
288         return GNUPG_INVALID_FD;
289       da = GENERIC_WRITE;
290       cd = CREATE_ALWAYS;
291       sm = FILE_SHARE_WRITE;
292     }
293   else
294     {
295       da = GENERIC_READ;
296       cd = OPEN_EXISTING;
297       sm = FILE_SHARE_READ;
298     }
299
300 #ifdef HAVE_W32CE_SYSTEM
301   {
302     wchar_t *wfname = utf8_to_wchar (fname);
303     if (wfname)
304       {
305         hfile = CreateFile (wfname, da, sm, NULL, cd,
306                             FILE_ATTRIBUTE_NORMAL, NULL);
307         xfree (wfname);
308       }
309     else
310       hfile = INVALID_HANDLE_VALUE;
311   }
312 #else
313   hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
314 #endif
315   return hfile;
316
317 #else /*!HAVE_W32_SYSTEM*/
318
319   int oflag;
320   int cflag = S_IRUSR | S_IWUSR;
321
322   if (!mode700)
323     cflag |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
324
325   /* Note, that we do not handle all mode combinations */
326   if (strchr (mode, '+'))
327     {
328       if (fd_cache_invalidate (fname))
329         return GNUPG_INVALID_FD;
330       oflag = O_RDWR;
331     }
332   else if (strchr (mode, 'w'))
333     {
334       if (fd_cache_invalidate (fname))
335         return GNUPG_INVALID_FD;
336       oflag = O_WRONLY | O_CREAT | O_TRUNC;
337     }
338   else
339     {
340       oflag = O_RDONLY;
341     }
342 #ifdef O_BINARY
343   if (strchr (mode, 'b'))
344     oflag |= O_BINARY;
345 #endif
346
347 #ifdef __riscos__
348   {
349     struct stat buf;
350
351     /* Don't allow iobufs on directories */
352     if (!stat (fname, &buf) && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
353       return __set_errno (EISDIR);
354   }
355 #endif
356   return open (fname, oflag, cflag);
357
358 #endif /*!HAVE_W32_SYSTEM*/
359 }
360
361
362 /*
363  * Instead of closing an FD we keep it open and cache it for later reuse
364  * Note that this caching strategy only works if the process does not chdir.
365  */
366 static void
367 fd_cache_close (const char *fname, gnupg_fd_t fp)
368 {
369   close_cache_t cc;
370
371   assert (fp);
372   if (!fname || !*fname)
373     {
374 #ifdef HAVE_W32_SYSTEM
375       CloseHandle (fp);
376 #else
377       close (fp);
378 #endif
379       if (DBG_IOBUF)
380         log_debug ("fd_cache_close (%d) real\n", (int)fp);
381       return;
382     }
383   /* try to reuse a slot */
384   for (cc = close_cache; cc; cc = cc->next)
385     {
386       if (cc->fp == GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
387         {
388           cc->fp = fp;
389           if (DBG_IOBUF)
390             log_debug ("fd_cache_close (%s) used existing slot\n", fname);
391           return;
392         }
393     }
394   /* add a new one */
395   if (DBG_IOBUF)
396     log_debug ("fd_cache_close (%s) new slot created\n", fname);
397   cc = xcalloc (1, sizeof *cc + strlen (fname));
398   strcpy (cc->fname, fname);
399   cc->fp = fp;
400   cc->next = close_cache;
401   close_cache = cc;
402 }
403
404 /*
405  * Do a direct_open on FNAME but first try to reuse one from the fd_cache
406  */
407 static gnupg_fd_t
408 fd_cache_open (const char *fname, const char *mode)
409 {
410   close_cache_t cc;
411
412   assert (fname);
413   for (cc = close_cache; cc; cc = cc->next)
414     {
415       if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
416         {
417           gnupg_fd_t fp = cc->fp;
418           cc->fp = GNUPG_INVALID_FD;
419           if (DBG_IOBUF)
420             log_debug ("fd_cache_open (%s) using cached fp\n", fname);
421 #ifdef HAVE_W32_SYSTEM
422           if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff)
423             {
424               log_error ("rewind file failed on handle %p: ec=%d\n",
425                          fp, (int) GetLastError ());
426               fp = GNUPG_INVALID_FD;
427             }
428 #else
429           if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
430             {
431               log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
432               fp = GNUPG_INVALID_FD;
433             }
434 #endif
435           return fp;
436         }
437     }
438   if (DBG_IOBUF)
439     log_debug ("fd_cache_open (%s) not cached\n", fname);
440   return direct_open (fname, mode, 0);
441 }
442
443
444 static int
445 file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
446              size_t * ret_len)
447 {
448   file_filter_ctx_t *a = opaque;
449   gnupg_fd_t f = a->fp;
450   size_t size = *ret_len;
451   size_t nbytes = 0;
452   int rc = 0;
453
454   (void)chain; /* Not used.  */
455
456   if (control == IOBUFCTRL_UNDERFLOW)
457     {
458       assert (size); /* We need a buffer.  */
459       if (a->eof_seen)
460         {
461           rc = -1;
462           *ret_len = 0;
463         }
464       else
465         {
466 #ifdef HAVE_W32_SYSTEM
467           unsigned long nread;
468
469           nbytes = 0;
470           if (!ReadFile (f, buf, size, &nread, NULL))
471             {
472               int ec = (int) GetLastError ();
473               if (ec != ERROR_BROKEN_PIPE)
474                 {
475                   rc = gpg_error_from_errno (ec);
476                   log_error ("%s: read error: ec=%d\n", a->fname, ec);
477                 }
478             }
479           else if (!nread)
480             {
481               a->eof_seen = 1;
482               rc = -1;
483             }
484           else
485             {
486               nbytes = nread;
487             }
488
489 #else
490
491           int n;
492
493           nbytes = 0;
494           do
495             {
496               n = read (f, buf, size);
497             }
498           while (n == -1 && errno == EINTR);
499           if (n == -1)
500             {                   /* error */
501               if (errno != EPIPE)
502                 {
503                   rc = gpg_error_from_syserror ();
504                   log_error ("%s: read error: %s\n",
505                              a->fname, strerror (errno));
506                 }
507             }
508           else if (!n)
509             {                   /* eof */
510               a->eof_seen = 1;
511               rc = -1;
512             }
513           else
514             {
515               nbytes = n;
516             }
517 #endif
518           *ret_len = nbytes;
519         }
520     }
521   else if (control == IOBUFCTRL_FLUSH)
522     {
523       if (size)
524         {
525 #ifdef HAVE_W32_SYSTEM
526           byte *p = buf;
527           unsigned long n;
528
529           nbytes = size;
530           do
531             {
532               if (size && !WriteFile (f, p, nbytes, &n, NULL))
533                 {
534                   int ec = (int) GetLastError ();
535                   rc = gpg_error_from_errno (ec);
536                   log_error ("%s: write error: ec=%d\n", a->fname, ec);
537                   break;
538                 }
539               p += n;
540               nbytes -= n;
541             }
542           while (nbytes);
543           nbytes = p - buf;
544 #else
545           byte *p = buf;
546           int n;
547
548           nbytes = size;
549           do
550             {
551               do
552                 {
553                   n = write (f, p, nbytes);
554                 }
555               while (n == -1 && errno == EINTR);
556               if (n > 0)
557                 {
558                   p += n;
559                   nbytes -= n;
560                 }
561             }
562           while (n != -1 && nbytes);
563           if (n == -1)
564             {
565               rc = gpg_error_from_syserror ();
566               log_error ("%s: write error: %s\n", a->fname, strerror (errno));
567             }
568           nbytes = p - buf;
569 #endif
570         }
571       *ret_len = nbytes;
572     }
573   else if (control == IOBUFCTRL_INIT)
574     {
575       a->eof_seen = 0;
576       a->keep_open = 0;
577       a->no_cache = 0;
578     }
579   else if (control == IOBUFCTRL_DESC)
580     {
581       *(char **) buf = "file_filter(fd)";
582     }
583   else if (control == IOBUFCTRL_FREE)
584     {
585       if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT)
586         {
587           if (DBG_IOBUF)
588             log_debug ("%s: close fd/handle %d\n", a->fname, FD2INT (f));
589           if (!a->keep_open)
590             fd_cache_close (a->no_cache ? NULL : a->fname, f);
591         }
592       f = GNUPG_INVALID_FD;
593       xfree (a); /* We can free our context now. */
594     }
595
596   return rc;
597 }
598
599
600 /* Similar to file_filter but using the estream system.  */
601 static int
602 file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
603                 size_t * ret_len)
604 {
605   file_es_filter_ctx_t *a = opaque;
606   estream_t f = a->fp;
607   size_t size = *ret_len;
608   size_t nbytes = 0;
609   int rc = 0;
610
611   (void)chain; /* Not used.  */
612
613   if (control == IOBUFCTRL_UNDERFLOW)
614     {
615       assert (size); /* We need a buffer.  */
616       if (a->eof_seen)
617         {
618           rc = -1;
619           *ret_len = 0;
620         }
621       else
622         {
623           nbytes = 0;
624           rc = es_read (f, buf, size, &nbytes);
625           if (rc == -1)
626             {                   /* error */
627               rc = gpg_error_from_syserror ();
628               log_error ("%s: read error: %s\n", a->fname, strerror (errno));
629             }
630           else if (!nbytes)
631             {                   /* eof */
632               a->eof_seen = 1;
633               rc = -1;
634             }
635           *ret_len = nbytes;
636         }
637     }
638   else if (control == IOBUFCTRL_FLUSH)
639     {
640       if (size)
641         {
642           byte *p = buf;
643           size_t nwritten;
644
645           nbytes = size;
646           do
647             {
648               nwritten = 0;
649               if (es_write (f, p, nbytes, &nwritten))
650                 {
651                   rc = gpg_error_from_syserror ();
652                   log_error ("%s: write error: %s\n",
653                              a->fname, strerror (errno));
654                   break;
655                 }
656               p += nwritten;
657               nbytes -= nwritten;
658             }
659           while (nbytes);
660           nbytes = p - buf;
661         }
662       *ret_len = nbytes;
663     }
664   else if (control == IOBUFCTRL_INIT)
665     {
666       a->eof_seen = 0;
667       a->no_cache = 0;
668     }
669   else if (control == IOBUFCTRL_DESC)
670     {
671       *(char **) buf = "estream_filter";
672     }
673   else if (control == IOBUFCTRL_FREE)
674     {
675       if (f != es_stdin && f != es_stdout)
676         {
677           if (DBG_IOBUF)
678             log_debug ("%s: es_fclose %p\n", a->fname, f);
679           if (!a->keep_open)
680             es_fclose (f);
681         }
682       f = NULL;
683       xfree (a); /* We can free our context now. */
684     }
685
686   return rc;
687 }
688
689
690 #ifdef HAVE_W32_SYSTEM
691 /* Because network sockets are special objects under Lose32 we have to
692    use a dedicated filter for them. */
693 static int
694 sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
695              size_t * ret_len)
696 {
697   sock_filter_ctx_t *a = opaque;
698   size_t size = *ret_len;
699   size_t nbytes = 0;
700   int rc = 0;
701
702   (void)chain;
703
704   if (control == IOBUFCTRL_UNDERFLOW)
705     {
706       assert (size);            /* need a buffer */
707       if (a->eof_seen)
708         {
709           rc = -1;
710           *ret_len = 0;
711         }
712       else
713         {
714           int nread;
715
716           nread = recv (a->sock, buf, size, 0);
717           if (nread == SOCKET_ERROR)
718             {
719               int ec = (int) WSAGetLastError ();
720               rc = gpg_error_from_errno (ec);
721               log_error ("socket read error: ec=%d\n", ec);
722             }
723           else if (!nread)
724             {
725               a->eof_seen = 1;
726               rc = -1;
727             }
728           else
729             {
730               nbytes = nread;
731             }
732           *ret_len = nbytes;
733         }
734     }
735   else if (control == IOBUFCTRL_FLUSH)
736     {
737       if (size)
738         {
739           byte *p = buf;
740           int n;
741
742           nbytes = size;
743           do
744             {
745               n = send (a->sock, p, nbytes, 0);
746               if (n == SOCKET_ERROR)
747                 {
748                   int ec = (int) WSAGetLastError ();
749                   rc = gpg_error_from_errno (ec);
750                   log_error ("socket write error: ec=%d\n", ec);
751                   break;
752                 }
753               p += n;
754               nbytes -= n;
755             }
756           while (nbytes);
757           nbytes = p - buf;
758         }
759       *ret_len = nbytes;
760     }
761   else if (control == IOBUFCTRL_INIT)
762     {
763       a->eof_seen = 0;
764       a->keep_open = 0;
765       a->no_cache = 0;
766     }
767   else if (control == IOBUFCTRL_DESC)
768     {
769       *(char **) buf = "sock_filter";
770     }
771   else if (control == IOBUFCTRL_FREE)
772     {
773       if (!a->keep_open)
774         closesocket (a->sock);
775       xfree (a);                /* we can free our context now */
776     }
777   return rc;
778 }
779 #endif /*HAVE_W32_SYSTEM*/
780
781 /****************
782  * This is used to implement the block write mode.
783  * Block reading is done on a byte by byte basis in readbyte(),
784  * without a filter
785  */
786 static int
787 block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
788               size_t * ret_len)
789 {
790   block_filter_ctx_t *a = opaque;
791   char *buf = (char *)buffer;
792   size_t size = *ret_len;
793   int c, needed, rc = 0;
794   char *p;
795
796   if (control == IOBUFCTRL_UNDERFLOW)
797     {
798       size_t n = 0;
799
800       p = buf;
801       assert (size);            /* need a buffer */
802       if (a->eof)               /* don't read any further */
803         rc = -1;
804       while (!rc && size)
805         {
806           if (!a->size)
807             {                   /* get the length bytes */
808               if (a->partial == 2)
809                 {
810                   a->eof = 1;
811                   if (!n)
812                     rc = -1;
813                   break;
814                 }
815               else if (a->partial)
816                 {
817                   /* These OpenPGP introduced huffman like encoded length
818                    * bytes are really a mess :-( */
819                   if (a->first_c)
820                     {
821                       c = a->first_c;
822                       a->first_c = 0;
823                     }
824                   else if ((c = iobuf_get (chain)) == -1)
825                     {
826                       log_error ("block_filter: 1st length byte missing\n");
827                       rc = GPG_ERR_BAD_DATA;
828                       break;
829                     }
830                   if (c < 192)
831                     {
832                       a->size = c;
833                       a->partial = 2;
834                       if (!a->size)
835                         {
836                           a->eof = 1;
837                           if (!n)
838                             rc = -1;
839                           break;
840                         }
841                     }
842                   else if (c < 224)
843                     {
844                       a->size = (c - 192) * 256;
845                       if ((c = iobuf_get (chain)) == -1)
846                         {
847                           log_error
848                             ("block_filter: 2nd length byte missing\n");
849                           rc = GPG_ERR_BAD_DATA;
850                           break;
851                         }
852                       a->size += c + 192;
853                       a->partial = 2;
854                       if (!a->size)
855                         {
856                           a->eof = 1;
857                           if (!n)
858                             rc = -1;
859                           break;
860                         }
861                     }
862                   else if (c == 255)
863                     {
864                       a->size = (size_t)iobuf_get (chain) << 24;
865                       a->size |= iobuf_get (chain) << 16;
866                       a->size |= iobuf_get (chain) << 8;
867                       if ((c = iobuf_get (chain)) == -1)
868                         {
869                           log_error ("block_filter: invalid 4 byte length\n");
870                           rc = GPG_ERR_BAD_DATA;
871                           break;
872                         }
873                       a->size |= c;
874                       a->partial = 2;
875                       if (!a->size)
876                         {
877                           a->eof = 1;
878                           if (!n)
879                             rc = -1;
880                           break;
881                         }
882                     }
883                   else
884                     { /* Next partial body length. */
885                       a->size = 1 << (c & 0x1f);
886                     }
887                   /*  log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
888                 }
889               else
890                 BUG ();
891             }
892
893           while (!rc && size && a->size)
894             {
895               needed = size < a->size ? size : a->size;
896               c = iobuf_read (chain, p, needed);
897               if (c < needed)
898                 {
899                   if (c == -1)
900                     c = 0;
901                   log_error
902                     ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
903                      a, (ulong) size + c, (ulong) a->size + c);
904                   rc = GPG_ERR_BAD_DATA;
905                 }
906               else
907                 {
908                   size -= c;
909                   a->size -= c;
910                   p += c;
911                   n += c;
912                 }
913             }
914         }
915       *ret_len = n;
916     }
917   else if (control == IOBUFCTRL_FLUSH)
918     {
919       if (a->partial)
920         {                       /* the complicated openpgp scheme */
921           size_t blen, n, nbytes = size + a->buflen;
922
923           assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
924           if (nbytes < OP_MIN_PARTIAL_CHUNK)
925             {
926               /* not enough to write a partial block out; so we store it */
927               if (!a->buffer)
928                 a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
929               memcpy (a->buffer + a->buflen, buf, size);
930               a->buflen += size;
931             }
932           else
933             {                   /* okay, we can write out something */
934               /* do this in a loop to use the most efficient block lengths */
935               p = buf;
936               do
937                 {
938                   /* find the best matching block length - this is limited
939                    * by the size of the internal buffering */
940                   for (blen = OP_MIN_PARTIAL_CHUNK * 2,
941                        c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
942                        blen *= 2, c++)
943                     ;
944                   blen /= 2;
945                   c--;
946                   /* write the partial length header */
947                   assert (c <= 0x1f);   /*;-) */
948                   c |= 0xe0;
949                   iobuf_put (chain, c);
950                   if ((n = a->buflen))
951                     {           /* write stuff from the buffer */
952                       assert (n == OP_MIN_PARTIAL_CHUNK);
953                       if (iobuf_write (chain, a->buffer, n))
954                         rc = gpg_error_from_syserror ();
955                       a->buflen = 0;
956                       nbytes -= n;
957                     }
958                   if ((n = nbytes) > blen)
959                     n = blen;
960                   if (n && iobuf_write (chain, p, n))
961                     rc = gpg_error_from_syserror ();
962                   p += n;
963                   nbytes -= n;
964                 }
965               while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
966               /* store the rest in the buffer */
967               if (!rc && nbytes)
968                 {
969                   assert (!a->buflen);
970                   assert (nbytes < OP_MIN_PARTIAL_CHUNK);
971                   if (!a->buffer)
972                     a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
973                   memcpy (a->buffer, p, nbytes);
974                   a->buflen = nbytes;
975                 }
976             }
977         }
978       else
979         BUG ();
980     }
981   else if (control == IOBUFCTRL_INIT)
982     {
983       if (DBG_IOBUF)
984         log_debug ("init block_filter %p\n", a);
985       if (a->partial)
986         a->count = 0;
987       else if (a->use == IOBUF_INPUT)
988         a->count = a->size = 0;
989       else
990         a->count = a->size;     /* force first length bytes */
991       a->eof = 0;
992       a->buffer = NULL;
993       a->buflen = 0;
994     }
995   else if (control == IOBUFCTRL_DESC)
996     {
997       *(char **) buf = "block_filter";
998     }
999   else if (control == IOBUFCTRL_FREE)
1000     {
1001       if (a->use == IOBUF_OUTPUT)
1002         {                       /* write the end markers */
1003           if (a->partial)
1004             {
1005               u32 len;
1006               /* write out the remaining bytes without a partial header
1007                * the length of this header may be 0 - but if it is
1008                * the first block we are not allowed to use a partial header
1009                * and frankly we can't do so, because this length must be
1010                * a power of 2. This is _really_ complicated because we
1011                * have to check the possible length of a packet prior
1012                * to it's creation: a chain of filters becomes complicated
1013                * and we need a lot of code to handle compressed packets etc.
1014                *   :-(((((((
1015                */
1016               /* construct header */
1017               len = a->buflen;
1018               /*log_debug("partial: remaining length=%u\n", len ); */
1019               if (len < 192)
1020                 rc = iobuf_put (chain, len);
1021               else if (len < 8384)
1022                 {
1023                   if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
1024                     rc = iobuf_put (chain, ((len - 192) % 256));
1025                 }
1026               else
1027                 {               /* use a 4 byte header */
1028                   if (!(rc = iobuf_put (chain, 0xff)))
1029                     if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
1030                       if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
1031                         if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
1032                           rc = iobuf_put (chain, len & 0xff);
1033                 }
1034               if (!rc && len)
1035                 rc = iobuf_write (chain, a->buffer, len);
1036               if (rc)
1037                 {
1038                   log_error ("block_filter: write error: %s\n",
1039                              strerror (errno));
1040                   rc = gpg_error_from_syserror ();
1041                 }
1042               xfree (a->buffer);
1043               a->buffer = NULL;
1044               a->buflen = 0;
1045             }
1046           else
1047             BUG ();
1048         }
1049       else if (a->size)
1050         {
1051           log_error ("block_filter: pending bytes!\n");
1052         }
1053       if (DBG_IOBUF)
1054         log_debug ("free block_filter %p\n", a);
1055       xfree (a);                /* we can free our context now */
1056     }
1057
1058   return rc;
1059 }
1060
1061 static const char *
1062 iobuf_desc (iobuf_t a)
1063 {
1064   size_t dummy_len = 0;
1065   const char *desc = "?";
1066
1067   if (! a || ! a->filter)
1068     return desc;
1069
1070   a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
1071              (byte *) & desc, &dummy_len);
1072
1073   return desc;
1074 }
1075
1076 static void
1077 print_chain (iobuf_t a)
1078 {
1079   if (!DBG_IOBUF)
1080     return;
1081   for (; a; a = a->chain)
1082     {
1083
1084       log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
1085                  a->no, a->subno, iobuf_desc (a), a->filter_eof,
1086                  (int) a->d.start, (int) a->d.len);
1087     }
1088 }
1089
1090 int
1091 iobuf_print_chain (iobuf_t a)
1092 {
1093   print_chain (a);
1094   return 0;
1095 }
1096
1097 iobuf_t
1098 iobuf_alloc (int use, size_t bufsize)
1099 {
1100   iobuf_t a;
1101   static int number = 0;
1102
1103   assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
1104           || use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
1105   if (bufsize == 0)
1106     {
1107       log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
1108       bufsize = IOBUF_BUFFER_SIZE;
1109     }
1110
1111   a = xcalloc (1, sizeof *a);
1112   a->use = use;
1113   a->d.buf = xmalloc (bufsize);
1114   a->d.size = bufsize;
1115   a->no = ++number;
1116   a->subno = 0;
1117   a->real_fname = NULL;
1118   return a;
1119 }
1120
1121 int
1122 iobuf_close (iobuf_t a)
1123 {
1124   iobuf_t a_chain;
1125   size_t dummy_len = 0;
1126   int rc = 0;
1127
1128   for (; a; a = a_chain)
1129     {
1130       int rc2 = 0;
1131
1132       a_chain = a->chain;
1133
1134       if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1135         log_error ("filter_flush failed on close: %s\n", gpg_strerror (rc));
1136
1137       if (DBG_IOBUF)
1138         log_debug ("iobuf-%d.%d: close '%s'\n",
1139                    a->no, a->subno, iobuf_desc (a));
1140
1141       if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1142                                          a->chain, NULL, &dummy_len)))
1143         log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1144       if (! rc && rc2)
1145         /* Whoops!  An error occurred.  Save it in RC if we haven't
1146            already recorded an error.  */
1147         rc = rc2;
1148
1149       xfree (a->real_fname);
1150       if (a->d.buf)
1151         {
1152           memset (a->d.buf, 0, a->d.size);      /* erase the buffer */
1153           xfree (a->d.buf);
1154         }
1155       xfree (a);
1156     }
1157   return rc;
1158 }
1159
1160 int
1161 iobuf_cancel (iobuf_t a)
1162 {
1163   const char *s;
1164   iobuf_t a2;
1165   int rc;
1166 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1167   char *remove_name = NULL;
1168 #endif
1169
1170   if (a && a->use == IOBUF_OUTPUT)
1171     {
1172       s = iobuf_get_real_fname (a);
1173       if (s && *s)
1174         {
1175 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1176           remove_name = xstrdup (s);
1177 #else
1178           remove (s);
1179 #endif
1180         }
1181     }
1182
1183   /* send a cancel message to all filters */
1184   for (a2 = a; a2; a2 = a2->chain)
1185     {
1186       size_t dummy;
1187       if (a2->filter)
1188         a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1189     }
1190
1191   rc = iobuf_close (a);
1192 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1193   if (remove_name)
1194     {
1195       /* Argg, MSDOS does not allow to remove open files.  So
1196        * we have to do it here */
1197 #ifdef HAVE_W32CE_SYSTEM
1198       wchar_t *wtmp = utf8_to_wchar (remove_name);
1199       if (wtmp)
1200         DeleteFile (wtmp);
1201       xfree (wtmp);
1202 #else
1203       remove (remove_name);
1204 #endif
1205       xfree (remove_name);
1206     }
1207 #endif
1208   return rc;
1209 }
1210
1211
1212 iobuf_t
1213 iobuf_temp (void)
1214 {
1215   return iobuf_alloc (IOBUF_OUTPUT_TEMP, IOBUF_BUFFER_SIZE);
1216 }
1217
1218 iobuf_t
1219 iobuf_temp_with_content (const char *buffer, size_t length)
1220 {
1221   iobuf_t a;
1222   int i;
1223
1224   a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
1225   assert (length == a->d.size);
1226   /* memcpy (a->d.buf, buffer, length); */
1227   for (i=0; i < length; i++)
1228     a->d.buf[i] = buffer[i];
1229   a->d.len = length;
1230
1231   return a;
1232 }
1233
1234 void
1235 iobuf_enable_special_filenames (int yes)
1236 {
1237   special_names_enabled = yes;
1238 }
1239
1240
1241 /* See whether the filename has the form "-&nnnn", where n is a
1242    non-zero number.  Returns this number or -1 if it is not the
1243    case.  */
1244 static int
1245 check_special_filename (const char *fname)
1246 {
1247   if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
1248     {
1249       int i;
1250
1251       fname += 2;
1252       for (i = 0; digitp (fname+i); i++)
1253         ;
1254       if (!fname[i])
1255         return atoi (fname);
1256     }
1257   return -1;
1258 }
1259
1260
1261 int
1262 iobuf_is_pipe_filename (const char *fname)
1263 {
1264   if (!fname || (*fname=='-' && !fname[1]) )
1265     return 1;
1266   return check_special_filename (fname) != -1;
1267 }
1268
1269 static iobuf_t
1270 do_open (const char *fname, int special_filenames,
1271          int use, const char *opentype, int mode700)
1272 {
1273   iobuf_t a;
1274   gnupg_fd_t fp;
1275   file_filter_ctx_t *fcx;
1276   size_t len = 0;
1277   int print_only = 0;
1278   int fd;
1279
1280   assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
1281
1282   if (special_filenames
1283       /* NULL or '-'.  */
1284       && (!fname || (*fname == '-' && !fname[1])))
1285     {
1286       if (use == IOBUF_INPUT)
1287         {
1288           fp = FD_FOR_STDIN;
1289           fname = "[stdin]";
1290         }
1291       else
1292         {
1293           fp = FD_FOR_STDOUT;
1294           fname = "[stdout]";
1295         }
1296       print_only = 1;
1297     }
1298   else if (!fname)
1299     return NULL;
1300   else if (special_filenames && (fd = check_special_filename (fname)) != -1)
1301     return iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT ? 0 : 1),
1302                          opentype);
1303   else
1304     {
1305       if (use == IOBUF_INPUT)
1306         fp = fd_cache_open (fname, opentype);
1307       else
1308         fp = direct_open (fname, opentype, mode700);
1309       if (fp == GNUPG_INVALID_FD)
1310         return NULL;
1311     }
1312
1313   a = iobuf_alloc (use, IOBUF_BUFFER_SIZE);
1314   fcx = xmalloc (sizeof *fcx + strlen (fname));
1315   fcx->fp = fp;
1316   fcx->print_only_name = print_only;
1317   strcpy (fcx->fname, fname);
1318   if (!print_only)
1319     a->real_fname = xstrdup (fname);
1320   a->filter = file_filter;
1321   a->filter_ov = fcx;
1322   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1323   if (DBG_IOBUF)
1324     log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n",
1325                a->no, a->subno, fname, iobuf_desc (a), FD2INT (fcx->fp));
1326
1327   return a;
1328 }
1329
1330 iobuf_t
1331 iobuf_open (const char *fname)
1332 {
1333   return do_open (fname, 1, IOBUF_INPUT, "rb", 0);
1334 }
1335
1336 iobuf_t
1337 iobuf_create (const char *fname, int mode700)
1338 {
1339   return do_open (fname, 1, IOBUF_OUTPUT, "wb", mode700);
1340 }
1341
1342 iobuf_t
1343 iobuf_openrw (const char *fname)
1344 {
1345   return do_open (fname, 0, IOBUF_OUTPUT, "r+b", 0);
1346 }
1347
1348
1349 static iobuf_t
1350 do_iobuf_fdopen (int fd, const char *mode, int keep_open)
1351 {
1352   iobuf_t a;
1353   gnupg_fd_t fp;
1354   file_filter_ctx_t *fcx;
1355   size_t len;
1356
1357   fp = INT2FD (fd);
1358
1359   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1360                    IOBUF_BUFFER_SIZE);
1361   fcx = xmalloc (sizeof *fcx + 20);
1362   fcx->fp = fp;
1363   fcx->print_only_name = 1;
1364   fcx->keep_open = keep_open;
1365   sprintf (fcx->fname, "[fd %d]", fd);
1366   a->filter = file_filter;
1367   a->filter_ov = fcx;
1368   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1369   if (DBG_IOBUF)
1370     log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
1371                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1372   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1373   return a;
1374 }
1375
1376
1377 iobuf_t
1378 iobuf_fdopen (int fd, const char *mode)
1379 {
1380   return do_iobuf_fdopen (fd, mode, 0);
1381 }
1382
1383 iobuf_t
1384 iobuf_fdopen_nc (int fd, const char *mode)
1385 {
1386   return do_iobuf_fdopen (fd, mode, 1);
1387 }
1388
1389
1390 iobuf_t
1391 iobuf_esopen (estream_t estream, const char *mode, int keep_open)
1392 {
1393   iobuf_t a;
1394   file_es_filter_ctx_t *fcx;
1395   size_t len = 0;
1396
1397   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1398                    IOBUF_BUFFER_SIZE);
1399   fcx = xtrymalloc (sizeof *fcx + 30);
1400   fcx->fp = estream;
1401   fcx->print_only_name = 1;
1402   fcx->keep_open = keep_open;
1403   sprintf (fcx->fname, "[fd %p]", estream);
1404   a->filter = file_es_filter;
1405   a->filter_ov = fcx;
1406   file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1407   if (DBG_IOBUF)
1408     log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
1409                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1410   return a;
1411 }
1412
1413
1414 iobuf_t
1415 iobuf_sockopen (int fd, const char *mode)
1416 {
1417   iobuf_t a;
1418 #ifdef HAVE_W32_SYSTEM
1419   sock_filter_ctx_t *scx;
1420   size_t len;
1421
1422   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1423                    IOBUF_BUFFER_SIZE);
1424   scx = xmalloc (sizeof *scx + 25);
1425   scx->sock = fd;
1426   scx->print_only_name = 1;
1427   sprintf (scx->fname, "[sock %d]", fd);
1428   a->filter = sock_filter;
1429   a->filter_ov = scx;
1430   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1431   if (DBG_IOBUF)
1432     log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
1433   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1434 #else
1435   a = iobuf_fdopen (fd, mode);
1436 #endif
1437   return a;
1438 }
1439
1440 int
1441 iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
1442 {
1443   if (cmd == IOBUF_IOCTL_KEEP_OPEN)
1444     {
1445       /* Keep system filepointer/descriptor open.  This was used in
1446          the past by http.c; this ioctl is not directly used
1447          anymore.  */
1448       if (DBG_IOBUF)
1449         log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
1450                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
1451                    intval);
1452       for (; a; a = a->chain)
1453         if (!a->chain && a->filter == file_filter)
1454           {
1455             file_filter_ctx_t *b = a->filter_ov;
1456             b->keep_open = intval;
1457             return 0;
1458           }
1459 #ifdef HAVE_W32_SYSTEM
1460         else if (!a->chain && a->filter == sock_filter)
1461           {
1462             sock_filter_ctx_t *b = a->filter_ov;
1463             b->keep_open = intval;
1464             return 0;
1465           }
1466 #endif
1467     }
1468   else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
1469     {
1470       if (DBG_IOBUF)
1471         log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
1472                    ptrval ? (char *) ptrval : "?");
1473       if (!a && !intval && ptrval)
1474         {
1475           if (fd_cache_invalidate (ptrval))
1476             return -1;
1477           return 0;
1478         }
1479     }
1480   else if (cmd == IOBUF_IOCTL_NO_CACHE)
1481     {
1482       if (DBG_IOBUF)
1483         log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
1484                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
1485                    intval);
1486       for (; a; a = a->chain)
1487         if (!a->chain && a->filter == file_filter)
1488           {
1489             file_filter_ctx_t *b = a->filter_ov;
1490             b->no_cache = intval;
1491             return 0;
1492           }
1493 #ifdef HAVE_W32_SYSTEM
1494         else if (!a->chain && a->filter == sock_filter)
1495           {
1496             sock_filter_ctx_t *b = a->filter_ov;
1497             b->no_cache = intval;
1498             return 0;
1499           }
1500 #endif
1501     }
1502   else if (cmd == IOBUF_IOCTL_FSYNC)
1503     {
1504       /* Do a fsync on the open fd and return any errors to the caller
1505          of iobuf_ioctl.  Note that we work on a file name here. */
1506       if (DBG_IOBUF)
1507         log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
1508                    ptrval? (const char*)ptrval:"<null>");
1509
1510         if (!a && !intval && ptrval)
1511           {
1512             return fd_cache_synchronize (ptrval);
1513           }
1514       }
1515
1516
1517   return -1;
1518 }
1519
1520
1521 /****************
1522  * Register an i/o filter.
1523  */
1524 int
1525 iobuf_push_filter (iobuf_t a,
1526                    int (*f) (void *opaque, int control,
1527                              iobuf_t chain, byte * buf, size_t * len),
1528                    void *ov)
1529 {
1530   return iobuf_push_filter2 (a, f, ov, 0);
1531 }
1532
1533 int
1534 iobuf_push_filter2 (iobuf_t a,
1535                     int (*f) (void *opaque, int control,
1536                               iobuf_t chain, byte * buf, size_t * len),
1537                     void *ov, int rel_ov)
1538 {
1539   iobuf_t b;
1540   size_t dummy_len = 0;
1541   int rc = 0;
1542
1543   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1544     return rc;
1545
1546   if (a->subno >= MAX_NESTING_FILTER)
1547     {
1548       log_error ("i/o filter too deeply nested - corrupted data?\n");
1549       return GPG_ERR_BAD_DATA;
1550     }
1551
1552   /* We want to create a new filter and put it in front of A.  A
1553      simple implementation would do:
1554
1555        b = iobuf_alloc (...);
1556        b->chain = a;
1557        return a;
1558
1559      This is a bit problematic: A is the head of the pipeline and
1560      there are potentially many pointers to it.  Requiring the caller
1561      to update all of these pointers is a burden.
1562
1563      An alternative implementation would add a level of indirection.
1564      For instance, we could use a pipeline object, which contains a
1565      pointer to the first filter in the pipeline.  This is not what we
1566      do either.
1567
1568      Instead, we allocate a new buffer (B) and copy the first filter's
1569      state into that and use the initial buffer (A) for the new
1570      filter.  One limitation of this approach is that it is not
1571      practical to maintain a pointer to a specific filter's state.
1572
1573      Before:
1574
1575            A
1576            |
1577            v 0x100               0x200
1578            +----------+          +----------+
1579            | filter x |--------->| filter y |---->....
1580            +----------+          +----------+
1581
1582      After:           B
1583                       |
1584                       v 0x300
1585                       +----------+
1586            A          | filter x |
1587            |          +----------+
1588            v 0x100    ^          v 0x200
1589            +----------+          +----------+
1590            | filter w |          | filter y |---->....
1591            +----------+          +----------+
1592
1593      Note: filter x's address changed from 0x100 to 0x300, but A still
1594      points to the head of the pipeline.
1595   */
1596
1597   b = xmalloc (sizeof *b);
1598   memcpy (b, a, sizeof *b);
1599   /* fixme: it is stupid to keep a copy of the name at every level
1600    * but we need the name somewhere because the name known by file_filter
1601    * may have been released when we need the name of the file */
1602   b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1603   /* remove the filter stuff from the new stream */
1604   a->filter = NULL;
1605   a->filter_ov = NULL;
1606   a->filter_ov_owner = 0;
1607   a->filter_eof = 0;
1608   if (a->use == IOBUF_OUTPUT_TEMP)
1609     /* A TEMP filter buffers any data sent to it; it does not forward
1610        any data down the pipeline.  If we add a new filter to the
1611        pipeline, it shouldn't also buffer data.  It should send it
1612        downstream to be buffered.  Thus, the correct type for a filter
1613        added in front of an IOBUF_OUTPUT_TEMP filter is IOBUF_OUPUT, not
1614        IOBUF_OUTPUT_TEMP.  */
1615     {
1616       a->use = IOBUF_OUTPUT;
1617
1618       /* When pipeline is written to, the temp buffer's size is
1619          increased accordingly.  We don't need to allocate a 10 MB
1620          buffer for a non-terminal filter.  Just use the default
1621          size.  */
1622       a->d.size = IOBUF_BUFFER_SIZE;
1623     }
1624   else if (a->use == IOBUF_INPUT_TEMP)
1625     /* Same idea as above.  */
1626     {
1627       a->use = IOBUF_INPUT;
1628       a->d.size = IOBUF_BUFFER_SIZE;
1629     }
1630
1631   /* The new filter (A) gets a new buffer.
1632
1633      If the pipeline is an output or temp pipeline, then giving the
1634      buffer to the new filter means that data that was written before
1635      the filter was pushed gets sent to the filter.  That's clearly
1636      wrong.
1637
1638      If the pipeline is an input pipeline, then giving the buffer to
1639      the new filter (A) means that data that has read from (B), but
1640      not yet read from the pipeline won't be processed by the new
1641      filter (A)!  That's certainly not what we want.  */
1642   a->d.buf = xmalloc (a->d.size);
1643   a->d.len = 0;
1644   a->d.start = 0;
1645
1646   /* disable nlimit for the new stream */
1647   a->ntotal = b->ntotal + b->nbytes;
1648   a->nlimit = a->nbytes = 0;
1649   a->nofast = 0;
1650   /* make a link from the new stream to the original stream */
1651   a->chain = b;
1652
1653   /* setup the function on the new stream */
1654   a->filter = f;
1655   a->filter_ov = ov;
1656   a->filter_ov_owner = rel_ov;
1657
1658   a->subno = b->subno + 1;
1659
1660   if (DBG_IOBUF)
1661     {
1662       log_debug ("iobuf-%d.%d: push '%s'\n",
1663                  a->no, a->subno, iobuf_desc (a));
1664       print_chain (a);
1665     }
1666
1667   /* now we can initialize the new function if we have one */
1668   if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1669                                     NULL, &dummy_len)))
1670     log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1671   return rc;
1672 }
1673
1674 /****************
1675  * Remove an i/o filter.
1676  */
1677 static int
1678 pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1679                                iobuf_t chain, byte * buf, size_t * len),
1680             void *ov)
1681 {
1682   iobuf_t b;
1683   size_t dummy_len = 0;
1684   int rc = 0;
1685
1686   if (DBG_IOBUF)
1687     log_debug ("iobuf-%d.%d: pop '%s'\n",
1688                a->no, a->subno, iobuf_desc (a));
1689   if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
1690     {
1691       /* This should be the last filter in the pipeline.  */
1692       assert (! a->chain);
1693       return 0;
1694     }
1695   if (!a->filter)
1696     {                           /* this is simple */
1697       b = a->chain;
1698       assert (b);
1699       xfree (a->d.buf);
1700       xfree (a->real_fname);
1701       memcpy (a, b, sizeof *a);
1702       xfree (b);
1703       return 0;
1704     }
1705   for (b = a; b; b = b->chain)
1706     if (b->filter == f && (!ov || b->filter_ov == ov))
1707       break;
1708   if (!b)
1709     log_bug ("pop_filter(): filter function not found\n");
1710
1711   /* flush this stream if it is an output stream */
1712   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (b)))
1713     {
1714       log_error ("filter_flush failed in pop_filter: %s\n", gpg_strerror (rc));
1715       return rc;
1716     }
1717   /* and tell the filter to free it self */
1718   if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1719                                     NULL, &dummy_len)))
1720     {
1721       log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1722       return rc;
1723     }
1724   if (b->filter_ov && b->filter_ov_owner)
1725     {
1726       xfree (b->filter_ov);
1727       b->filter_ov = NULL;
1728     }
1729
1730
1731   /* and see how to remove it */
1732   if (a == b && !b->chain)
1733     log_bug ("can't remove the last filter from the chain\n");
1734   else if (a == b)
1735     {                           /* remove the first iobuf from the chain */
1736       /* everything from b is copied to a. This is save because
1737        * a flush has been done on the to be removed entry
1738        */
1739       b = a->chain;
1740       xfree (a->d.buf);
1741       xfree (a->real_fname);
1742       memcpy (a, b, sizeof *a);
1743       xfree (b);
1744       if (DBG_IOBUF)
1745         log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1746     }
1747   else if (!b->chain)
1748     {                           /* remove the last iobuf from the chain */
1749       log_bug ("Ohh jeee, trying to remove a head filter\n");
1750     }
1751   else
1752     {                           /* remove an intermediate iobuf from the chain */
1753       log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1754     }
1755
1756   return rc;
1757 }
1758
1759
1760 /****************
1761  * read underflow: read more bytes into the buffer and return
1762  * the first byte or -1 on EOF.
1763  */
1764 static int
1765 underflow (iobuf_t a, int clear_pending_eof)
1766 {
1767   size_t len;
1768   int rc;
1769
1770   if (DBG_IOBUF)
1771     log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
1772                a->no, a->subno,
1773                (int) a->d.size, (int) (a->d.len - a->d.start),
1774                (int) (a->d.size - (a->d.len - a->d.start)));
1775
1776   if (a->use == IOBUF_INPUT_TEMP)
1777     /* By definition, there isn't more data to read into the
1778        buffer.  */
1779     return -1;
1780
1781   assert (a->use == IOBUF_INPUT);
1782
1783   /* If there is still some buffered data, then move it to the start
1784      of the buffer and try to fill the end of the buffer.  (This is
1785      useful if we are called from iobuf_peek().)  */
1786   assert (a->d.start <= a->d.len);
1787   a->d.len -= a->d.start;
1788   memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
1789   a->d.start = 0;
1790
1791   if (a->d.len == 0 && a->filter_eof)
1792     /* The last time we tried to read from this filter, we got an EOF.
1793        We couldn't return the EOF, because there was buffered data.
1794        Since there is no longer any buffered data, return the
1795        error.  */
1796     {
1797       if (DBG_IOBUF)
1798         log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
1799                    a->no, a->subno);
1800       if (! clear_pending_eof)
1801         return -1;
1802
1803       if (a->chain)
1804         /* A filter follows this one.  Free this filter.  */
1805         {
1806           iobuf_t b = a->chain;
1807           if (DBG_IOBUF)
1808             log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
1809                        a->no, a->subno);
1810           xfree (a->d.buf);
1811           xfree (a->real_fname);
1812           memcpy (a, b, sizeof *a);
1813           xfree (b);
1814           print_chain (a);
1815         }
1816       else
1817         a->filter_eof = 0;      /* for the top level filter */
1818       return -1;                /* return one(!) EOF */
1819     }
1820
1821   if (a->d.len == 0 && a->error)
1822     /* The last time we tried to read from this filter, we got an
1823        error.  We couldn't return the error, because there was
1824        buffered data.  Since there is no longer any buffered data,
1825        return the error.  */
1826     {
1827       if (DBG_IOBUF)
1828         log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
1829                    a->no, a->subno, gpg_strerror (a->error));
1830       return -1;
1831     }
1832
1833   if (a->filter && ! a->filter_eof && ! a->error)
1834     /* We have a filter function and the last time we tried to read we
1835        didn't get an EOF or an error.  Try to fill the buffer.  */
1836     {
1837       /* Be careful to account for any buffered data.  */
1838       len = a->d.size - a->d.len;
1839       if (DBG_IOBUF)
1840         log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
1841                    a->no, a->subno, (ulong) len);
1842       if (len == 0)
1843         /* There is no space for more data.  Don't bother calling
1844            A->FILTER.  */
1845         rc = 0;
1846       else
1847         rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1848                         &a->d.buf[a->d.len], &len);
1849       a->d.len += len;
1850
1851       if (DBG_IOBUF)
1852         log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s), read %lu bytes\n",
1853                    a->no, a->subno,
1854                    rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
1855                    (ulong) len);
1856 /*          if( a->no == 1 ) */
1857 /*                   log_hexdump ("     data:", a->d.buf, len); */
1858
1859       if (rc == -1)
1860         /* EOF.  */
1861         {
1862           size_t dummy_len = 0;
1863
1864           /* Tell the filter to free itself */
1865           if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
1866                                NULL, &dummy_len)))
1867             log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1868
1869           /* Free everything except for the internal buffer.  */
1870           if (a->filter_ov && a->filter_ov_owner)
1871             xfree (a->filter_ov);
1872           a->filter_ov = NULL;
1873           a->filter = NULL;
1874           a->filter_eof = 1;
1875
1876           if (clear_pending_eof && a->d.len == 0 && a->chain)
1877             /* We don't need to keep this filter around at all:
1878
1879                  - we got an EOF
1880                  - we have no buffered data
1881                  - a filter follows this one.
1882
1883               Unlink this filter.  */
1884             {
1885               iobuf_t b = a->chain;
1886               if (DBG_IOBUF)
1887                 log_debug ("iobuf-%d.%d: pop in underflow (nothing buffered, got EOF)\n",
1888                            a->no, a->subno);
1889               xfree (a->d.buf);
1890               xfree (a->real_fname);
1891               memcpy (a, b, sizeof *a);
1892               xfree (b);
1893
1894               print_chain (a);
1895
1896               return -1;
1897             }
1898           else if (a->d.len == 0)
1899             /* We can't unlink this filter (it is the only one in the
1900                pipeline), but we can immediately return EOF.  */
1901             return -1;
1902         }
1903       else if (rc)
1904         /* Record the error.  */
1905         {
1906           a->error = rc;
1907
1908           if (a->d.len == 0)
1909             /* There is no buffered data.  Immediately return EOF.  */
1910             return -1;
1911         }
1912     }
1913
1914   assert (a->d.start <= a->d.len);
1915   if (a->d.start < a->d.len)
1916     return a->d.buf[a->d.start++];
1917
1918   /* EOF.  */
1919   return -1;
1920 }
1921
1922
1923 static int
1924 filter_flush (iobuf_t a)
1925 {
1926   size_t len;
1927   int rc;
1928
1929   if (a->use == IOBUF_OUTPUT_TEMP)
1930     {                           /* increase the temp buffer */
1931       size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
1932
1933       if (DBG_IOBUF)
1934         log_debug ("increasing temp iobuf from %lu to %lu\n",
1935                    (ulong) a->d.size, (ulong) newsize);
1936
1937       a->d.buf = xrealloc (a->d.buf, newsize);
1938       a->d.size = newsize;
1939       return 0;
1940     }
1941   else if (a->use != IOBUF_OUTPUT)
1942     log_bug ("flush on non-output iobuf\n");
1943   else if (!a->filter)
1944     log_bug ("filter_flush: no filter\n");
1945   len = a->d.len;
1946   rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
1947   if (!rc && len != a->d.len)
1948     {
1949       log_info ("filter_flush did not write all!\n");
1950       rc = GPG_ERR_INTERNAL;
1951     }
1952   else if (rc)
1953     a->error = rc;
1954   a->d.len = 0;
1955
1956   return rc;
1957 }
1958
1959
1960 int
1961 iobuf_readbyte (iobuf_t a)
1962 {
1963   int c;
1964
1965   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
1966     {
1967       log_bug ("iobuf_readbyte called on a non-INPUT pipeline!\n");
1968       return -1;
1969     }
1970
1971   assert (a->d.start <= a->d.len);
1972
1973   if (a->nlimit && a->nbytes >= a->nlimit)
1974     return -1;                  /* forced EOF */
1975
1976   if (a->d.start < a->d.len)
1977     {
1978       c = a->d.buf[a->d.start++];
1979     }
1980   else if ((c = underflow (a, 1)) == -1)
1981     return -1;                  /* EOF */
1982
1983   assert (a->d.start <= a->d.len);
1984
1985   /* Note: if underflow doesn't return EOF, then it returns the first
1986      byte that was read and advances a->d.start appropriately.  */
1987
1988   a->nbytes++;
1989   return c;
1990 }
1991
1992
1993 int
1994 iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
1995 {
1996   unsigned char *buf = (unsigned char *)buffer;
1997   int c, n;
1998
1999   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
2000     {
2001       log_bug ("iobuf_read called on a non-INPUT pipeline!\n");
2002       return -1;
2003     }
2004
2005   if (a->nlimit)
2006     {
2007       /* Handle special cases. */
2008       for (n = 0; n < buflen; n++)
2009         {
2010           if ((c = iobuf_readbyte (a)) == -1)
2011             {
2012               if (!n)
2013                 return -1;      /* eof */
2014               break;
2015             }
2016
2017           if (buf)
2018             {
2019               *buf = c;
2020               buf++;
2021             }
2022         }
2023       return n;
2024     }
2025
2026   n = 0;
2027   do
2028     {
2029       if (n < buflen && a->d.start < a->d.len)
2030         /* Drain the buffer.  */
2031         {
2032           unsigned size = a->d.len - a->d.start;
2033           if (size > buflen - n)
2034             size = buflen - n;
2035           if (buf)
2036             memcpy (buf, a->d.buf + a->d.start, size);
2037           n += size;
2038           a->d.start += size;
2039           if (buf)
2040             buf += size;
2041         }
2042       if (n < buflen)
2043         /* Draining the internal buffer didn't fill BUFFER.  Call
2044            underflow to read more data into the filter's internal
2045            buffer.  */
2046         {
2047           if ((c = underflow (a, 1)) == -1)
2048             /* EOF.  If we managed to read something, don't return EOF
2049                now.  */
2050             {
2051               a->nbytes += n;
2052               return n ? n : -1 /*EOF*/;
2053             }
2054           if (buf)
2055             *buf++ = c;
2056           n++;
2057         }
2058     }
2059   while (n < buflen);
2060   a->nbytes += n;
2061   return n;
2062 }
2063
2064
2065
2066 int
2067 iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
2068 {
2069   int n = 0;
2070
2071   assert (buflen > 0);
2072   assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
2073
2074   if (buflen > a->d.size)
2075     /* We can't peek more than we can buffer.  */
2076     buflen = a->d.size;
2077
2078   /* Try to fill the internal buffer with enough data to satisfy the
2079      request.  */
2080   while (buflen > a->d.len - a->d.start)
2081     {
2082       if (underflow (a, 0) == -1)
2083         /* EOF.  We can't read any more.  */
2084         break;
2085
2086       /* Underflow consumes the first character (it's the return
2087          value).  unget() it by resetting the "file position".  */
2088       assert (a->d.start == 1);
2089       a->d.start = 0;
2090     }
2091
2092   n = a->d.len - a->d.start;
2093   if (n > buflen)
2094     n = buflen;
2095
2096   if (n == 0)
2097     /* EOF.  */
2098     return -1;
2099
2100   memcpy (buf, &a->d.buf[a->d.start], n);
2101
2102   return n;
2103 }
2104
2105
2106
2107
2108 int
2109 iobuf_writebyte (iobuf_t a, unsigned int c)
2110 {
2111   int rc;
2112
2113   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2114     {
2115       log_bug ("iobuf_writebyte called on an input pipeline!\n");
2116       return -1;
2117     }
2118
2119   if (a->d.len == a->d.size)
2120     if ((rc=filter_flush (a)))
2121       return rc;
2122
2123   assert (a->d.len < a->d.size);
2124   a->d.buf[a->d.len++] = c;
2125   return 0;
2126 }
2127
2128
2129 int
2130 iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
2131 {
2132   const unsigned char *buf = (const unsigned char *)buffer;
2133   int rc;
2134
2135   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2136     {
2137       log_bug ("iobuf_write called on an input pipeline!\n");
2138       return -1;
2139     }
2140
2141   do
2142     {
2143       if (buflen && a->d.len < a->d.size)
2144         {
2145           unsigned size = a->d.size - a->d.len;
2146           if (size > buflen)
2147             size = buflen;
2148           memcpy (a->d.buf + a->d.len, buf, size);
2149           buflen -= size;
2150           buf += size;
2151           a->d.len += size;
2152         }
2153       if (buflen)
2154         {
2155           rc = filter_flush (a);
2156           if (rc)
2157             return rc;
2158         }
2159     }
2160   while (buflen);
2161   return 0;
2162 }
2163
2164
2165 int
2166 iobuf_writestr (iobuf_t a, const char *buf)
2167 {
2168   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2169     {
2170       log_bug ("iobuf_writestr called on an input pipeline!\n");
2171       return -1;
2172     }
2173
2174   return iobuf_write (a, buf, strlen (buf));
2175 }
2176
2177
2178
2179 int
2180 iobuf_write_temp (iobuf_t dest, iobuf_t source)
2181 {
2182   assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2183   assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
2184
2185   iobuf_flush_temp (source);
2186   return iobuf_write (dest, source->d.buf, source->d.len);
2187 }
2188
2189 size_t
2190 iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
2191 {
2192   size_t n;
2193
2194   while (1)
2195     {
2196       int rc = filter_flush (a);
2197       if (rc)
2198         log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed.  Ignoring.\n",
2199                  a->no, a->subno, iobuf_desc (a));
2200       if (! a->chain)
2201         break;
2202       a = a->chain;
2203     }
2204
2205   n = a->d.len;
2206   if (n > buflen)
2207     n = buflen;
2208   memcpy (buffer, a->d.buf, n);
2209   return n;
2210 }
2211
2212 /* Copies the data from the input iobuf SOURCE to the output iobuf
2213    DEST until either an error is encountered or EOF is reached.
2214    Returns the number of bytes copies.  */
2215 size_t
2216 iobuf_copy (iobuf_t dest, iobuf_t source)
2217 {
2218   char *temp;
2219   /* Use a 1 MB buffer.  */
2220   const size_t temp_size = 1024 * 1024;
2221
2222   size_t nread;
2223   size_t nwrote = 0;
2224   int err;
2225
2226   assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP);
2227   assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2228
2229   temp = xmalloc (temp_size);
2230   while (1)
2231     {
2232       nread = iobuf_read (source, temp, temp_size);
2233       if (nread == -1)
2234         /* EOF.  */
2235         break;
2236
2237       err = iobuf_write (dest, temp, nread);
2238       if (err)
2239         break;
2240       nwrote += nread;
2241     }
2242   xfree (temp);
2243
2244   return nwrote;
2245 }
2246
2247
2248 void
2249 iobuf_flush_temp (iobuf_t temp)
2250 {
2251   if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP)
2252     log_bug ("iobuf_writestr called on an input pipeline!\n");
2253   while (temp->chain)
2254     pop_filter (temp, temp->filter, NULL);
2255 }
2256
2257
2258 void
2259 iobuf_set_limit (iobuf_t a, off_t nlimit)
2260 {
2261   if (nlimit)
2262     a->nofast = 1;
2263   else
2264     a->nofast = 0;
2265   a->nlimit = nlimit;
2266   a->ntotal += a->nbytes;
2267   a->nbytes = 0;
2268 }
2269
2270
2271
2272 off_t
2273 iobuf_get_filelength (iobuf_t a, int *overflow)
2274 {
2275   if (overflow)
2276     *overflow = 0;
2277
2278   /* Hmmm: file_filter may have already been removed */
2279   for ( ; a->chain; a = a->chain )
2280     ;
2281
2282   if (a->filter != file_filter)
2283     return 0;
2284
2285   {
2286     file_filter_ctx_t *b = a->filter_ov;
2287     gnupg_fd_t fp = b->fp;
2288
2289 #if defined(HAVE_W32_SYSTEM)
2290     ulong size;
2291     static int (* __stdcall get_file_size_ex) (void *handle,
2292                                                LARGE_INTEGER *r_size);
2293     static int get_file_size_ex_initialized;
2294
2295     if (!get_file_size_ex_initialized)
2296       {
2297         void *handle;
2298
2299         handle = dlopen ("kernel32.dll", RTLD_LAZY);
2300         if (handle)
2301           {
2302             get_file_size_ex = dlsym (handle, "GetFileSizeEx");
2303             if (!get_file_size_ex)
2304               dlclose (handle);
2305           }
2306         get_file_size_ex_initialized = 1;
2307       }
2308
2309     if (get_file_size_ex)
2310       {
2311         /* This is a newer system with GetFileSizeEx; we use this
2312            then because it seem that GetFileSize won't return a
2313            proper error in case a file is larger than 4GB. */
2314         LARGE_INTEGER exsize;
2315
2316         if (get_file_size_ex (fp, &exsize))
2317           {
2318             if (!exsize.u.HighPart)
2319               return exsize.u.LowPart;
2320             if (overflow)
2321               *overflow = 1;
2322             return 0;
2323           }
2324       }
2325     else
2326       {
2327         if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
2328           return size;
2329       }
2330     log_error ("GetFileSize for handle %p failed: %s\n",
2331                fp, w32_strerror (0));
2332 #else /*!HAVE_W32_SYSTEM*/
2333     {
2334       struct stat st;
2335
2336       if ( !fstat (FD2INT (fp), &st) )
2337         return st.st_size;
2338       log_error("fstat() failed: %s\n", strerror(errno) );
2339     }
2340 #endif /*!HAVE_W32_SYSTEM*/
2341   }
2342
2343   return 0;
2344 }
2345
2346
2347 int
2348 iobuf_get_fd (iobuf_t a)
2349 {
2350   for (; a->chain; a = a->chain)
2351     ;
2352
2353   if (a->filter != file_filter)
2354     return -1;
2355
2356   {
2357     file_filter_ctx_t *b = a->filter_ov;
2358     gnupg_fd_t fp = b->fp;
2359
2360     return FD2INT (fp);
2361   }
2362 }
2363
2364
2365 off_t
2366 iobuf_tell (iobuf_t a)
2367 {
2368   return a->ntotal + a->nbytes;
2369 }
2370
2371
2372 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2373
2374 #ifdef HAVE_LIMITS_H
2375 # include <limits.h>
2376 #endif
2377 #ifndef LONG_MAX
2378 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2379 #endif
2380 #ifndef LONG_MIN
2381 # define LONG_MIN (-1 - LONG_MAX)
2382 #endif
2383
2384 /****************
2385  * A substitute for fseeko, for hosts that don't have it.
2386  */
2387 static int
2388 fseeko (FILE * stream, off_t newpos, int whence)
2389 {
2390   while (newpos != (long) newpos)
2391     {
2392       long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2393       if (fseek (stream, pos, whence) != 0)
2394         return -1;
2395       newpos -= pos;
2396       whence = SEEK_CUR;
2397     }
2398   return fseek (stream, (long) newpos, whence);
2399 }
2400 #endif
2401
2402 int
2403 iobuf_seek (iobuf_t a, off_t newpos)
2404 {
2405   file_filter_ctx_t *b = NULL;
2406
2407   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_INPUT)
2408     {
2409       /* Find the last filter in the pipeline.  */
2410       for (; a->chain; a = a->chain)
2411         ;
2412
2413       if (a->filter != file_filter)
2414         return -1;
2415
2416       b = a->filter_ov;
2417
2418 #ifdef HAVE_W32_SYSTEM
2419       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2420         {
2421           log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2422                      b->fp, (int) GetLastError ());
2423           return -1;
2424         }
2425 #else
2426       if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2427         {
2428           log_error ("can't lseek: %s\n", strerror (errno));
2429           return -1;
2430         }
2431 #endif
2432       /* Discard the buffer it is not a temp stream.  */
2433       a->d.len = 0;
2434     }
2435   a->d.start = 0;
2436   a->nbytes = 0;
2437   a->nlimit = 0;
2438   a->nofast = 0;
2439   a->ntotal = newpos;
2440   a->error = 0;
2441
2442   /* It is impossible for A->CHAIN to be non-NULL.  If A is an INPUT
2443      or OUTPUT buffer, then we find the last filter, which is defined
2444      as A->CHAIN being NULL.  If A is a TEMP filter, then A must be
2445      the only filter in the pipe: when iobuf_push_filter adds a filter
2446      to the front of a pipeline, it sets the new filter to be an
2447      OUTPUT filter if the pipeline is an OUTPUT or TEMP pipeline and
2448      to be an INPUT filter if the pipeline is an INPUT pipeline.
2449      Thus, only the last filter in a TEMP pipeline can be a */
2450
2451   /* remove filters, but the last */
2452   if (a->chain)
2453     log_debug ("pop_filter called in iobuf_seek - please report\n");
2454   while (a->chain)
2455     pop_filter (a, a->filter, NULL);
2456
2457   return 0;
2458 }
2459
2460
2461 const char *
2462 iobuf_get_real_fname (iobuf_t a)
2463 {
2464   if (a->real_fname)
2465     return a->real_fname;
2466
2467   /* the old solution */
2468   for (; a; a = a->chain)
2469     if (!a->chain && a->filter == file_filter)
2470       {
2471         file_filter_ctx_t *b = a->filter_ov;
2472         return b->print_only_name ? NULL : b->fname;
2473       }
2474
2475   return NULL;
2476 }
2477
2478 const char *
2479 iobuf_get_fname (iobuf_t a)
2480 {
2481   for (; a; a = a->chain)
2482     if (!a->chain && a->filter == file_filter)
2483       {
2484         file_filter_ctx_t *b = a->filter_ov;
2485         return b->fname;
2486       }
2487   return NULL;
2488 }
2489
2490 const char *
2491 iobuf_get_fname_nonnull (iobuf_t a)
2492 {
2493   const char *fname;
2494
2495   fname = iobuf_get_fname (a);
2496   return fname? fname : "[?]";
2497 }
2498
2499
2500 /****************
2501  * enable partial block mode as described in the OpenPGP draft.
2502  * LEN is the first length byte on read, but ignored on writes.
2503  */
2504 void
2505 iobuf_set_partial_block_mode (iobuf_t a, size_t len)
2506 {
2507   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2508
2509   ctx->use = a->use;
2510   if (!len)
2511     {
2512       if (a->use == IOBUF_INPUT)
2513         log_debug ("pop_filter called in set_partial_block_mode"
2514                    " - please report\n");
2515       /* XXX: This pop_filter doesn't make sense.  Since we haven't
2516          actually added the filter to the pipeline yet, why are we
2517          popping anything?  Moreover, since we don't report an error,
2518          the caller won't directly see an error.  I think that it
2519          would be better to push the filter and set a->error to
2520          GPG_ERR_BAD_DATA, but Werner thinks it's impossible for len
2521          to be 0 (but he doesn't want to remove the check just in
2522          case).  */
2523       pop_filter (a, block_filter, NULL);
2524     }
2525   else
2526     {
2527       ctx->partial = 1;
2528       ctx->size = 0;
2529       ctx->first_c = len;
2530       iobuf_push_filter (a, block_filter, ctx);
2531     }
2532 }
2533
2534
2535
2536 unsigned int
2537 iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2538                  unsigned *length_of_buffer, unsigned *max_length)
2539 {
2540   int c;
2541   char *buffer = (char *)*addr_of_buffer;
2542   unsigned length = *length_of_buffer;
2543   unsigned nbytes = 0;
2544   unsigned maxlen = *max_length;
2545   char *p;
2546
2547   /* The code assumes that we have space for at least a newline and a
2548      NUL character in the buffer.  This requires at least 2 bytes.  We
2549      don't complicate the code by handling the stupid corner case, but
2550      simply assert that it can't happen.  */
2551   assert (length >= 2 || maxlen >= 2);
2552
2553   if (!buffer || length <= 1)
2554     /* must allocate a new buffer */
2555     {
2556       length = 256 <= maxlen ? 256 : maxlen;
2557       buffer = xrealloc (buffer, length);
2558       *addr_of_buffer = (unsigned char *)buffer;
2559       *length_of_buffer = length;
2560     }
2561
2562   p = buffer;
2563   while ((c = iobuf_get (a)) != -1)
2564     {
2565       *p++ = c;
2566       nbytes++;
2567       if (c == '\n')
2568         break;
2569
2570       if (nbytes == length - 1)
2571         /* We don't have enough space to add a \n and a \0.  Increase
2572            the buffer size.  */
2573         {
2574           if (length == maxlen)
2575             /* We reached the buffer's size limit!  */
2576             {
2577               /* Skip the rest of the line.  */
2578               while (c != '\n' && (c = iobuf_get (a)) != -1)
2579                 ;
2580
2581               /* p is pointing at the last byte in the buffer.  We
2582                  always terminate the line with "\n\0" so overwrite
2583                  the previous byte with a \n.  */
2584               assert (p > buffer);
2585               p[-1] = '\n';
2586
2587               /* Indicate truncation.  */
2588               *max_length = 0;
2589               break;
2590             }
2591
2592           length += length < 1024 ? 256 : 1024;
2593           if (length > maxlen)
2594             length = maxlen;
2595
2596           buffer = xrealloc (buffer, length);
2597           *addr_of_buffer = (unsigned char *)buffer;
2598           *length_of_buffer = length;
2599           p = buffer + nbytes;
2600         }
2601     }
2602   /* Add the terminating NUL.  */
2603   *p = 0;
2604
2605   /* Return the number of characters written to the buffer including
2606      the newline, but not including the terminating NUL.  */
2607   return nbytes;
2608 }
2609
2610 static int
2611 translate_file_handle (int fd, int for_write)
2612 {
2613 #if defined(HAVE_W32CE_SYSTEM)
2614   /* This is called only with one of the special filenames.  Under
2615      W32CE the FD here is not a file descriptor but a rendezvous id,
2616      thus we need to finish the pipe first.  */
2617   fd = _assuan_w32ce_finish_pipe (fd, for_write);
2618 #elif defined(HAVE_W32_SYSTEM)
2619   {
2620     int x;
2621
2622     (void)for_write;
2623
2624     if (fd == 0)
2625       x = (int) GetStdHandle (STD_INPUT_HANDLE);
2626     else if (fd == 1)
2627       x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2628     else if (fd == 2)
2629       x = (int) GetStdHandle (STD_ERROR_HANDLE);
2630     else
2631       x = fd;
2632
2633     if (x == -1)
2634       log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2635                  fd, (int) GetLastError ());
2636
2637     fd = x;
2638   }
2639 #else
2640   (void)for_write;
2641 #endif
2642   return fd;
2643 }
2644
2645
2646 void
2647 iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2648 {
2649   if ( partial )
2650     {
2651       for (;;)
2652         {
2653           if (a->nofast || a->d.start >= a->d.len)
2654             {
2655               if (iobuf_readbyte (a) == -1)
2656                 {
2657                   break;
2658                 }
2659             }
2660           else
2661             {
2662               unsigned long count = a->d.len - a->d.start;
2663               a->nbytes += count;
2664               a->d.start = a->d.len;
2665             }
2666         }
2667     }
2668   else
2669     {
2670       unsigned long remaining = n;
2671       while (remaining > 0)
2672         {
2673           if (a->nofast || a->d.start >= a->d.len)
2674             {
2675               if (iobuf_readbyte (a) == -1)
2676                 {
2677                   break;
2678                 }
2679               --remaining;
2680             }
2681           else
2682             {
2683               unsigned long count = a->d.len - a->d.start;
2684               if (count > remaining)
2685                 {
2686                   count = remaining;
2687                 }
2688               a->nbytes += count;
2689               a->d.start += count;
2690               remaining -= count;
2691             }
2692         }
2693     }
2694 }