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