Imported Upstream version 2.1.12
[platform/upstream/gpg2.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       mem2str (buf, "file_filter(fd)", *ret_len);
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       xfree (a); /* We can free our context now. */
593     }
594
595   return rc;
596 }
597
598
599 /* Similar to file_filter but using the estream system.  */
600 static int
601 file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
602                 size_t * ret_len)
603 {
604   file_es_filter_ctx_t *a = opaque;
605   estream_t f = a->fp;
606   size_t size = *ret_len;
607   size_t nbytes = 0;
608   int rc = 0;
609
610   (void)chain; /* Not used.  */
611
612   if (control == IOBUFCTRL_UNDERFLOW)
613     {
614       assert (size); /* We need a buffer.  */
615       if (a->eof_seen)
616         {
617           rc = -1;
618           *ret_len = 0;
619         }
620       else
621         {
622           nbytes = 0;
623           rc = es_read (f, buf, size, &nbytes);
624           if (rc == -1)
625             {                   /* error */
626               rc = gpg_error_from_syserror ();
627               log_error ("%s: read error: %s\n", a->fname, strerror (errno));
628             }
629           else if (!nbytes)
630             {                   /* eof */
631               a->eof_seen = 1;
632               rc = -1;
633             }
634           *ret_len = nbytes;
635         }
636     }
637   else if (control == IOBUFCTRL_FLUSH)
638     {
639       if (size)
640         {
641           byte *p = buf;
642           size_t nwritten;
643
644           nbytes = size;
645           do
646             {
647               nwritten = 0;
648               if (es_write (f, p, nbytes, &nwritten))
649                 {
650                   rc = gpg_error_from_syserror ();
651                   log_error ("%s: write error: %s\n",
652                              a->fname, strerror (errno));
653                   break;
654                 }
655               p += nwritten;
656               nbytes -= nwritten;
657             }
658           while (nbytes);
659           nbytes = p - buf;
660         }
661       *ret_len = nbytes;
662     }
663   else if (control == IOBUFCTRL_INIT)
664     {
665       a->eof_seen = 0;
666       a->no_cache = 0;
667     }
668   else if (control == IOBUFCTRL_DESC)
669     {
670       mem2str (buf, "estream_filter", *ret_len);
671     }
672   else if (control == IOBUFCTRL_FREE)
673     {
674       if (f != es_stdin && f != es_stdout)
675         {
676           if (DBG_IOBUF)
677             log_debug ("%s: es_fclose %p\n", a->fname, f);
678           if (!a->keep_open)
679             es_fclose (f);
680         }
681       f = NULL;
682       xfree (a); /* We can free our context now. */
683     }
684
685   return rc;
686 }
687
688
689 #ifdef HAVE_W32_SYSTEM
690 /* Because network sockets are special objects under Lose32 we have to
691    use a dedicated filter for them. */
692 static int
693 sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
694              size_t * ret_len)
695 {
696   sock_filter_ctx_t *a = opaque;
697   size_t size = *ret_len;
698   size_t nbytes = 0;
699   int rc = 0;
700
701   (void)chain;
702
703   if (control == IOBUFCTRL_UNDERFLOW)
704     {
705       assert (size);            /* need a buffer */
706       if (a->eof_seen)
707         {
708           rc = -1;
709           *ret_len = 0;
710         }
711       else
712         {
713           int nread;
714
715           nread = recv (a->sock, buf, size, 0);
716           if (nread == SOCKET_ERROR)
717             {
718               int ec = (int) WSAGetLastError ();
719               rc = gpg_error_from_errno (ec);
720               log_error ("socket read error: ec=%d\n", ec);
721             }
722           else if (!nread)
723             {
724               a->eof_seen = 1;
725               rc = -1;
726             }
727           else
728             {
729               nbytes = nread;
730             }
731           *ret_len = nbytes;
732         }
733     }
734   else if (control == IOBUFCTRL_FLUSH)
735     {
736       if (size)
737         {
738           byte *p = buf;
739           int n;
740
741           nbytes = size;
742           do
743             {
744               n = send (a->sock, p, nbytes, 0);
745               if (n == SOCKET_ERROR)
746                 {
747                   int ec = (int) WSAGetLastError ();
748                   rc = gpg_error_from_errno (ec);
749                   log_error ("socket write error: ec=%d\n", ec);
750                   break;
751                 }
752               p += n;
753               nbytes -= n;
754             }
755           while (nbytes);
756           nbytes = p - buf;
757         }
758       *ret_len = nbytes;
759     }
760   else if (control == IOBUFCTRL_INIT)
761     {
762       a->eof_seen = 0;
763       a->keep_open = 0;
764       a->no_cache = 0;
765     }
766   else if (control == IOBUFCTRL_DESC)
767     {
768       mem2str (buf, "sock_filter", *ret_len);
769     }
770   else if (control == IOBUFCTRL_FREE)
771     {
772       if (!a->keep_open)
773         closesocket (a->sock);
774       xfree (a);                /* we can free our context now */
775     }
776   return rc;
777 }
778 #endif /*HAVE_W32_SYSTEM*/
779
780 /****************
781  * This is used to implement the block write mode.
782  * Block reading is done on a byte by byte basis in readbyte(),
783  * without a filter
784  */
785 static int
786 block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
787               size_t * ret_len)
788 {
789   block_filter_ctx_t *a = opaque;
790   char *buf = (char *)buffer;
791   size_t size = *ret_len;
792   int c, needed, rc = 0;
793   char *p;
794
795   if (control == IOBUFCTRL_UNDERFLOW)
796     {
797       size_t n = 0;
798
799       p = buf;
800       assert (size);            /* need a buffer */
801       if (a->eof)               /* don't read any further */
802         rc = -1;
803       while (!rc && size)
804         {
805           if (!a->size)
806             {                   /* get the length bytes */
807               if (a->partial == 2)
808                 {
809                   a->eof = 1;
810                   if (!n)
811                     rc = -1;
812                   break;
813                 }
814               else if (a->partial)
815                 {
816                   /* These OpenPGP introduced huffman like encoded length
817                    * bytes are really a mess :-( */
818                   if (a->first_c)
819                     {
820                       c = a->first_c;
821                       a->first_c = 0;
822                     }
823                   else if ((c = iobuf_get (chain)) == -1)
824                     {
825                       log_error ("block_filter: 1st length byte missing\n");
826                       rc = GPG_ERR_BAD_DATA;
827                       break;
828                     }
829                   if (c < 192)
830                     {
831                       a->size = c;
832                       a->partial = 2;
833                       if (!a->size)
834                         {
835                           a->eof = 1;
836                           if (!n)
837                             rc = -1;
838                           break;
839                         }
840                     }
841                   else if (c < 224)
842                     {
843                       a->size = (c - 192) * 256;
844                       if ((c = iobuf_get (chain)) == -1)
845                         {
846                           log_error
847                             ("block_filter: 2nd length byte missing\n");
848                           rc = GPG_ERR_BAD_DATA;
849                           break;
850                         }
851                       a->size += c + 192;
852                       a->partial = 2;
853                       if (!a->size)
854                         {
855                           a->eof = 1;
856                           if (!n)
857                             rc = -1;
858                           break;
859                         }
860                     }
861                   else if (c == 255)
862                     {
863                       a->size = (size_t)iobuf_get (chain) << 24;
864                       a->size |= iobuf_get (chain) << 16;
865                       a->size |= iobuf_get (chain) << 8;
866                       if ((c = iobuf_get (chain)) == -1)
867                         {
868                           log_error ("block_filter: invalid 4 byte length\n");
869                           rc = GPG_ERR_BAD_DATA;
870                           break;
871                         }
872                       a->size |= c;
873                       a->partial = 2;
874                       if (!a->size)
875                         {
876                           a->eof = 1;
877                           if (!n)
878                             rc = -1;
879                           break;
880                         }
881                     }
882                   else
883                     { /* Next partial body length. */
884                       a->size = 1 << (c & 0x1f);
885                     }
886                   /*  log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
887                 }
888               else
889                 BUG ();
890             }
891
892           while (!rc && size && a->size)
893             {
894               needed = size < a->size ? size : a->size;
895               c = iobuf_read (chain, p, needed);
896               if (c < needed)
897                 {
898                   if (c == -1)
899                     c = 0;
900                   log_error
901                     ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
902                      a, (ulong) size + c, (ulong) a->size + c);
903                   rc = GPG_ERR_BAD_DATA;
904                 }
905               else
906                 {
907                   size -= c;
908                   a->size -= c;
909                   p += c;
910                   n += c;
911                 }
912             }
913         }
914       *ret_len = n;
915     }
916   else if (control == IOBUFCTRL_FLUSH)
917     {
918       if (a->partial)
919         {                       /* the complicated openpgp scheme */
920           size_t blen, n, nbytes = size + a->buflen;
921
922           assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
923           if (nbytes < OP_MIN_PARTIAL_CHUNK)
924             {
925               /* not enough to write a partial block out; so we store it */
926               if (!a->buffer)
927                 a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
928               memcpy (a->buffer + a->buflen, buf, size);
929               a->buflen += size;
930             }
931           else
932             {                   /* okay, we can write out something */
933               /* do this in a loop to use the most efficient block lengths */
934               p = buf;
935               do
936                 {
937                   /* find the best matching block length - this is limited
938                    * by the size of the internal buffering */
939                   for (blen = OP_MIN_PARTIAL_CHUNK * 2,
940                        c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
941                        blen *= 2, c++)
942                     ;
943                   blen /= 2;
944                   c--;
945                   /* write the partial length header */
946                   assert (c <= 0x1f);   /*;-) */
947                   c |= 0xe0;
948                   iobuf_put (chain, c);
949                   if ((n = a->buflen))
950                     {           /* write stuff from the buffer */
951                       assert (n == OP_MIN_PARTIAL_CHUNK);
952                       if (iobuf_write (chain, a->buffer, n))
953                         rc = gpg_error_from_syserror ();
954                       a->buflen = 0;
955                       nbytes -= n;
956                     }
957                   if ((n = nbytes) > blen)
958                     n = blen;
959                   if (n && iobuf_write (chain, p, n))
960                     rc = gpg_error_from_syserror ();
961                   p += n;
962                   nbytes -= n;
963                 }
964               while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
965               /* store the rest in the buffer */
966               if (!rc && nbytes)
967                 {
968                   assert (!a->buflen);
969                   assert (nbytes < OP_MIN_PARTIAL_CHUNK);
970                   if (!a->buffer)
971                     a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
972                   memcpy (a->buffer, p, nbytes);
973                   a->buflen = nbytes;
974                 }
975             }
976         }
977       else
978         BUG ();
979     }
980   else if (control == IOBUFCTRL_INIT)
981     {
982       if (DBG_IOBUF)
983         log_debug ("init block_filter %p\n", a);
984       if (a->partial)
985         a->count = 0;
986       else if (a->use == IOBUF_INPUT)
987         a->count = a->size = 0;
988       else
989         a->count = a->size;     /* force first length bytes */
990       a->eof = 0;
991       a->buffer = NULL;
992       a->buflen = 0;
993     }
994   else if (control == IOBUFCTRL_DESC)
995     {
996       mem2str (buf, "block_filter", *ret_len);
997     }
998   else if (control == IOBUFCTRL_FREE)
999     {
1000       if (a->use == IOBUF_OUTPUT)
1001         {                       /* write the end markers */
1002           if (a->partial)
1003             {
1004               u32 len;
1005               /* write out the remaining bytes without a partial header
1006                * the length of this header may be 0 - but if it is
1007                * the first block we are not allowed to use a partial header
1008                * and frankly we can't do so, because this length must be
1009                * a power of 2. This is _really_ complicated because we
1010                * have to check the possible length of a packet prior
1011                * to it's creation: a chain of filters becomes complicated
1012                * and we need a lot of code to handle compressed packets etc.
1013                *   :-(((((((
1014                */
1015               /* construct header */
1016               len = a->buflen;
1017               /*log_debug("partial: remaining length=%u\n", len ); */
1018               if (len < 192)
1019                 rc = iobuf_put (chain, len);
1020               else if (len < 8384)
1021                 {
1022                   if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
1023                     rc = iobuf_put (chain, ((len - 192) % 256));
1024                 }
1025               else
1026                 {               /* use a 4 byte header */
1027                   if (!(rc = iobuf_put (chain, 0xff)))
1028                     if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
1029                       if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
1030                         if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
1031                           rc = iobuf_put (chain, len & 0xff);
1032                 }
1033               if (!rc && len)
1034                 rc = iobuf_write (chain, a->buffer, len);
1035               if (rc)
1036                 {
1037                   log_error ("block_filter: write error: %s\n",
1038                              strerror (errno));
1039                   rc = gpg_error_from_syserror ();
1040                 }
1041               xfree (a->buffer);
1042               a->buffer = NULL;
1043               a->buflen = 0;
1044             }
1045           else
1046             BUG ();
1047         }
1048       else if (a->size)
1049         {
1050           log_error ("block_filter: pending bytes!\n");
1051         }
1052       if (DBG_IOBUF)
1053         log_debug ("free block_filter %p\n", a);
1054       xfree (a);                /* we can free our context now */
1055     }
1056
1057   return rc;
1058 }
1059
1060 #define MAX_IOBUF_DESC 32
1061 /*
1062  * Fill the buffer by the description of iobuf A.
1063  * The buffer size should be MAX_IOBUF_DESC (or larger).
1064  * Returns BUF as (const char *).
1065  */
1066 static const char *
1067 iobuf_desc (iobuf_t a, byte *buf)
1068 {
1069   size_t len = MAX_IOBUF_DESC;
1070
1071   if (! a || ! a->filter)
1072     memcpy (buf, "?", 2);
1073   else
1074     a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, buf, &len);
1075
1076   return buf;
1077 }
1078
1079 static void
1080 print_chain (iobuf_t a)
1081 {
1082   if (!DBG_IOBUF)
1083     return;
1084   for (; a; a = a->chain)
1085     {
1086       byte desc[MAX_IOBUF_DESC];
1087
1088       log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
1089                  a->no, a->subno, iobuf_desc (a, desc), a->filter_eof,
1090                  (int) a->d.start, (int) a->d.len);
1091     }
1092 }
1093
1094 int
1095 iobuf_print_chain (iobuf_t a)
1096 {
1097   print_chain (a);
1098   return 0;
1099 }
1100
1101 iobuf_t
1102 iobuf_alloc (int use, size_t bufsize)
1103 {
1104   iobuf_t a;
1105   static int number = 0;
1106
1107   assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
1108           || use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
1109   if (bufsize == 0)
1110     {
1111       log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
1112       bufsize = IOBUF_BUFFER_SIZE;
1113     }
1114
1115   a = xcalloc (1, sizeof *a);
1116   a->use = use;
1117   a->d.buf = xmalloc (bufsize);
1118   a->d.size = bufsize;
1119   a->no = ++number;
1120   a->subno = 0;
1121   a->real_fname = NULL;
1122   return a;
1123 }
1124
1125 int
1126 iobuf_close (iobuf_t a)
1127 {
1128   iobuf_t a_chain;
1129   size_t dummy_len = 0;
1130   int rc = 0;
1131
1132   for (; a; a = a_chain)
1133     {
1134       byte desc[MAX_IOBUF_DESC];
1135       int rc2 = 0;
1136
1137       a_chain = a->chain;
1138
1139       if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1140         log_error ("filter_flush failed on close: %s\n", gpg_strerror (rc));
1141
1142       if (DBG_IOBUF)
1143         log_debug ("iobuf-%d.%d: close '%s'\n",
1144                    a->no, a->subno, iobuf_desc (a, desc));
1145
1146       if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1147                                          a->chain, NULL, &dummy_len)))
1148         log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1149       if (! rc && rc2)
1150         /* Whoops!  An error occurred.  Save it in RC if we haven't
1151            already recorded an error.  */
1152         rc = rc2;
1153
1154       xfree (a->real_fname);
1155       if (a->d.buf)
1156         {
1157           memset (a->d.buf, 0, a->d.size);      /* erase the buffer */
1158           xfree (a->d.buf);
1159         }
1160       xfree (a);
1161     }
1162   return rc;
1163 }
1164
1165 int
1166 iobuf_cancel (iobuf_t a)
1167 {
1168   const char *s;
1169   iobuf_t a2;
1170   int rc;
1171 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1172   char *remove_name = NULL;
1173 #endif
1174
1175   if (a && a->use == IOBUF_OUTPUT)
1176     {
1177       s = iobuf_get_real_fname (a);
1178       if (s && *s)
1179         {
1180 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1181           remove_name = xstrdup (s);
1182 #else
1183           remove (s);
1184 #endif
1185         }
1186     }
1187
1188   /* send a cancel message to all filters */
1189   for (a2 = a; a2; a2 = a2->chain)
1190     {
1191       size_t dummy;
1192       if (a2->filter)
1193         a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1194     }
1195
1196   rc = iobuf_close (a);
1197 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1198   if (remove_name)
1199     {
1200       /* Argg, MSDOS does not allow to remove open files.  So
1201        * we have to do it here */
1202 #ifdef HAVE_W32CE_SYSTEM
1203       wchar_t *wtmp = utf8_to_wchar (remove_name);
1204       if (wtmp)
1205         DeleteFile (wtmp);
1206       xfree (wtmp);
1207 #else
1208       remove (remove_name);
1209 #endif
1210       xfree (remove_name);
1211     }
1212 #endif
1213   return rc;
1214 }
1215
1216
1217 iobuf_t
1218 iobuf_temp (void)
1219 {
1220   return iobuf_alloc (IOBUF_OUTPUT_TEMP, IOBUF_BUFFER_SIZE);
1221 }
1222
1223 iobuf_t
1224 iobuf_temp_with_content (const char *buffer, size_t length)
1225 {
1226   iobuf_t a;
1227   int i;
1228
1229   a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
1230   assert (length == a->d.size);
1231   /* memcpy (a->d.buf, buffer, length); */
1232   for (i=0; i < length; i++)
1233     a->d.buf[i] = buffer[i];
1234   a->d.len = length;
1235
1236   return a;
1237 }
1238
1239 void
1240 iobuf_enable_special_filenames (int yes)
1241 {
1242   special_names_enabled = yes;
1243 }
1244
1245
1246 /* See whether the filename has the form "-&nnnn", where n is a
1247    non-zero number.  Returns this number or -1 if it is not the
1248    case.  */
1249 static int
1250 check_special_filename (const char *fname)
1251 {
1252   if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
1253     {
1254       int i;
1255
1256       fname += 2;
1257       for (i = 0; digitp (fname+i); i++)
1258         ;
1259       if (!fname[i])
1260         return atoi (fname);
1261     }
1262   return -1;
1263 }
1264
1265
1266 int
1267 iobuf_is_pipe_filename (const char *fname)
1268 {
1269   if (!fname || (*fname=='-' && !fname[1]) )
1270     return 1;
1271   return check_special_filename (fname) != -1;
1272 }
1273
1274 static iobuf_t
1275 do_open (const char *fname, int special_filenames,
1276          int use, const char *opentype, int mode700)
1277 {
1278   iobuf_t a;
1279   gnupg_fd_t fp;
1280   file_filter_ctx_t *fcx;
1281   size_t len = 0;
1282   int print_only = 0;
1283   int fd;
1284   byte desc[MAX_IOBUF_DESC];
1285
1286   assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
1287
1288   if (special_filenames
1289       /* NULL or '-'.  */
1290       && (!fname || (*fname == '-' && !fname[1])))
1291     {
1292       if (use == IOBUF_INPUT)
1293         {
1294           fp = FD_FOR_STDIN;
1295           fname = "[stdin]";
1296         }
1297       else
1298         {
1299           fp = FD_FOR_STDOUT;
1300           fname = "[stdout]";
1301         }
1302       print_only = 1;
1303     }
1304   else if (!fname)
1305     return NULL;
1306   else if (special_filenames && (fd = check_special_filename (fname)) != -1)
1307     return iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT ? 0 : 1),
1308                          opentype);
1309   else
1310     {
1311       if (use == IOBUF_INPUT)
1312         fp = fd_cache_open (fname, opentype);
1313       else
1314         fp = direct_open (fname, opentype, mode700);
1315       if (fp == GNUPG_INVALID_FD)
1316         return NULL;
1317     }
1318
1319   a = iobuf_alloc (use, IOBUF_BUFFER_SIZE);
1320   fcx = xmalloc (sizeof *fcx + strlen (fname));
1321   fcx->fp = fp;
1322   fcx->print_only_name = print_only;
1323   strcpy (fcx->fname, fname);
1324   if (!print_only)
1325     a->real_fname = xstrdup (fname);
1326   a->filter = file_filter;
1327   a->filter_ov = fcx;
1328   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1329   if (DBG_IOBUF)
1330     log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n",
1331                a->no, a->subno, fname, iobuf_desc (a, desc), FD2INT (fcx->fp));
1332
1333   return a;
1334 }
1335
1336 iobuf_t
1337 iobuf_open (const char *fname)
1338 {
1339   return do_open (fname, 1, IOBUF_INPUT, "rb", 0);
1340 }
1341
1342 iobuf_t
1343 iobuf_create (const char *fname, int mode700)
1344 {
1345   return do_open (fname, 1, IOBUF_OUTPUT, "wb", mode700);
1346 }
1347
1348 iobuf_t
1349 iobuf_openrw (const char *fname)
1350 {
1351   return do_open (fname, 0, IOBUF_OUTPUT, "r+b", 0);
1352 }
1353
1354
1355 static iobuf_t
1356 do_iobuf_fdopen (int fd, const char *mode, int keep_open)
1357 {
1358   iobuf_t a;
1359   gnupg_fd_t fp;
1360   file_filter_ctx_t *fcx;
1361   size_t len;
1362
1363   fp = INT2FD (fd);
1364
1365   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1366                    IOBUF_BUFFER_SIZE);
1367   fcx = xmalloc (sizeof *fcx + 20);
1368   fcx->fp = fp;
1369   fcx->print_only_name = 1;
1370   fcx->keep_open = keep_open;
1371   sprintf (fcx->fname, "[fd %d]", fd);
1372   a->filter = file_filter;
1373   a->filter_ov = fcx;
1374   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1375   if (DBG_IOBUF)
1376     log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
1377                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1378   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1379   return a;
1380 }
1381
1382
1383 iobuf_t
1384 iobuf_fdopen (int fd, const char *mode)
1385 {
1386   return do_iobuf_fdopen (fd, mode, 0);
1387 }
1388
1389 iobuf_t
1390 iobuf_fdopen_nc (int fd, const char *mode)
1391 {
1392   return do_iobuf_fdopen (fd, mode, 1);
1393 }
1394
1395
1396 iobuf_t
1397 iobuf_esopen (estream_t estream, const char *mode, int keep_open)
1398 {
1399   iobuf_t a;
1400   file_es_filter_ctx_t *fcx;
1401   size_t len = 0;
1402
1403   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1404                    IOBUF_BUFFER_SIZE);
1405   fcx = xtrymalloc (sizeof *fcx + 30);
1406   fcx->fp = estream;
1407   fcx->print_only_name = 1;
1408   fcx->keep_open = keep_open;
1409   sprintf (fcx->fname, "[fd %p]", estream);
1410   a->filter = file_es_filter;
1411   a->filter_ov = fcx;
1412   file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1413   if (DBG_IOBUF)
1414     log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
1415                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1416   return a;
1417 }
1418
1419
1420 iobuf_t
1421 iobuf_sockopen (int fd, const char *mode)
1422 {
1423   iobuf_t a;
1424 #ifdef HAVE_W32_SYSTEM
1425   sock_filter_ctx_t *scx;
1426   size_t len;
1427
1428   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1429                    IOBUF_BUFFER_SIZE);
1430   scx = xmalloc (sizeof *scx + 25);
1431   scx->sock = fd;
1432   scx->print_only_name = 1;
1433   sprintf (scx->fname, "[sock %d]", fd);
1434   a->filter = sock_filter;
1435   a->filter_ov = scx;
1436   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1437   if (DBG_IOBUF)
1438     log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
1439   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1440 #else
1441   a = iobuf_fdopen (fd, mode);
1442 #endif
1443   return a;
1444 }
1445
1446 int
1447 iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
1448 {
1449   byte desc[MAX_IOBUF_DESC];
1450
1451   if (cmd == IOBUF_IOCTL_KEEP_OPEN)
1452     {
1453       /* Keep system filepointer/descriptor open.  This was used in
1454          the past by http.c; this ioctl is not directly used
1455          anymore.  */
1456       if (DBG_IOBUF)
1457         log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
1458                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc),
1459                    intval);
1460       for (; a; a = a->chain)
1461         if (!a->chain && a->filter == file_filter)
1462           {
1463             file_filter_ctx_t *b = a->filter_ov;
1464             b->keep_open = intval;
1465             return 0;
1466           }
1467 #ifdef HAVE_W32_SYSTEM
1468         else if (!a->chain && a->filter == sock_filter)
1469           {
1470             sock_filter_ctx_t *b = a->filter_ov;
1471             b->keep_open = intval;
1472             return 0;
1473           }
1474 #endif
1475     }
1476   else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
1477     {
1478       if (DBG_IOBUF)
1479         log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
1480                    ptrval ? (char *) ptrval : "?");
1481       if (!a && !intval && ptrval)
1482         {
1483           if (fd_cache_invalidate (ptrval))
1484             return -1;
1485           return 0;
1486         }
1487     }
1488   else if (cmd == IOBUF_IOCTL_NO_CACHE)
1489     {
1490       if (DBG_IOBUF)
1491         log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
1492                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc),
1493                    intval);
1494       for (; a; a = a->chain)
1495         if (!a->chain && a->filter == file_filter)
1496           {
1497             file_filter_ctx_t *b = a->filter_ov;
1498             b->no_cache = intval;
1499             return 0;
1500           }
1501 #ifdef HAVE_W32_SYSTEM
1502         else if (!a->chain && a->filter == sock_filter)
1503           {
1504             sock_filter_ctx_t *b = a->filter_ov;
1505             b->no_cache = intval;
1506             return 0;
1507           }
1508 #endif
1509     }
1510   else if (cmd == IOBUF_IOCTL_FSYNC)
1511     {
1512       /* Do a fsync on the open fd and return any errors to the caller
1513          of iobuf_ioctl.  Note that we work on a file name here. */
1514       if (DBG_IOBUF)
1515         log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
1516                    ptrval? (const char*)ptrval:"<null>");
1517
1518       if (!a && !intval && ptrval)
1519         {
1520           return fd_cache_synchronize (ptrval);
1521         }
1522     }
1523
1524
1525   return -1;
1526 }
1527
1528
1529 /****************
1530  * Register an i/o filter.
1531  */
1532 int
1533 iobuf_push_filter (iobuf_t a,
1534                    int (*f) (void *opaque, int control,
1535                              iobuf_t chain, byte * buf, size_t * len),
1536                    void *ov)
1537 {
1538   return iobuf_push_filter2 (a, f, ov, 0);
1539 }
1540
1541 int
1542 iobuf_push_filter2 (iobuf_t a,
1543                     int (*f) (void *opaque, int control,
1544                               iobuf_t chain, byte * buf, size_t * len),
1545                     void *ov, int rel_ov)
1546 {
1547   iobuf_t b;
1548   size_t dummy_len = 0;
1549   int rc = 0;
1550
1551   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1552     return rc;
1553
1554   if (a->subno >= MAX_NESTING_FILTER)
1555     {
1556       log_error ("i/o filter too deeply nested - corrupted data?\n");
1557       return GPG_ERR_BAD_DATA;
1558     }
1559
1560   /* We want to create a new filter and put it in front of A.  A
1561      simple implementation would do:
1562
1563        b = iobuf_alloc (...);
1564        b->chain = a;
1565        return a;
1566
1567      This is a bit problematic: A is the head of the pipeline and
1568      there are potentially many pointers to it.  Requiring the caller
1569      to update all of these pointers is a burden.
1570
1571      An alternative implementation would add a level of indirection.
1572      For instance, we could use a pipeline object, which contains a
1573      pointer to the first filter in the pipeline.  This is not what we
1574      do either.
1575
1576      Instead, we allocate a new buffer (B) and copy the first filter's
1577      state into that and use the initial buffer (A) for the new
1578      filter.  One limitation of this approach is that it is not
1579      practical to maintain a pointer to a specific filter's state.
1580
1581      Before:
1582
1583            A
1584            |
1585            v 0x100               0x200
1586            +----------+          +----------+
1587            | filter x |--------->| filter y |---->....
1588            +----------+          +----------+
1589
1590      After:           B
1591                       |
1592                       v 0x300
1593                       +----------+
1594            A          | filter x |
1595            |          +----------+
1596            v 0x100    ^          v 0x200
1597            +----------+          +----------+
1598            | filter w |          | filter y |---->....
1599            +----------+          +----------+
1600
1601      Note: filter x's address changed from 0x100 to 0x300, but A still
1602      points to the head of the pipeline.
1603   */
1604
1605   b = xmalloc (sizeof *b);
1606   memcpy (b, a, sizeof *b);
1607   /* fixme: it is stupid to keep a copy of the name at every level
1608    * but we need the name somewhere because the name known by file_filter
1609    * may have been released when we need the name of the file */
1610   b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1611   /* remove the filter stuff from the new stream */
1612   a->filter = NULL;
1613   a->filter_ov = NULL;
1614   a->filter_ov_owner = 0;
1615   a->filter_eof = 0;
1616   if (a->use == IOBUF_OUTPUT_TEMP)
1617     /* A TEMP filter buffers any data sent to it; it does not forward
1618        any data down the pipeline.  If we add a new filter to the
1619        pipeline, it shouldn't also buffer data.  It should send it
1620        downstream to be buffered.  Thus, the correct type for a filter
1621        added in front of an IOBUF_OUTPUT_TEMP filter is IOBUF_OUPUT, not
1622        IOBUF_OUTPUT_TEMP.  */
1623     {
1624       a->use = IOBUF_OUTPUT;
1625
1626       /* When pipeline is written to, the temp buffer's size is
1627          increased accordingly.  We don't need to allocate a 10 MB
1628          buffer for a non-terminal filter.  Just use the default
1629          size.  */
1630       a->d.size = IOBUF_BUFFER_SIZE;
1631     }
1632   else if (a->use == IOBUF_INPUT_TEMP)
1633     /* Same idea as above.  */
1634     {
1635       a->use = IOBUF_INPUT;
1636       a->d.size = IOBUF_BUFFER_SIZE;
1637     }
1638
1639   /* The new filter (A) gets a new buffer.
1640
1641      If the pipeline is an output or temp pipeline, then giving the
1642      buffer to the new filter means that data that was written before
1643      the filter was pushed gets sent to the filter.  That's clearly
1644      wrong.
1645
1646      If the pipeline is an input pipeline, then giving the buffer to
1647      the new filter (A) means that data that has read from (B), but
1648      not yet read from the pipeline won't be processed by the new
1649      filter (A)!  That's certainly not what we want.  */
1650   a->d.buf = xmalloc (a->d.size);
1651   a->d.len = 0;
1652   a->d.start = 0;
1653
1654   /* disable nlimit for the new stream */
1655   a->ntotal = b->ntotal + b->nbytes;
1656   a->nlimit = a->nbytes = 0;
1657   a->nofast = 0;
1658   /* make a link from the new stream to the original stream */
1659   a->chain = b;
1660
1661   /* setup the function on the new stream */
1662   a->filter = f;
1663   a->filter_ov = ov;
1664   a->filter_ov_owner = rel_ov;
1665
1666   a->subno = b->subno + 1;
1667
1668   if (DBG_IOBUF)
1669     {
1670       byte desc[MAX_IOBUF_DESC];
1671       log_debug ("iobuf-%d.%d: push '%s'\n",
1672                  a->no, a->subno, iobuf_desc (a, desc));
1673       print_chain (a);
1674     }
1675
1676   /* now we can initialize the new function if we have one */
1677   if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1678                                     NULL, &dummy_len)))
1679     log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1680   return rc;
1681 }
1682
1683 /****************
1684  * Remove an i/o filter.
1685  */
1686 int
1687 iobuf_pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1688                                        iobuf_t chain, byte * buf, size_t * len),
1689                   void *ov)
1690 {
1691   iobuf_t b;
1692   size_t dummy_len = 0;
1693   int rc = 0;
1694   byte desc[MAX_IOBUF_DESC];
1695
1696   if (DBG_IOBUF)
1697     log_debug ("iobuf-%d.%d: pop '%s'\n",
1698                a->no, a->subno, iobuf_desc (a, desc));
1699   if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
1700     {
1701       /* This should be the last filter in the pipeline.  */
1702       assert (! a->chain);
1703       return 0;
1704     }
1705   if (!a->filter)
1706     {                           /* this is simple */
1707       b = a->chain;
1708       assert (b);
1709       xfree (a->d.buf);
1710       xfree (a->real_fname);
1711       memcpy (a, b, sizeof *a);
1712       xfree (b);
1713       return 0;
1714     }
1715   for (b = a; b; b = b->chain)
1716     if (b->filter == f && (!ov || b->filter_ov == ov))
1717       break;
1718   if (!b)
1719     log_bug ("iobuf_pop_filter(): filter function not found\n");
1720
1721   /* flush this stream if it is an output stream */
1722   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (b)))
1723     {
1724       log_error ("filter_flush failed in iobuf_pop_filter: %s\n",
1725                  gpg_strerror (rc));
1726       return rc;
1727     }
1728   /* and tell the filter to free it self */
1729   if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1730                                     NULL, &dummy_len)))
1731     {
1732       log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1733       return rc;
1734     }
1735   if (b->filter_ov && b->filter_ov_owner)
1736     {
1737       xfree (b->filter_ov);
1738       b->filter_ov = NULL;
1739     }
1740
1741
1742   /* and see how to remove it */
1743   if (a == b && !b->chain)
1744     log_bug ("can't remove the last filter from the chain\n");
1745   else if (a == b)
1746     {                           /* remove the first iobuf from the chain */
1747       /* everything from b is copied to a. This is save because
1748        * a flush has been done on the to be removed entry
1749        */
1750       b = a->chain;
1751       xfree (a->d.buf);
1752       xfree (a->real_fname);
1753       memcpy (a, b, sizeof *a);
1754       xfree (b);
1755       if (DBG_IOBUF)
1756         log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1757     }
1758   else if (!b->chain)
1759     {                           /* remove the last iobuf from the chain */
1760       log_bug ("Ohh jeee, trying to remove a head filter\n");
1761     }
1762   else
1763     {                           /* remove an intermediate iobuf from the chain */
1764       log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1765     }
1766
1767   return rc;
1768 }
1769
1770
1771 /****************
1772  * read underflow: read more bytes into the buffer and return
1773  * the first byte or -1 on EOF.
1774  */
1775 static int
1776 underflow (iobuf_t a, int clear_pending_eof)
1777 {
1778   size_t len;
1779   int rc;
1780
1781   if (DBG_IOBUF)
1782     log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
1783                a->no, a->subno,
1784                (int) a->d.size, (int) (a->d.len - a->d.start),
1785                (int) (a->d.size - (a->d.len - a->d.start)));
1786
1787   if (a->use == IOBUF_INPUT_TEMP)
1788     /* By definition, there isn't more data to read into the
1789        buffer.  */
1790     return -1;
1791
1792   assert (a->use == IOBUF_INPUT);
1793
1794   /* If there is still some buffered data, then move it to the start
1795      of the buffer and try to fill the end of the buffer.  (This is
1796      useful if we are called from iobuf_peek().)  */
1797   assert (a->d.start <= a->d.len);
1798   a->d.len -= a->d.start;
1799   memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
1800   a->d.start = 0;
1801
1802   if (a->d.len == 0 && a->filter_eof)
1803     /* The last time we tried to read from this filter, we got an EOF.
1804        We couldn't return the EOF, because there was buffered data.
1805        Since there is no longer any buffered data, return the
1806        error.  */
1807     {
1808       if (DBG_IOBUF)
1809         log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
1810                    a->no, a->subno);
1811       if (! clear_pending_eof)
1812         return -1;
1813
1814       if (a->chain)
1815         /* A filter follows this one.  Free this filter.  */
1816         {
1817           iobuf_t b = a->chain;
1818           if (DBG_IOBUF)
1819             log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
1820                        a->no, a->subno);
1821           xfree (a->d.buf);
1822           xfree (a->real_fname);
1823           memcpy (a, b, sizeof *a);
1824           xfree (b);
1825           print_chain (a);
1826         }
1827       else
1828         a->filter_eof = 0;      /* for the top level filter */
1829       return -1;                /* return one(!) EOF */
1830     }
1831
1832   if (a->d.len == 0 && a->error)
1833     /* The last time we tried to read from this filter, we got an
1834        error.  We couldn't return the error, because there was
1835        buffered data.  Since there is no longer any buffered data,
1836        return the error.  */
1837     {
1838       if (DBG_IOBUF)
1839         log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
1840                    a->no, a->subno, gpg_strerror (a->error));
1841       return -1;
1842     }
1843
1844   if (a->filter && ! a->filter_eof && ! a->error)
1845     /* We have a filter function and the last time we tried to read we
1846        didn't get an EOF or an error.  Try to fill the buffer.  */
1847     {
1848       /* Be careful to account for any buffered data.  */
1849       len = a->d.size - a->d.len;
1850       if (DBG_IOBUF)
1851         log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
1852                    a->no, a->subno, (ulong) len);
1853       if (len == 0)
1854         /* There is no space for more data.  Don't bother calling
1855            A->FILTER.  */
1856         rc = 0;
1857       else
1858         rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1859                         &a->d.buf[a->d.len], &len);
1860       a->d.len += len;
1861
1862       if (DBG_IOBUF)
1863         log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s), read %lu bytes\n",
1864                    a->no, a->subno,
1865                    rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
1866                    (ulong) len);
1867 /*          if( a->no == 1 ) */
1868 /*                   log_hexdump ("     data:", a->d.buf, len); */
1869
1870       if (rc == -1)
1871         /* EOF.  */
1872         {
1873           size_t dummy_len = 0;
1874
1875           /* Tell the filter to free itself */
1876           if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
1877                                NULL, &dummy_len)))
1878             log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1879
1880           /* Free everything except for the internal buffer.  */
1881           if (a->filter_ov && a->filter_ov_owner)
1882             xfree (a->filter_ov);
1883           a->filter_ov = NULL;
1884           a->filter = NULL;
1885           a->filter_eof = 1;
1886
1887           if (clear_pending_eof && a->d.len == 0 && a->chain)
1888             /* We don't need to keep this filter around at all:
1889
1890                  - we got an EOF
1891                  - we have no buffered data
1892                  - a filter follows this one.
1893
1894               Unlink this filter.  */
1895             {
1896               iobuf_t b = a->chain;
1897               if (DBG_IOBUF)
1898                 log_debug ("iobuf-%d.%d: pop in underflow (nothing buffered, got EOF)\n",
1899                            a->no, a->subno);
1900               xfree (a->d.buf);
1901               xfree (a->real_fname);
1902               memcpy (a, b, sizeof *a);
1903               xfree (b);
1904
1905               print_chain (a);
1906
1907               return -1;
1908             }
1909           else if (a->d.len == 0)
1910             /* We can't unlink this filter (it is the only one in the
1911                pipeline), but we can immediately return EOF.  */
1912             return -1;
1913         }
1914       else if (rc)
1915         /* Record the error.  */
1916         {
1917           a->error = rc;
1918
1919           if (a->d.len == 0)
1920             /* There is no buffered data.  Immediately return EOF.  */
1921             return -1;
1922         }
1923     }
1924
1925   assert (a->d.start <= a->d.len);
1926   if (a->d.start < a->d.len)
1927     return a->d.buf[a->d.start++];
1928
1929   /* EOF.  */
1930   return -1;
1931 }
1932
1933
1934 static int
1935 filter_flush (iobuf_t a)
1936 {
1937   size_t len;
1938   int rc;
1939
1940   if (a->use == IOBUF_OUTPUT_TEMP)
1941     {                           /* increase the temp buffer */
1942       size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
1943
1944       if (DBG_IOBUF)
1945         log_debug ("increasing temp iobuf from %lu to %lu\n",
1946                    (ulong) a->d.size, (ulong) newsize);
1947
1948       a->d.buf = xrealloc (a->d.buf, newsize);
1949       a->d.size = newsize;
1950       return 0;
1951     }
1952   else if (a->use != IOBUF_OUTPUT)
1953     log_bug ("flush on non-output iobuf\n");
1954   else if (!a->filter)
1955     log_bug ("filter_flush: no filter\n");
1956   len = a->d.len;
1957   rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
1958   if (!rc && len != a->d.len)
1959     {
1960       log_info ("filter_flush did not write all!\n");
1961       rc = GPG_ERR_INTERNAL;
1962     }
1963   else if (rc)
1964     a->error = rc;
1965   a->d.len = 0;
1966
1967   return rc;
1968 }
1969
1970
1971 int
1972 iobuf_readbyte (iobuf_t a)
1973 {
1974   int c;
1975
1976   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
1977     {
1978       log_bug ("iobuf_readbyte called on a non-INPUT pipeline!\n");
1979       return -1;
1980     }
1981
1982   assert (a->d.start <= a->d.len);
1983
1984   if (a->nlimit && a->nbytes >= a->nlimit)
1985     return -1;                  /* forced EOF */
1986
1987   if (a->d.start < a->d.len)
1988     {
1989       c = a->d.buf[a->d.start++];
1990     }
1991   else if ((c = underflow (a, 1)) == -1)
1992     return -1;                  /* EOF */
1993
1994   assert (a->d.start <= a->d.len);
1995
1996   /* Note: if underflow doesn't return EOF, then it returns the first
1997      byte that was read and advances a->d.start appropriately.  */
1998
1999   a->nbytes++;
2000   return c;
2001 }
2002
2003
2004 int
2005 iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
2006 {
2007   unsigned char *buf = (unsigned char *)buffer;
2008   int c, n;
2009
2010   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
2011     {
2012       log_bug ("iobuf_read called on a non-INPUT pipeline!\n");
2013       return -1;
2014     }
2015
2016   if (a->nlimit)
2017     {
2018       /* Handle special cases. */
2019       for (n = 0; n < buflen; n++)
2020         {
2021           if ((c = iobuf_readbyte (a)) == -1)
2022             {
2023               if (!n)
2024                 return -1;      /* eof */
2025               break;
2026             }
2027
2028           if (buf)
2029             {
2030               *buf = c;
2031               buf++;
2032             }
2033         }
2034       return n;
2035     }
2036
2037   n = 0;
2038   do
2039     {
2040       if (n < buflen && a->d.start < a->d.len)
2041         /* Drain the buffer.  */
2042         {
2043           unsigned size = a->d.len - a->d.start;
2044           if (size > buflen - n)
2045             size = buflen - n;
2046           if (buf)
2047             memcpy (buf, a->d.buf + a->d.start, size);
2048           n += size;
2049           a->d.start += size;
2050           if (buf)
2051             buf += size;
2052         }
2053       if (n < buflen)
2054         /* Draining the internal buffer didn't fill BUFFER.  Call
2055            underflow to read more data into the filter's internal
2056            buffer.  */
2057         {
2058           if ((c = underflow (a, 1)) == -1)
2059             /* EOF.  If we managed to read something, don't return EOF
2060                now.  */
2061             {
2062               a->nbytes += n;
2063               return n ? n : -1 /*EOF*/;
2064             }
2065           if (buf)
2066             *buf++ = c;
2067           n++;
2068         }
2069     }
2070   while (n < buflen);
2071   a->nbytes += n;
2072   return n;
2073 }
2074
2075
2076
2077 int
2078 iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
2079 {
2080   int n = 0;
2081
2082   assert (buflen > 0);
2083   assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
2084
2085   if (buflen > a->d.size)
2086     /* We can't peek more than we can buffer.  */
2087     buflen = a->d.size;
2088
2089   /* Try to fill the internal buffer with enough data to satisfy the
2090      request.  */
2091   while (buflen > a->d.len - a->d.start)
2092     {
2093       if (underflow (a, 0) == -1)
2094         /* EOF.  We can't read any more.  */
2095         break;
2096
2097       /* Underflow consumes the first character (it's the return
2098          value).  unget() it by resetting the "file position".  */
2099       assert (a->d.start == 1);
2100       a->d.start = 0;
2101     }
2102
2103   n = a->d.len - a->d.start;
2104   if (n > buflen)
2105     n = buflen;
2106
2107   if (n == 0)
2108     /* EOF.  */
2109     return -1;
2110
2111   memcpy (buf, &a->d.buf[a->d.start], n);
2112
2113   return n;
2114 }
2115
2116
2117
2118
2119 int
2120 iobuf_writebyte (iobuf_t a, unsigned int c)
2121 {
2122   int rc;
2123
2124   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2125     {
2126       log_bug ("iobuf_writebyte called on an input pipeline!\n");
2127       return -1;
2128     }
2129
2130   if (a->d.len == a->d.size)
2131     if ((rc=filter_flush (a)))
2132       return rc;
2133
2134   assert (a->d.len < a->d.size);
2135   a->d.buf[a->d.len++] = c;
2136   return 0;
2137 }
2138
2139
2140 int
2141 iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
2142 {
2143   const unsigned char *buf = (const unsigned char *)buffer;
2144   int rc;
2145
2146   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2147     {
2148       log_bug ("iobuf_write called on an input pipeline!\n");
2149       return -1;
2150     }
2151
2152   do
2153     {
2154       if (buflen && a->d.len < a->d.size)
2155         {
2156           unsigned size = a->d.size - a->d.len;
2157           if (size > buflen)
2158             size = buflen;
2159           memcpy (a->d.buf + a->d.len, buf, size);
2160           buflen -= size;
2161           buf += size;
2162           a->d.len += size;
2163         }
2164       if (buflen)
2165         {
2166           rc = filter_flush (a);
2167           if (rc)
2168             return rc;
2169         }
2170     }
2171   while (buflen);
2172   return 0;
2173 }
2174
2175
2176 int
2177 iobuf_writestr (iobuf_t a, const char *buf)
2178 {
2179   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2180     {
2181       log_bug ("iobuf_writestr called on an input pipeline!\n");
2182       return -1;
2183     }
2184
2185   return iobuf_write (a, buf, strlen (buf));
2186 }
2187
2188
2189
2190 int
2191 iobuf_write_temp (iobuf_t dest, iobuf_t source)
2192 {
2193   assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2194   assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
2195
2196   iobuf_flush_temp (source);
2197   return iobuf_write (dest, source->d.buf, source->d.len);
2198 }
2199
2200 size_t
2201 iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
2202 {
2203   byte desc[MAX_IOBUF_DESC];
2204   size_t n;
2205
2206   while (1)
2207     {
2208       int rc = filter_flush (a);
2209       if (rc)
2210         log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed.  Ignoring.\n",
2211                  a->no, a->subno, iobuf_desc (a, desc));
2212       if (! a->chain)
2213         break;
2214       a = a->chain;
2215     }
2216
2217   n = a->d.len;
2218   if (n > buflen)
2219     n = buflen;
2220   memcpy (buffer, a->d.buf, n);
2221   return n;
2222 }
2223
2224 /* Copies the data from the input iobuf SOURCE to the output iobuf
2225    DEST until either an error is encountered or EOF is reached.
2226    Returns the number of bytes copies.  */
2227 size_t
2228 iobuf_copy (iobuf_t dest, iobuf_t source)
2229 {
2230   char *temp;
2231   /* Use a 32 KB buffer.  */
2232   const size_t temp_size = 32 * 1024;
2233
2234   size_t nread;
2235   size_t nwrote = 0;
2236   int err;
2237
2238   assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP);
2239   assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2240
2241   if (iobuf_error (dest))
2242     return -1;
2243
2244   temp = xmalloc (temp_size);
2245   while (1)
2246     {
2247       nread = iobuf_read (source, temp, temp_size);
2248       if (nread == -1)
2249         /* EOF.  */
2250         break;
2251
2252       err = iobuf_write (dest, temp, nread);
2253       if (err)
2254         break;
2255       nwrote += nread;
2256     }
2257
2258   /* Burn the buffer.  */
2259   wipememory (temp, sizeof (temp));
2260   xfree (temp);
2261
2262   return nwrote;
2263 }
2264
2265
2266 void
2267 iobuf_flush_temp (iobuf_t temp)
2268 {
2269   if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP)
2270     log_bug ("iobuf_flush_temp called on an input pipeline!\n");
2271   while (temp->chain)
2272     iobuf_pop_filter (temp, temp->filter, NULL);
2273 }
2274
2275
2276 void
2277 iobuf_set_limit (iobuf_t a, off_t nlimit)
2278 {
2279   if (nlimit)
2280     a->nofast = 1;
2281   else
2282     a->nofast = 0;
2283   a->nlimit = nlimit;
2284   a->ntotal += a->nbytes;
2285   a->nbytes = 0;
2286 }
2287
2288
2289
2290 off_t
2291 iobuf_get_filelength (iobuf_t a, int *overflow)
2292 {
2293   if (overflow)
2294     *overflow = 0;
2295
2296   /* Hmmm: file_filter may have already been removed */
2297   for ( ; a->chain; a = a->chain )
2298     ;
2299
2300   if (a->filter != file_filter)
2301     return 0;
2302
2303   {
2304     file_filter_ctx_t *b = a->filter_ov;
2305     gnupg_fd_t fp = b->fp;
2306
2307 #if defined(HAVE_W32_SYSTEM)
2308     ulong size;
2309     static int (* __stdcall get_file_size_ex) (void *handle,
2310                                                LARGE_INTEGER *r_size);
2311     static int get_file_size_ex_initialized;
2312
2313     if (!get_file_size_ex_initialized)
2314       {
2315         void *handle;
2316
2317         handle = dlopen ("kernel32.dll", RTLD_LAZY);
2318         if (handle)
2319           {
2320             get_file_size_ex = dlsym (handle, "GetFileSizeEx");
2321             if (!get_file_size_ex)
2322               dlclose (handle);
2323           }
2324         get_file_size_ex_initialized = 1;
2325       }
2326
2327     if (get_file_size_ex)
2328       {
2329         /* This is a newer system with GetFileSizeEx; we use this
2330            then because it seem that GetFileSize won't return a
2331            proper error in case a file is larger than 4GB. */
2332         LARGE_INTEGER exsize;
2333
2334         if (get_file_size_ex (fp, &exsize))
2335           {
2336             if (!exsize.u.HighPart)
2337               return exsize.u.LowPart;
2338             if (overflow)
2339               *overflow = 1;
2340             return 0;
2341           }
2342       }
2343     else
2344       {
2345         if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
2346           return size;
2347       }
2348     log_error ("GetFileSize for handle %p failed: %s\n",
2349                fp, w32_strerror (0));
2350 #else /*!HAVE_W32_SYSTEM*/
2351     {
2352       struct stat st;
2353
2354       if ( !fstat (FD2INT (fp), &st) )
2355         return st.st_size;
2356       log_error("fstat() failed: %s\n", strerror(errno) );
2357     }
2358 #endif /*!HAVE_W32_SYSTEM*/
2359   }
2360
2361   return 0;
2362 }
2363
2364
2365 int
2366 iobuf_get_fd (iobuf_t a)
2367 {
2368   for (; a->chain; a = a->chain)
2369     ;
2370
2371   if (a->filter != file_filter)
2372     return -1;
2373
2374   {
2375     file_filter_ctx_t *b = a->filter_ov;
2376     gnupg_fd_t fp = b->fp;
2377
2378     return FD2INT (fp);
2379   }
2380 }
2381
2382
2383 off_t
2384 iobuf_tell (iobuf_t a)
2385 {
2386   return a->ntotal + a->nbytes;
2387 }
2388
2389
2390 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2391
2392 #ifdef HAVE_LIMITS_H
2393 # include <limits.h>
2394 #endif
2395 #ifndef LONG_MAX
2396 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2397 #endif
2398 #ifndef LONG_MIN
2399 # define LONG_MIN (-1 - LONG_MAX)
2400 #endif
2401
2402 /****************
2403  * A substitute for fseeko, for hosts that don't have it.
2404  */
2405 static int
2406 fseeko (FILE * stream, off_t newpos, int whence)
2407 {
2408   while (newpos != (long) newpos)
2409     {
2410       long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2411       if (fseek (stream, pos, whence) != 0)
2412         return -1;
2413       newpos -= pos;
2414       whence = SEEK_CUR;
2415     }
2416   return fseek (stream, (long) newpos, whence);
2417 }
2418 #endif
2419
2420 int
2421 iobuf_seek (iobuf_t a, off_t newpos)
2422 {
2423   file_filter_ctx_t *b = NULL;
2424
2425   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_INPUT)
2426     {
2427       /* Find the last filter in the pipeline.  */
2428       for (; a->chain; a = a->chain)
2429         ;
2430
2431       if (a->filter != file_filter)
2432         return -1;
2433
2434       b = a->filter_ov;
2435
2436 #ifdef HAVE_W32_SYSTEM
2437       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2438         {
2439           log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2440                      b->fp, (int) GetLastError ());
2441           return -1;
2442         }
2443 #else
2444       if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2445         {
2446           log_error ("can't lseek: %s\n", strerror (errno));
2447           return -1;
2448         }
2449 #endif
2450       /* Discard the buffer it is not a temp stream.  */
2451       a->d.len = 0;
2452     }
2453   a->d.start = 0;
2454   a->nbytes = 0;
2455   a->nlimit = 0;
2456   a->nofast = 0;
2457   a->ntotal = newpos;
2458   a->error = 0;
2459
2460   /* It is impossible for A->CHAIN to be non-NULL.  If A is an INPUT
2461      or OUTPUT buffer, then we find the last filter, which is defined
2462      as A->CHAIN being NULL.  If A is a TEMP filter, then A must be
2463      the only filter in the pipe: when iobuf_push_filter adds a filter
2464      to the front of a pipeline, it sets the new filter to be an
2465      OUTPUT filter if the pipeline is an OUTPUT or TEMP pipeline and
2466      to be an INPUT filter if the pipeline is an INPUT pipeline.
2467      Thus, only the last filter in a TEMP pipeline can be a */
2468
2469   /* remove filters, but the last */
2470   if (a->chain)
2471     log_debug ("iobuf_pop_filter called in iobuf_seek - please report\n");
2472   while (a->chain)
2473     iobuf_pop_filter (a, a->filter, NULL);
2474
2475   return 0;
2476 }
2477
2478
2479 const char *
2480 iobuf_get_real_fname (iobuf_t a)
2481 {
2482   if (a->real_fname)
2483     return a->real_fname;
2484
2485   /* the old solution */
2486   for (; a; a = a->chain)
2487     if (!a->chain && a->filter == file_filter)
2488       {
2489         file_filter_ctx_t *b = a->filter_ov;
2490         return b->print_only_name ? NULL : b->fname;
2491       }
2492
2493   return NULL;
2494 }
2495
2496 const char *
2497 iobuf_get_fname (iobuf_t a)
2498 {
2499   for (; a; a = a->chain)
2500     if (!a->chain && a->filter == file_filter)
2501       {
2502         file_filter_ctx_t *b = a->filter_ov;
2503         return b->fname;
2504       }
2505   return NULL;
2506 }
2507
2508 const char *
2509 iobuf_get_fname_nonnull (iobuf_t a)
2510 {
2511   const char *fname;
2512
2513   fname = iobuf_get_fname (a);
2514   return fname? fname : "[?]";
2515 }
2516
2517
2518 /****************
2519  * Enable or disable partial body length mode (RFC 4880 4.2.2.4).
2520  *
2521  * If LEN is 0, this disables partial block mode by popping the
2522  * partial body length filter, which which must be the most recently
2523  * added filter.
2524  *
2525  * If LEN is non-zero, it pushes a partial body length filter.  If
2526  * this is a read filter, LEN must be the length byte from the first
2527  * chunk and A should be position just after this first partial body
2528  * length header.
2529  */
2530 void
2531 iobuf_set_partial_body_length_mode (iobuf_t a, size_t len)
2532 {
2533   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2534
2535   ctx->use = a->use;
2536   if (!len)
2537     /* Disable partial body length mode.  */
2538     {
2539       if (a->use == IOBUF_INPUT)
2540         log_debug ("iobuf_pop_filter called in set_partial_block_mode"
2541                    " - please report\n");
2542
2543       log_assert (a->filter == block_filter);
2544       iobuf_pop_filter (a, block_filter, NULL);
2545     }
2546   else
2547     /* Enabled partial body length mode.  */
2548     {
2549       ctx->partial = 1;
2550       ctx->size = 0;
2551       ctx->first_c = len;
2552       iobuf_push_filter (a, block_filter, ctx);
2553     }
2554 }
2555
2556
2557
2558 unsigned int
2559 iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2560                  unsigned *length_of_buffer, unsigned *max_length)
2561 {
2562   int c;
2563   char *buffer = (char *)*addr_of_buffer;
2564   unsigned length = *length_of_buffer;
2565   unsigned nbytes = 0;
2566   unsigned maxlen = *max_length;
2567   char *p;
2568
2569   /* The code assumes that we have space for at least a newline and a
2570      NUL character in the buffer.  This requires at least 2 bytes.  We
2571      don't complicate the code by handling the stupid corner case, but
2572      simply assert that it can't happen.  */
2573   assert (length >= 2 || maxlen >= 2);
2574
2575   if (!buffer || length <= 1)
2576     /* must allocate a new buffer */
2577     {
2578       length = 256 <= maxlen ? 256 : maxlen;
2579       buffer = xrealloc (buffer, length);
2580       *addr_of_buffer = (unsigned char *)buffer;
2581       *length_of_buffer = length;
2582     }
2583
2584   p = buffer;
2585   while ((c = iobuf_get (a)) != -1)
2586     {
2587       *p++ = c;
2588       nbytes++;
2589       if (c == '\n')
2590         break;
2591
2592       if (nbytes == length - 1)
2593         /* We don't have enough space to add a \n and a \0.  Increase
2594            the buffer size.  */
2595         {
2596           if (length == maxlen)
2597             /* We reached the buffer's size limit!  */
2598             {
2599               /* Skip the rest of the line.  */
2600               while (c != '\n' && (c = iobuf_get (a)) != -1)
2601                 ;
2602
2603               /* p is pointing at the last byte in the buffer.  We
2604                  always terminate the line with "\n\0" so overwrite
2605                  the previous byte with a \n.  */
2606               assert (p > buffer);
2607               p[-1] = '\n';
2608
2609               /* Indicate truncation.  */
2610               *max_length = 0;
2611               break;
2612             }
2613
2614           length += length < 1024 ? 256 : 1024;
2615           if (length > maxlen)
2616             length = maxlen;
2617
2618           buffer = xrealloc (buffer, length);
2619           *addr_of_buffer = (unsigned char *)buffer;
2620           *length_of_buffer = length;
2621           p = buffer + nbytes;
2622         }
2623     }
2624   /* Add the terminating NUL.  */
2625   *p = 0;
2626
2627   /* Return the number of characters written to the buffer including
2628      the newline, but not including the terminating NUL.  */
2629   return nbytes;
2630 }
2631
2632 static int
2633 translate_file_handle (int fd, int for_write)
2634 {
2635 #if defined(HAVE_W32CE_SYSTEM)
2636   /* This is called only with one of the special filenames.  Under
2637      W32CE the FD here is not a file descriptor but a rendezvous id,
2638      thus we need to finish the pipe first.  */
2639   fd = _assuan_w32ce_finish_pipe (fd, for_write);
2640 #elif defined(HAVE_W32_SYSTEM)
2641   {
2642     int x;
2643
2644     (void)for_write;
2645
2646     if (fd == 0)
2647       x = (int) GetStdHandle (STD_INPUT_HANDLE);
2648     else if (fd == 1)
2649       x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2650     else if (fd == 2)
2651       x = (int) GetStdHandle (STD_ERROR_HANDLE);
2652     else
2653       x = fd;
2654
2655     if (x == -1)
2656       log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2657                  fd, (int) GetLastError ());
2658
2659     fd = x;
2660   }
2661 #else
2662   (void)for_write;
2663 #endif
2664   return fd;
2665 }
2666
2667
2668 void
2669 iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2670 {
2671   if ( partial )
2672     {
2673       for (;;)
2674         {
2675           if (a->nofast || a->d.start >= a->d.len)
2676             {
2677               if (iobuf_readbyte (a) == -1)
2678                 {
2679                   break;
2680                 }
2681             }
2682           else
2683             {
2684               unsigned long count = a->d.len - a->d.start;
2685               a->nbytes += count;
2686               a->d.start = a->d.len;
2687             }
2688         }
2689     }
2690   else
2691     {
2692       unsigned long remaining = n;
2693       while (remaining > 0)
2694         {
2695           if (a->nofast || a->d.start >= a->d.len)
2696             {
2697               if (iobuf_readbyte (a) == -1)
2698                 {
2699                   break;
2700                 }
2701               --remaining;
2702             }
2703           else
2704             {
2705               unsigned long count = a->d.len - a->d.start;
2706               if (count > remaining)
2707                 {
2708                   count = remaining;
2709                 }
2710               a->nbytes += count;
2711               a->d.start += count;
2712               remaining -= count;
2713             }
2714         }
2715     }
2716 }