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