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