common: Avoid warnings about useless assignments.
[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       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       *(char **) buf = "estream_filter";
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       *(char **) buf = "sock_filter";
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       *(char **) buf = "block_filter";
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 static const char *
1061 iobuf_desc (iobuf_t a)
1062 {
1063   size_t dummy_len = 0;
1064   const char *desc = "?";
1065
1066   if (! a || ! a->filter)
1067     return desc;
1068
1069   a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
1070              (byte *) & desc, &dummy_len);
1071
1072   return desc;
1073 }
1074
1075 static void
1076 print_chain (iobuf_t a)
1077 {
1078   if (!DBG_IOBUF)
1079     return;
1080   for (; a; a = a->chain)
1081     {
1082
1083       log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
1084                  a->no, a->subno, iobuf_desc (a), a->filter_eof,
1085                  (int) a->d.start, (int) a->d.len);
1086     }
1087 }
1088
1089 int
1090 iobuf_print_chain (iobuf_t a)
1091 {
1092   print_chain (a);
1093   return 0;
1094 }
1095
1096 iobuf_t
1097 iobuf_alloc (int use, size_t bufsize)
1098 {
1099   iobuf_t a;
1100   static int number = 0;
1101
1102   assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
1103           || use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
1104   if (bufsize == 0)
1105     {
1106       log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
1107       bufsize = IOBUF_BUFFER_SIZE;
1108     }
1109
1110   a = xcalloc (1, sizeof *a);
1111   a->use = use;
1112   a->d.buf = xmalloc (bufsize);
1113   a->d.size = bufsize;
1114   a->no = ++number;
1115   a->subno = 0;
1116   a->real_fname = NULL;
1117   return a;
1118 }
1119
1120 int
1121 iobuf_close (iobuf_t a)
1122 {
1123   iobuf_t a_chain;
1124   size_t dummy_len = 0;
1125   int rc = 0;
1126
1127   for (; a; a = a_chain)
1128     {
1129       int rc2 = 0;
1130
1131       a_chain = a->chain;
1132
1133       if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1134         log_error ("filter_flush failed on close: %s\n", gpg_strerror (rc));
1135
1136       if (DBG_IOBUF)
1137         log_debug ("iobuf-%d.%d: close '%s'\n",
1138                    a->no, a->subno, iobuf_desc (a));
1139
1140       if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1141                                          a->chain, NULL, &dummy_len)))
1142         log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1143       if (! rc && rc2)
1144         /* Whoops!  An error occurred.  Save it in RC if we haven't
1145            already recorded an error.  */
1146         rc = rc2;
1147
1148       xfree (a->real_fname);
1149       if (a->d.buf)
1150         {
1151           memset (a->d.buf, 0, a->d.size);      /* erase the buffer */
1152           xfree (a->d.buf);
1153         }
1154       xfree (a);
1155     }
1156   return rc;
1157 }
1158
1159 int
1160 iobuf_cancel (iobuf_t a)
1161 {
1162   const char *s;
1163   iobuf_t a2;
1164   int rc;
1165 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1166   char *remove_name = NULL;
1167 #endif
1168
1169   if (a && a->use == IOBUF_OUTPUT)
1170     {
1171       s = iobuf_get_real_fname (a);
1172       if (s && *s)
1173         {
1174 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1175           remove_name = xstrdup (s);
1176 #else
1177           remove (s);
1178 #endif
1179         }
1180     }
1181
1182   /* send a cancel message to all filters */
1183   for (a2 = a; a2; a2 = a2->chain)
1184     {
1185       size_t dummy;
1186       if (a2->filter)
1187         a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1188     }
1189
1190   rc = iobuf_close (a);
1191 #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1192   if (remove_name)
1193     {
1194       /* Argg, MSDOS does not allow to remove open files.  So
1195        * we have to do it here */
1196 #ifdef HAVE_W32CE_SYSTEM
1197       wchar_t *wtmp = utf8_to_wchar (remove_name);
1198       if (wtmp)
1199         DeleteFile (wtmp);
1200       xfree (wtmp);
1201 #else
1202       remove (remove_name);
1203 #endif
1204       xfree (remove_name);
1205     }
1206 #endif
1207   return rc;
1208 }
1209
1210
1211 iobuf_t
1212 iobuf_temp (void)
1213 {
1214   return iobuf_alloc (IOBUF_OUTPUT_TEMP, IOBUF_BUFFER_SIZE);
1215 }
1216
1217 iobuf_t
1218 iobuf_temp_with_content (const char *buffer, size_t length)
1219 {
1220   iobuf_t a;
1221   int i;
1222
1223   a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
1224   assert (length == a->d.size);
1225   /* memcpy (a->d.buf, buffer, length); */
1226   for (i=0; i < length; i++)
1227     a->d.buf[i] = buffer[i];
1228   a->d.len = length;
1229
1230   return a;
1231 }
1232
1233 void
1234 iobuf_enable_special_filenames (int yes)
1235 {
1236   special_names_enabled = yes;
1237 }
1238
1239
1240 /* See whether the filename has the form "-&nnnn", where n is a
1241    non-zero number.  Returns this number or -1 if it is not the
1242    case.  */
1243 static int
1244 check_special_filename (const char *fname)
1245 {
1246   if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
1247     {
1248       int i;
1249
1250       fname += 2;
1251       for (i = 0; digitp (fname+i); i++)
1252         ;
1253       if (!fname[i])
1254         return atoi (fname);
1255     }
1256   return -1;
1257 }
1258
1259
1260 int
1261 iobuf_is_pipe_filename (const char *fname)
1262 {
1263   if (!fname || (*fname=='-' && !fname[1]) )
1264     return 1;
1265   return check_special_filename (fname) != -1;
1266 }
1267
1268 static iobuf_t
1269 do_open (const char *fname, int special_filenames,
1270          int use, const char *opentype, int mode700)
1271 {
1272   iobuf_t a;
1273   gnupg_fd_t fp;
1274   file_filter_ctx_t *fcx;
1275   size_t len = 0;
1276   int print_only = 0;
1277   int fd;
1278
1279   assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
1280
1281   if (special_filenames
1282       /* NULL or '-'.  */
1283       && (!fname || (*fname == '-' && !fname[1])))
1284     {
1285       if (use == IOBUF_INPUT)
1286         {
1287           fp = FD_FOR_STDIN;
1288           fname = "[stdin]";
1289         }
1290       else
1291         {
1292           fp = FD_FOR_STDOUT;
1293           fname = "[stdout]";
1294         }
1295       print_only = 1;
1296     }
1297   else if (!fname)
1298     return NULL;
1299   else if (special_filenames && (fd = check_special_filename (fname)) != -1)
1300     return iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT ? 0 : 1),
1301                          opentype);
1302   else
1303     {
1304       if (use == IOBUF_INPUT)
1305         fp = fd_cache_open (fname, opentype);
1306       else
1307         fp = direct_open (fname, opentype, mode700);
1308       if (fp == GNUPG_INVALID_FD)
1309         return NULL;
1310     }
1311
1312   a = iobuf_alloc (use, IOBUF_BUFFER_SIZE);
1313   fcx = xmalloc (sizeof *fcx + strlen (fname));
1314   fcx->fp = fp;
1315   fcx->print_only_name = print_only;
1316   strcpy (fcx->fname, fname);
1317   if (!print_only)
1318     a->real_fname = xstrdup (fname);
1319   a->filter = file_filter;
1320   a->filter_ov = fcx;
1321   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1322   if (DBG_IOBUF)
1323     log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n",
1324                a->no, a->subno, fname, iobuf_desc (a), FD2INT (fcx->fp));
1325
1326   return a;
1327 }
1328
1329 iobuf_t
1330 iobuf_open (const char *fname)
1331 {
1332   return do_open (fname, 1, IOBUF_INPUT, "rb", 0);
1333 }
1334
1335 iobuf_t
1336 iobuf_create (const char *fname, int mode700)
1337 {
1338   return do_open (fname, 1, IOBUF_OUTPUT, "wb", mode700);
1339 }
1340
1341 iobuf_t
1342 iobuf_openrw (const char *fname)
1343 {
1344   return do_open (fname, 0, IOBUF_OUTPUT, "r+b", 0);
1345 }
1346
1347
1348 static iobuf_t
1349 do_iobuf_fdopen (int fd, const char *mode, int keep_open)
1350 {
1351   iobuf_t a;
1352   gnupg_fd_t fp;
1353   file_filter_ctx_t *fcx;
1354   size_t len;
1355
1356   fp = INT2FD (fd);
1357
1358   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1359                    IOBUF_BUFFER_SIZE);
1360   fcx = xmalloc (sizeof *fcx + 20);
1361   fcx->fp = fp;
1362   fcx->print_only_name = 1;
1363   fcx->keep_open = keep_open;
1364   sprintf (fcx->fname, "[fd %d]", fd);
1365   a->filter = file_filter;
1366   a->filter_ov = fcx;
1367   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1368   if (DBG_IOBUF)
1369     log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
1370                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1371   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1372   return a;
1373 }
1374
1375
1376 iobuf_t
1377 iobuf_fdopen (int fd, const char *mode)
1378 {
1379   return do_iobuf_fdopen (fd, mode, 0);
1380 }
1381
1382 iobuf_t
1383 iobuf_fdopen_nc (int fd, const char *mode)
1384 {
1385   return do_iobuf_fdopen (fd, mode, 1);
1386 }
1387
1388
1389 iobuf_t
1390 iobuf_esopen (estream_t estream, const char *mode, int keep_open)
1391 {
1392   iobuf_t a;
1393   file_es_filter_ctx_t *fcx;
1394   size_t len = 0;
1395
1396   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1397                    IOBUF_BUFFER_SIZE);
1398   fcx = xtrymalloc (sizeof *fcx + 30);
1399   fcx->fp = estream;
1400   fcx->print_only_name = 1;
1401   fcx->keep_open = keep_open;
1402   sprintf (fcx->fname, "[fd %p]", estream);
1403   a->filter = file_es_filter;
1404   a->filter_ov = fcx;
1405   file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1406   if (DBG_IOBUF)
1407     log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
1408                a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1409   return a;
1410 }
1411
1412
1413 iobuf_t
1414 iobuf_sockopen (int fd, const char *mode)
1415 {
1416   iobuf_t a;
1417 #ifdef HAVE_W32_SYSTEM
1418   sock_filter_ctx_t *scx;
1419   size_t len;
1420
1421   a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1422                    IOBUF_BUFFER_SIZE);
1423   scx = xmalloc (sizeof *scx + 25);
1424   scx->sock = fd;
1425   scx->print_only_name = 1;
1426   sprintf (scx->fname, "[sock %d]", fd);
1427   a->filter = sock_filter;
1428   a->filter_ov = scx;
1429   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1430   if (DBG_IOBUF)
1431     log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
1432   iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1433 #else
1434   a = iobuf_fdopen (fd, mode);
1435 #endif
1436   return a;
1437 }
1438
1439 int
1440 iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
1441 {
1442   if (cmd == IOBUF_IOCTL_KEEP_OPEN)
1443     {
1444       /* Keep system filepointer/descriptor open.  This was used in
1445          the past by http.c; this ioctl is not directly used
1446          anymore.  */
1447       if (DBG_IOBUF)
1448         log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
1449                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
1450                    intval);
1451       for (; a; a = a->chain)
1452         if (!a->chain && a->filter == file_filter)
1453           {
1454             file_filter_ctx_t *b = a->filter_ov;
1455             b->keep_open = intval;
1456             return 0;
1457           }
1458 #ifdef HAVE_W32_SYSTEM
1459         else if (!a->chain && a->filter == sock_filter)
1460           {
1461             sock_filter_ctx_t *b = a->filter_ov;
1462             b->keep_open = intval;
1463             return 0;
1464           }
1465 #endif
1466     }
1467   else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
1468     {
1469       if (DBG_IOBUF)
1470         log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
1471                    ptrval ? (char *) ptrval : "?");
1472       if (!a && !intval && ptrval)
1473         {
1474           if (fd_cache_invalidate (ptrval))
1475             return -1;
1476           return 0;
1477         }
1478     }
1479   else if (cmd == IOBUF_IOCTL_NO_CACHE)
1480     {
1481       if (DBG_IOBUF)
1482         log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
1483                    a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
1484                    intval);
1485       for (; a; a = a->chain)
1486         if (!a->chain && a->filter == file_filter)
1487           {
1488             file_filter_ctx_t *b = a->filter_ov;
1489             b->no_cache = intval;
1490             return 0;
1491           }
1492 #ifdef HAVE_W32_SYSTEM
1493         else if (!a->chain && a->filter == sock_filter)
1494           {
1495             sock_filter_ctx_t *b = a->filter_ov;
1496             b->no_cache = intval;
1497             return 0;
1498           }
1499 #endif
1500     }
1501   else if (cmd == IOBUF_IOCTL_FSYNC)
1502     {
1503       /* Do a fsync on the open fd and return any errors to the caller
1504          of iobuf_ioctl.  Note that we work on a file name here. */
1505       if (DBG_IOBUF)
1506         log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
1507                    ptrval? (const char*)ptrval:"<null>");
1508
1509         if (!a && !intval && ptrval)
1510           {
1511             return fd_cache_synchronize (ptrval);
1512           }
1513       }
1514
1515
1516   return -1;
1517 }
1518
1519
1520 /****************
1521  * Register an i/o filter.
1522  */
1523 int
1524 iobuf_push_filter (iobuf_t a,
1525                    int (*f) (void *opaque, int control,
1526                              iobuf_t chain, byte * buf, size_t * len),
1527                    void *ov)
1528 {
1529   return iobuf_push_filter2 (a, f, ov, 0);
1530 }
1531
1532 int
1533 iobuf_push_filter2 (iobuf_t a,
1534                     int (*f) (void *opaque, int control,
1535                               iobuf_t chain, byte * buf, size_t * len),
1536                     void *ov, int rel_ov)
1537 {
1538   iobuf_t b;
1539   size_t dummy_len = 0;
1540   int rc = 0;
1541
1542   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1543     return rc;
1544
1545   if (a->subno >= MAX_NESTING_FILTER)
1546     {
1547       log_error ("i/o filter too deeply nested - corrupted data?\n");
1548       return GPG_ERR_BAD_DATA;
1549     }
1550
1551   /* We want to create a new filter and put it in front of A.  A
1552      simple implementation would do:
1553
1554        b = iobuf_alloc (...);
1555        b->chain = a;
1556        return a;
1557
1558      This is a bit problematic: A is the head of the pipeline and
1559      there are potentially many pointers to it.  Requiring the caller
1560      to update all of these pointers is a burden.
1561
1562      An alternative implementation would add a level of indirection.
1563      For instance, we could use a pipeline object, which contains a
1564      pointer to the first filter in the pipeline.  This is not what we
1565      do either.
1566
1567      Instead, we allocate a new buffer (B) and copy the first filter's
1568      state into that and use the initial buffer (A) for the new
1569      filter.  One limitation of this approach is that it is not
1570      practical to maintain a pointer to a specific filter's state.
1571
1572      Before:
1573
1574            A
1575            |
1576            v 0x100               0x200
1577            +----------+          +----------+
1578            | filter x |--------->| filter y |---->....
1579            +----------+          +----------+
1580
1581      After:           B
1582                       |
1583                       v 0x300
1584                       +----------+
1585            A          | filter x |
1586            |          +----------+
1587            v 0x100    ^          v 0x200
1588            +----------+          +----------+
1589            | filter w |          | filter y |---->....
1590            +----------+          +----------+
1591
1592      Note: filter x's address changed from 0x100 to 0x300, but A still
1593      points to the head of the pipeline.
1594   */
1595
1596   b = xmalloc (sizeof *b);
1597   memcpy (b, a, sizeof *b);
1598   /* fixme: it is stupid to keep a copy of the name at every level
1599    * but we need the name somewhere because the name known by file_filter
1600    * may have been released when we need the name of the file */
1601   b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1602   /* remove the filter stuff from the new stream */
1603   a->filter = NULL;
1604   a->filter_ov = NULL;
1605   a->filter_ov_owner = 0;
1606   a->filter_eof = 0;
1607   if (a->use == IOBUF_OUTPUT_TEMP)
1608     /* A TEMP filter buffers any data sent to it; it does not forward
1609        any data down the pipeline.  If we add a new filter to the
1610        pipeline, it shouldn't also buffer data.  It should send it
1611        downstream to be buffered.  Thus, the correct type for a filter
1612        added in front of an IOBUF_OUTPUT_TEMP filter is IOBUF_OUPUT, not
1613        IOBUF_OUTPUT_TEMP.  */
1614     {
1615       a->use = IOBUF_OUTPUT;
1616
1617       /* When pipeline is written to, the temp buffer's size is
1618          increased accordingly.  We don't need to allocate a 10 MB
1619          buffer for a non-terminal filter.  Just use the default
1620          size.  */
1621       a->d.size = IOBUF_BUFFER_SIZE;
1622     }
1623   else if (a->use == IOBUF_INPUT_TEMP)
1624     /* Same idea as above.  */
1625     {
1626       a->use = IOBUF_INPUT;
1627       a->d.size = IOBUF_BUFFER_SIZE;
1628     }
1629
1630   /* The new filter (A) gets a new buffer.
1631
1632      If the pipeline is an output or temp pipeline, then giving the
1633      buffer to the new filter means that data that was written before
1634      the filter was pushed gets sent to the filter.  That's clearly
1635      wrong.
1636
1637      If the pipeline is an input pipeline, then giving the buffer to
1638      the new filter (A) means that data that has read from (B), but
1639      not yet read from the pipeline won't be processed by the new
1640      filter (A)!  That's certainly not what we want.  */
1641   a->d.buf = xmalloc (a->d.size);
1642   a->d.len = 0;
1643   a->d.start = 0;
1644
1645   /* disable nlimit for the new stream */
1646   a->ntotal = b->ntotal + b->nbytes;
1647   a->nlimit = a->nbytes = 0;
1648   a->nofast = 0;
1649   /* make a link from the new stream to the original stream */
1650   a->chain = b;
1651
1652   /* setup the function on the new stream */
1653   a->filter = f;
1654   a->filter_ov = ov;
1655   a->filter_ov_owner = rel_ov;
1656
1657   a->subno = b->subno + 1;
1658
1659   if (DBG_IOBUF)
1660     {
1661       log_debug ("iobuf-%d.%d: push '%s'\n",
1662                  a->no, a->subno, iobuf_desc (a));
1663       print_chain (a);
1664     }
1665
1666   /* now we can initialize the new function if we have one */
1667   if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1668                                     NULL, &dummy_len)))
1669     log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1670   return rc;
1671 }
1672
1673 /****************
1674  * Remove an i/o filter.
1675  */
1676 static int
1677 pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1678                                iobuf_t chain, byte * buf, size_t * len),
1679             void *ov)
1680 {
1681   iobuf_t b;
1682   size_t dummy_len = 0;
1683   int rc = 0;
1684
1685   if (DBG_IOBUF)
1686     log_debug ("iobuf-%d.%d: pop '%s'\n",
1687                a->no, a->subno, iobuf_desc (a));
1688   if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
1689     {
1690       /* This should be the last filter in the pipeline.  */
1691       assert (! a->chain);
1692       return 0;
1693     }
1694   if (!a->filter)
1695     {                           /* this is simple */
1696       b = a->chain;
1697       assert (b);
1698       xfree (a->d.buf);
1699       xfree (a->real_fname);
1700       memcpy (a, b, sizeof *a);
1701       xfree (b);
1702       return 0;
1703     }
1704   for (b = a; b; b = b->chain)
1705     if (b->filter == f && (!ov || b->filter_ov == ov))
1706       break;
1707   if (!b)
1708     log_bug ("pop_filter(): filter function not found\n");
1709
1710   /* flush this stream if it is an output stream */
1711   if (a->use == IOBUF_OUTPUT && (rc = filter_flush (b)))
1712     {
1713       log_error ("filter_flush failed in pop_filter: %s\n", gpg_strerror (rc));
1714       return rc;
1715     }
1716   /* and tell the filter to free it self */
1717   if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1718                                     NULL, &dummy_len)))
1719     {
1720       log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1721       return rc;
1722     }
1723   if (b->filter_ov && b->filter_ov_owner)
1724     {
1725       xfree (b->filter_ov);
1726       b->filter_ov = NULL;
1727     }
1728
1729
1730   /* and see how to remove it */
1731   if (a == b && !b->chain)
1732     log_bug ("can't remove the last filter from the chain\n");
1733   else if (a == b)
1734     {                           /* remove the first iobuf from the chain */
1735       /* everything from b is copied to a. This is save because
1736        * a flush has been done on the to be removed entry
1737        */
1738       b = a->chain;
1739       xfree (a->d.buf);
1740       xfree (a->real_fname);
1741       memcpy (a, b, sizeof *a);
1742       xfree (b);
1743       if (DBG_IOBUF)
1744         log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1745     }
1746   else if (!b->chain)
1747     {                           /* remove the last iobuf from the chain */
1748       log_bug ("Ohh jeee, trying to remove a head filter\n");
1749     }
1750   else
1751     {                           /* remove an intermediate iobuf from the chain */
1752       log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1753     }
1754
1755   return rc;
1756 }
1757
1758
1759 /****************
1760  * read underflow: read more bytes into the buffer and return
1761  * the first byte or -1 on EOF.
1762  */
1763 static int
1764 underflow (iobuf_t a, int clear_pending_eof)
1765 {
1766   size_t len;
1767   int rc;
1768
1769   if (DBG_IOBUF)
1770     log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
1771                a->no, a->subno,
1772                (int) a->d.size, (int) (a->d.len - a->d.start),
1773                (int) (a->d.size - (a->d.len - a->d.start)));
1774
1775   if (a->use == IOBUF_INPUT_TEMP)
1776     /* By definition, there isn't more data to read into the
1777        buffer.  */
1778     return -1;
1779
1780   assert (a->use == IOBUF_INPUT);
1781
1782   /* If there is still some buffered data, then move it to the start
1783      of the buffer and try to fill the end of the buffer.  (This is
1784      useful if we are called from iobuf_peek().)  */
1785   assert (a->d.start <= a->d.len);
1786   a->d.len -= a->d.start;
1787   memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
1788   a->d.start = 0;
1789
1790   if (a->d.len == 0 && a->filter_eof)
1791     /* The last time we tried to read from this filter, we got an EOF.
1792        We couldn't return the EOF, because there was buffered data.
1793        Since there is no longer any buffered data, return the
1794        error.  */
1795     {
1796       if (DBG_IOBUF)
1797         log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
1798                    a->no, a->subno);
1799       if (! clear_pending_eof)
1800         return -1;
1801
1802       if (a->chain)
1803         /* A filter follows this one.  Free this filter.  */
1804         {
1805           iobuf_t b = a->chain;
1806           if (DBG_IOBUF)
1807             log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
1808                        a->no, a->subno);
1809           xfree (a->d.buf);
1810           xfree (a->real_fname);
1811           memcpy (a, b, sizeof *a);
1812           xfree (b);
1813           print_chain (a);
1814         }
1815       else
1816         a->filter_eof = 0;      /* for the top level filter */
1817       return -1;                /* return one(!) EOF */
1818     }
1819
1820   if (a->d.len == 0 && a->error)
1821     /* The last time we tried to read from this filter, we got an
1822        error.  We couldn't return the error, because there was
1823        buffered data.  Since there is no longer any buffered data,
1824        return the error.  */
1825     {
1826       if (DBG_IOBUF)
1827         log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
1828                    a->no, a->subno, gpg_strerror (a->error));
1829       return -1;
1830     }
1831
1832   if (a->filter && ! a->filter_eof && ! a->error)
1833     /* We have a filter function and the last time we tried to read we
1834        didn't get an EOF or an error.  Try to fill the buffer.  */
1835     {
1836       /* Be careful to account for any buffered data.  */
1837       len = a->d.size - a->d.len;
1838       if (DBG_IOBUF)
1839         log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
1840                    a->no, a->subno, (ulong) len);
1841       if (len == 0)
1842         /* There is no space for more data.  Don't bother calling
1843            A->FILTER.  */
1844         rc = 0;
1845       else
1846         rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1847                         &a->d.buf[a->d.len], &len);
1848       a->d.len += len;
1849
1850       if (DBG_IOBUF)
1851         log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s), read %lu bytes\n",
1852                    a->no, a->subno,
1853                    rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
1854                    (ulong) len);
1855 /*          if( a->no == 1 ) */
1856 /*                   log_hexdump ("     data:", a->d.buf, len); */
1857
1858       if (rc == -1)
1859         /* EOF.  */
1860         {
1861           size_t dummy_len = 0;
1862
1863           /* Tell the filter to free itself */
1864           if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
1865                                NULL, &dummy_len)))
1866             log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1867
1868           /* Free everything except for the internal buffer.  */
1869           if (a->filter_ov && a->filter_ov_owner)
1870             xfree (a->filter_ov);
1871           a->filter_ov = NULL;
1872           a->filter = NULL;
1873           a->filter_eof = 1;
1874
1875           if (clear_pending_eof && a->d.len == 0 && a->chain)
1876             /* We don't need to keep this filter around at all:
1877
1878                  - we got an EOF
1879                  - we have no buffered data
1880                  - a filter follows this one.
1881
1882               Unlink this filter.  */
1883             {
1884               iobuf_t b = a->chain;
1885               if (DBG_IOBUF)
1886                 log_debug ("iobuf-%d.%d: pop in underflow (nothing buffered, got EOF)\n",
1887                            a->no, a->subno);
1888               xfree (a->d.buf);
1889               xfree (a->real_fname);
1890               memcpy (a, b, sizeof *a);
1891               xfree (b);
1892
1893               print_chain (a);
1894
1895               return -1;
1896             }
1897           else if (a->d.len == 0)
1898             /* We can't unlink this filter (it is the only one in the
1899                pipeline), but we can immediately return EOF.  */
1900             return -1;
1901         }
1902       else if (rc)
1903         /* Record the error.  */
1904         {
1905           a->error = rc;
1906
1907           if (a->d.len == 0)
1908             /* There is no buffered data.  Immediately return EOF.  */
1909             return -1;
1910         }
1911     }
1912
1913   assert (a->d.start <= a->d.len);
1914   if (a->d.start < a->d.len)
1915     return a->d.buf[a->d.start++];
1916
1917   /* EOF.  */
1918   return -1;
1919 }
1920
1921
1922 static int
1923 filter_flush (iobuf_t a)
1924 {
1925   size_t len;
1926   int rc;
1927
1928   if (a->use == IOBUF_OUTPUT_TEMP)
1929     {                           /* increase the temp buffer */
1930       size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
1931
1932       if (DBG_IOBUF)
1933         log_debug ("increasing temp iobuf from %lu to %lu\n",
1934                    (ulong) a->d.size, (ulong) newsize);
1935
1936       a->d.buf = xrealloc (a->d.buf, newsize);
1937       a->d.size = newsize;
1938       return 0;
1939     }
1940   else if (a->use != IOBUF_OUTPUT)
1941     log_bug ("flush on non-output iobuf\n");
1942   else if (!a->filter)
1943     log_bug ("filter_flush: no filter\n");
1944   len = a->d.len;
1945   rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
1946   if (!rc && len != a->d.len)
1947     {
1948       log_info ("filter_flush did not write all!\n");
1949       rc = GPG_ERR_INTERNAL;
1950     }
1951   else if (rc)
1952     a->error = rc;
1953   a->d.len = 0;
1954
1955   return rc;
1956 }
1957
1958
1959 int
1960 iobuf_readbyte (iobuf_t a)
1961 {
1962   int c;
1963
1964   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
1965     {
1966       log_bug ("iobuf_readbyte called on a non-INPUT pipeline!\n");
1967       return -1;
1968     }
1969
1970   assert (a->d.start <= a->d.len);
1971
1972   if (a->nlimit && a->nbytes >= a->nlimit)
1973     return -1;                  /* forced EOF */
1974
1975   if (a->d.start < a->d.len)
1976     {
1977       c = a->d.buf[a->d.start++];
1978     }
1979   else if ((c = underflow (a, 1)) == -1)
1980     return -1;                  /* EOF */
1981
1982   assert (a->d.start <= a->d.len);
1983
1984   /* Note: if underflow doesn't return EOF, then it returns the first
1985      byte that was read and advances a->d.start appropriately.  */
1986
1987   a->nbytes++;
1988   return c;
1989 }
1990
1991
1992 int
1993 iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
1994 {
1995   unsigned char *buf = (unsigned char *)buffer;
1996   int c, n;
1997
1998   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
1999     {
2000       log_bug ("iobuf_read called on a non-INPUT pipeline!\n");
2001       return -1;
2002     }
2003
2004   if (a->nlimit)
2005     {
2006       /* Handle special cases. */
2007       for (n = 0; n < buflen; n++)
2008         {
2009           if ((c = iobuf_readbyte (a)) == -1)
2010             {
2011               if (!n)
2012                 return -1;      /* eof */
2013               break;
2014             }
2015
2016           if (buf)
2017             {
2018               *buf = c;
2019               buf++;
2020             }
2021         }
2022       return n;
2023     }
2024
2025   n = 0;
2026   do
2027     {
2028       if (n < buflen && a->d.start < a->d.len)
2029         /* Drain the buffer.  */
2030         {
2031           unsigned size = a->d.len - a->d.start;
2032           if (size > buflen - n)
2033             size = buflen - n;
2034           if (buf)
2035             memcpy (buf, a->d.buf + a->d.start, size);
2036           n += size;
2037           a->d.start += size;
2038           if (buf)
2039             buf += size;
2040         }
2041       if (n < buflen)
2042         /* Draining the internal buffer didn't fill BUFFER.  Call
2043            underflow to read more data into the filter's internal
2044            buffer.  */
2045         {
2046           if ((c = underflow (a, 1)) == -1)
2047             /* EOF.  If we managed to read something, don't return EOF
2048                now.  */
2049             {
2050               a->nbytes += n;
2051               return n ? n : -1 /*EOF*/;
2052             }
2053           if (buf)
2054             *buf++ = c;
2055           n++;
2056         }
2057     }
2058   while (n < buflen);
2059   a->nbytes += n;
2060   return n;
2061 }
2062
2063
2064
2065 int
2066 iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
2067 {
2068   int n = 0;
2069
2070   assert (buflen > 0);
2071   assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
2072
2073   if (buflen > a->d.size)
2074     /* We can't peek more than we can buffer.  */
2075     buflen = a->d.size;
2076
2077   /* Try to fill the internal buffer with enough data to satisfy the
2078      request.  */
2079   while (buflen > a->d.len - a->d.start)
2080     {
2081       if (underflow (a, 0) == -1)
2082         /* EOF.  We can't read any more.  */
2083         break;
2084
2085       /* Underflow consumes the first character (it's the return
2086          value).  unget() it by resetting the "file position".  */
2087       assert (a->d.start == 1);
2088       a->d.start = 0;
2089     }
2090
2091   n = a->d.len - a->d.start;
2092   if (n > buflen)
2093     n = buflen;
2094
2095   if (n == 0)
2096     /* EOF.  */
2097     return -1;
2098
2099   memcpy (buf, &a->d.buf[a->d.start], n);
2100
2101   return n;
2102 }
2103
2104
2105
2106
2107 int
2108 iobuf_writebyte (iobuf_t a, unsigned int c)
2109 {
2110   int rc;
2111
2112   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2113     {
2114       log_bug ("iobuf_writebyte called on an input pipeline!\n");
2115       return -1;
2116     }
2117
2118   if (a->d.len == a->d.size)
2119     if ((rc=filter_flush (a)))
2120       return rc;
2121
2122   assert (a->d.len < a->d.size);
2123   a->d.buf[a->d.len++] = c;
2124   return 0;
2125 }
2126
2127
2128 int
2129 iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
2130 {
2131   const unsigned char *buf = (const unsigned char *)buffer;
2132   int rc;
2133
2134   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2135     {
2136       log_bug ("iobuf_write called on an input pipeline!\n");
2137       return -1;
2138     }
2139
2140   do
2141     {
2142       if (buflen && a->d.len < a->d.size)
2143         {
2144           unsigned size = a->d.size - a->d.len;
2145           if (size > buflen)
2146             size = buflen;
2147           memcpy (a->d.buf + a->d.len, buf, size);
2148           buflen -= size;
2149           buf += size;
2150           a->d.len += size;
2151         }
2152       if (buflen)
2153         {
2154           rc = filter_flush (a);
2155           if (rc)
2156             return rc;
2157         }
2158     }
2159   while (buflen);
2160   return 0;
2161 }
2162
2163
2164 int
2165 iobuf_writestr (iobuf_t a, const char *buf)
2166 {
2167   if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2168     {
2169       log_bug ("iobuf_writestr called on an input pipeline!\n");
2170       return -1;
2171     }
2172
2173   return iobuf_write (a, buf, strlen (buf));
2174 }
2175
2176
2177
2178 int
2179 iobuf_write_temp (iobuf_t dest, iobuf_t source)
2180 {
2181   assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2182   assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
2183
2184   iobuf_flush_temp (source);
2185   return iobuf_write (dest, source->d.buf, source->d.len);
2186 }
2187
2188 size_t
2189 iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
2190 {
2191   size_t n;
2192
2193   while (1)
2194     {
2195       int rc = filter_flush (a);
2196       if (rc)
2197         log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed.  Ignoring.\n",
2198                  a->no, a->subno, iobuf_desc (a));
2199       if (! a->chain)
2200         break;
2201       a = a->chain;
2202     }
2203
2204   n = a->d.len;
2205   if (n > buflen)
2206     n = buflen;
2207   memcpy (buffer, a->d.buf, n);
2208   return n;
2209 }
2210
2211 /* Copies the data from the input iobuf SOURCE to the output iobuf
2212    DEST until either an error is encountered or EOF is reached.
2213    Returns the number of bytes copies.  */
2214 size_t
2215 iobuf_copy (iobuf_t dest, iobuf_t source)
2216 {
2217   char *temp;
2218   /* Use a 1 MB buffer.  */
2219   const size_t temp_size = 1024 * 1024;
2220
2221   size_t nread;
2222   size_t nwrote = 0;
2223   int err;
2224
2225   assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP);
2226   assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2227
2228   temp = xmalloc (temp_size);
2229   while (1)
2230     {
2231       nread = iobuf_read (source, temp, temp_size);
2232       if (nread == -1)
2233         /* EOF.  */
2234         break;
2235
2236       err = iobuf_write (dest, temp, nread);
2237       if (err)
2238         break;
2239       nwrote += nread;
2240     }
2241   xfree (temp);
2242
2243   return nwrote;
2244 }
2245
2246
2247 void
2248 iobuf_flush_temp (iobuf_t temp)
2249 {
2250   if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP)
2251     log_bug ("iobuf_writestr called on an input pipeline!\n");
2252   while (temp->chain)
2253     pop_filter (temp, temp->filter, NULL);
2254 }
2255
2256
2257 void
2258 iobuf_set_limit (iobuf_t a, off_t nlimit)
2259 {
2260   if (nlimit)
2261     a->nofast = 1;
2262   else
2263     a->nofast = 0;
2264   a->nlimit = nlimit;
2265   a->ntotal += a->nbytes;
2266   a->nbytes = 0;
2267 }
2268
2269
2270
2271 off_t
2272 iobuf_get_filelength (iobuf_t a, int *overflow)
2273 {
2274   if (overflow)
2275     *overflow = 0;
2276
2277   /* Hmmm: file_filter may have already been removed */
2278   for ( ; a->chain; a = a->chain )
2279     ;
2280
2281   if (a->filter != file_filter)
2282     return 0;
2283
2284   {
2285     file_filter_ctx_t *b = a->filter_ov;
2286     gnupg_fd_t fp = b->fp;
2287
2288 #if defined(HAVE_W32_SYSTEM)
2289     ulong size;
2290     static int (* __stdcall get_file_size_ex) (void *handle,
2291                                                LARGE_INTEGER *r_size);
2292     static int get_file_size_ex_initialized;
2293
2294     if (!get_file_size_ex_initialized)
2295       {
2296         void *handle;
2297
2298         handle = dlopen ("kernel32.dll", RTLD_LAZY);
2299         if (handle)
2300           {
2301             get_file_size_ex = dlsym (handle, "GetFileSizeEx");
2302             if (!get_file_size_ex)
2303               dlclose (handle);
2304           }
2305         get_file_size_ex_initialized = 1;
2306       }
2307
2308     if (get_file_size_ex)
2309       {
2310         /* This is a newer system with GetFileSizeEx; we use this
2311            then because it seem that GetFileSize won't return a
2312            proper error in case a file is larger than 4GB. */
2313         LARGE_INTEGER exsize;
2314
2315         if (get_file_size_ex (fp, &exsize))
2316           {
2317             if (!exsize.u.HighPart)
2318               return exsize.u.LowPart;
2319             if (overflow)
2320               *overflow = 1;
2321             return 0;
2322           }
2323       }
2324     else
2325       {
2326         if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
2327           return size;
2328       }
2329     log_error ("GetFileSize for handle %p failed: %s\n",
2330                fp, w32_strerror (0));
2331 #else /*!HAVE_W32_SYSTEM*/
2332     {
2333       struct stat st;
2334
2335       if ( !fstat (FD2INT (fp), &st) )
2336         return st.st_size;
2337       log_error("fstat() failed: %s\n", strerror(errno) );
2338     }
2339 #endif /*!HAVE_W32_SYSTEM*/
2340   }
2341
2342   return 0;
2343 }
2344
2345
2346 int
2347 iobuf_get_fd (iobuf_t a)
2348 {
2349   for (; a->chain; a = a->chain)
2350     ;
2351
2352   if (a->filter != file_filter)
2353     return -1;
2354
2355   {
2356     file_filter_ctx_t *b = a->filter_ov;
2357     gnupg_fd_t fp = b->fp;
2358
2359     return FD2INT (fp);
2360   }
2361 }
2362
2363
2364 off_t
2365 iobuf_tell (iobuf_t a)
2366 {
2367   return a->ntotal + a->nbytes;
2368 }
2369
2370
2371 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2372
2373 #ifdef HAVE_LIMITS_H
2374 # include <limits.h>
2375 #endif
2376 #ifndef LONG_MAX
2377 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2378 #endif
2379 #ifndef LONG_MIN
2380 # define LONG_MIN (-1 - LONG_MAX)
2381 #endif
2382
2383 /****************
2384  * A substitute for fseeko, for hosts that don't have it.
2385  */
2386 static int
2387 fseeko (FILE * stream, off_t newpos, int whence)
2388 {
2389   while (newpos != (long) newpos)
2390     {
2391       long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2392       if (fseek (stream, pos, whence) != 0)
2393         return -1;
2394       newpos -= pos;
2395       whence = SEEK_CUR;
2396     }
2397   return fseek (stream, (long) newpos, whence);
2398 }
2399 #endif
2400
2401 int
2402 iobuf_seek (iobuf_t a, off_t newpos)
2403 {
2404   file_filter_ctx_t *b = NULL;
2405
2406   if (a->use == IOBUF_OUTPUT || a->use == IOBUF_INPUT)
2407     {
2408       /* Find the last filter in the pipeline.  */
2409       for (; a->chain; a = a->chain)
2410         ;
2411
2412       if (a->filter != file_filter)
2413         return -1;
2414
2415       b = a->filter_ov;
2416
2417 #ifdef HAVE_W32_SYSTEM
2418       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2419         {
2420           log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2421                      b->fp, (int) GetLastError ());
2422           return -1;
2423         }
2424 #else
2425       if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2426         {
2427           log_error ("can't lseek: %s\n", strerror (errno));
2428           return -1;
2429         }
2430 #endif
2431       /* Discard the buffer it is not a temp stream.  */
2432       a->d.len = 0;
2433     }
2434   a->d.start = 0;
2435   a->nbytes = 0;
2436   a->nlimit = 0;
2437   a->nofast = 0;
2438   a->ntotal = newpos;
2439   a->error = 0;
2440
2441   /* It is impossible for A->CHAIN to be non-NULL.  If A is an INPUT
2442      or OUTPUT buffer, then we find the last filter, which is defined
2443      as A->CHAIN being NULL.  If A is a TEMP filter, then A must be
2444      the only filter in the pipe: when iobuf_push_filter adds a filter
2445      to the front of a pipeline, it sets the new filter to be an
2446      OUTPUT filter if the pipeline is an OUTPUT or TEMP pipeline and
2447      to be an INPUT filter if the pipeline is an INPUT pipeline.
2448      Thus, only the last filter in a TEMP pipeline can be a */
2449
2450   /* remove filters, but the last */
2451   if (a->chain)
2452     log_debug ("pop_filter called in iobuf_seek - please report\n");
2453   while (a->chain)
2454     pop_filter (a, a->filter, NULL);
2455
2456   return 0;
2457 }
2458
2459
2460 const char *
2461 iobuf_get_real_fname (iobuf_t a)
2462 {
2463   if (a->real_fname)
2464     return a->real_fname;
2465
2466   /* the old solution */
2467   for (; a; a = a->chain)
2468     if (!a->chain && a->filter == file_filter)
2469       {
2470         file_filter_ctx_t *b = a->filter_ov;
2471         return b->print_only_name ? NULL : b->fname;
2472       }
2473
2474   return NULL;
2475 }
2476
2477 const char *
2478 iobuf_get_fname (iobuf_t a)
2479 {
2480   for (; a; a = a->chain)
2481     if (!a->chain && a->filter == file_filter)
2482       {
2483         file_filter_ctx_t *b = a->filter_ov;
2484         return b->fname;
2485       }
2486   return NULL;
2487 }
2488
2489 const char *
2490 iobuf_get_fname_nonnull (iobuf_t a)
2491 {
2492   const char *fname;
2493
2494   fname = iobuf_get_fname (a);
2495   return fname? fname : "[?]";
2496 }
2497
2498
2499 /****************
2500  * enable partial block mode as described in the OpenPGP draft.
2501  * LEN is the first length byte on read, but ignored on writes.
2502  */
2503 void
2504 iobuf_set_partial_block_mode (iobuf_t a, size_t len)
2505 {
2506   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2507
2508   ctx->use = a->use;
2509   if (!len)
2510     {
2511       if (a->use == IOBUF_INPUT)
2512         log_debug ("pop_filter called in set_partial_block_mode"
2513                    " - please report\n");
2514       /* XXX: This pop_filter doesn't make sense.  Since we haven't
2515          actually added the filter to the pipeline yet, why are we
2516          popping anything?  Moreover, since we don't report an error,
2517          the caller won't directly see an error.  I think that it
2518          would be better to push the filter and set a->error to
2519          GPG_ERR_BAD_DATA, but Werner thinks it's impossible for len
2520          to be 0 (but he doesn't want to remove the check just in
2521          case).  */
2522       pop_filter (a, block_filter, NULL);
2523     }
2524   else
2525     {
2526       ctx->partial = 1;
2527       ctx->size = 0;
2528       ctx->first_c = len;
2529       iobuf_push_filter (a, block_filter, ctx);
2530     }
2531 }
2532
2533
2534
2535 unsigned int
2536 iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2537                  unsigned *length_of_buffer, unsigned *max_length)
2538 {
2539   int c;
2540   char *buffer = (char *)*addr_of_buffer;
2541   unsigned length = *length_of_buffer;
2542   unsigned nbytes = 0;
2543   unsigned maxlen = *max_length;
2544   char *p;
2545
2546   /* The code assumes that we have space for at least a newline and a
2547      NUL character in the buffer.  This requires at least 2 bytes.  We
2548      don't complicate the code by handling the stupid corner case, but
2549      simply assert that it can't happen.  */
2550   assert (length >= 2 || maxlen >= 2);
2551
2552   if (!buffer || length <= 1)
2553     /* must allocate a new buffer */
2554     {
2555       length = 256 <= maxlen ? 256 : maxlen;
2556       buffer = xrealloc (buffer, length);
2557       *addr_of_buffer = (unsigned char *)buffer;
2558       *length_of_buffer = length;
2559     }
2560
2561   p = buffer;
2562   while ((c = iobuf_get (a)) != -1)
2563     {
2564       *p++ = c;
2565       nbytes++;
2566       if (c == '\n')
2567         break;
2568
2569       if (nbytes == length - 1)
2570         /* We don't have enough space to add a \n and a \0.  Increase
2571            the buffer size.  */
2572         {
2573           if (length == maxlen)
2574             /* We reached the buffer's size limit!  */
2575             {
2576               /* Skip the rest of the line.  */
2577               while (c != '\n' && (c = iobuf_get (a)) != -1)
2578                 ;
2579
2580               /* p is pointing at the last byte in the buffer.  We
2581                  always terminate the line with "\n\0" so overwrite
2582                  the previous byte with a \n.  */
2583               assert (p > buffer);
2584               p[-1] = '\n';
2585
2586               /* Indicate truncation.  */
2587               *max_length = 0;
2588               break;
2589             }
2590
2591           length += length < 1024 ? 256 : 1024;
2592           if (length > maxlen)
2593             length = maxlen;
2594
2595           buffer = xrealloc (buffer, length);
2596           *addr_of_buffer = (unsigned char *)buffer;
2597           *length_of_buffer = length;
2598           p = buffer + nbytes;
2599         }
2600     }
2601   /* Add the terminating NUL.  */
2602   *p = 0;
2603
2604   /* Return the number of characters written to the buffer including
2605      the newline, but not including the terminating NUL.  */
2606   return nbytes;
2607 }
2608
2609 static int
2610 translate_file_handle (int fd, int for_write)
2611 {
2612 #if defined(HAVE_W32CE_SYSTEM)
2613   /* This is called only with one of the special filenames.  Under
2614      W32CE the FD here is not a file descriptor but a rendezvous id,
2615      thus we need to finish the pipe first.  */
2616   fd = _assuan_w32ce_finish_pipe (fd, for_write);
2617 #elif defined(HAVE_W32_SYSTEM)
2618   {
2619     int x;
2620
2621     (void)for_write;
2622
2623     if (fd == 0)
2624       x = (int) GetStdHandle (STD_INPUT_HANDLE);
2625     else if (fd == 1)
2626       x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2627     else if (fd == 2)
2628       x = (int) GetStdHandle (STD_ERROR_HANDLE);
2629     else
2630       x = fd;
2631
2632     if (x == -1)
2633       log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2634                  fd, (int) GetLastError ());
2635
2636     fd = x;
2637   }
2638 #else
2639   (void)for_write;
2640 #endif
2641   return fd;
2642 }
2643
2644
2645 void
2646 iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2647 {
2648   if ( partial )
2649     {
2650       for (;;)
2651         {
2652           if (a->nofast || a->d.start >= a->d.len)
2653             {
2654               if (iobuf_readbyte (a) == -1)
2655                 {
2656                   break;
2657                 }
2658             }
2659           else
2660             {
2661               unsigned long count = a->d.len - a->d.start;
2662               a->nbytes += count;
2663               a->d.start = a->d.len;
2664             }
2665         }
2666     }
2667   else
2668     {
2669       unsigned long remaining = n;
2670       while (remaining > 0)
2671         {
2672           if (a->nofast || a->d.start >= a->d.len)
2673             {
2674               if (iobuf_readbyte (a) == -1)
2675                 {
2676                   break;
2677                 }
2678               --remaining;
2679             }
2680           else
2681             {
2682               unsigned long count = a->d.len - a->d.start;
2683               if (count > remaining)
2684                 {
2685                   count = remaining;
2686                 }
2687               a->nbytes += count;
2688               a->d.start += count;
2689               remaining -= count;
2690             }
2691         }
2692     }
2693 }