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