* Makefile.am (sm): Build kbx only if gpgsm is to be build.
[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 * buf,
679               size_t * ret_len)
680 {
681   block_filter_ctx_t *a = opaque;
682   size_t size = *ret_len;
683   int c, needed, rc = 0;
684   char *p;
685
686   if (control == IOBUFCTRL_UNDERFLOW)
687     {
688       size_t n = 0;
689
690       p = buf;
691       assert (size);            /* need a buffer */
692       if (a->eof)               /* don't read any further */
693         rc = -1;
694       while (!rc && size)
695         {
696           if (!a->size)
697             {                   /* get the length bytes */
698               if (a->partial == 2)
699                 {
700                   a->eof = 1;
701                   if (!n)
702                     rc = -1;
703                   break;
704                 }
705               else if (a->partial)
706                 {
707                   /* These OpenPGP introduced huffman like encoded length
708                    * bytes are really a mess :-( */
709                   if (a->first_c)
710                     {
711                       c = a->first_c;
712                       a->first_c = 0;
713                     }
714                   else if ((c = iobuf_get (chain)) == -1)
715                     {
716                       log_error ("block_filter: 1st length byte missing\n");
717                       rc = GPG_ERR_BAD_DATA;
718                       break;
719                     }
720                   if (c < 192)
721                     {
722                       a->size = c;
723                       a->partial = 2;
724                       if (!a->size)
725                         {
726                           a->eof = 1;
727                           if (!n)
728                             rc = -1;
729                           break;
730                         }
731                     }
732                   else if (c < 224)
733                     {
734                       a->size = (c - 192) * 256;
735                       if ((c = iobuf_get (chain)) == -1)
736                         {
737                           log_error
738                             ("block_filter: 2nd length byte missing\n");
739                           rc = GPG_ERR_BAD_DATA;
740                           break;
741                         }
742                       a->size += c + 192;
743                       a->partial = 2;
744                       if (!a->size)
745                         {
746                           a->eof = 1;
747                           if (!n)
748                             rc = -1;
749                           break;
750                         }
751                     }
752                   else if (c == 255)
753                     {
754                       a->size = iobuf_get (chain) << 24;
755                       a->size |= iobuf_get (chain) << 16;
756                       a->size |= iobuf_get (chain) << 8;
757                       if ((c = iobuf_get (chain)) == -1)
758                         {
759                           log_error ("block_filter: invalid 4 byte length\n");
760                           rc = GPG_ERR_BAD_DATA;
761                           break;
762                         }
763                       a->size |= c;
764                     }
765                   else
766                     {           /* next partial body length */
767                       a->size = 1 << (c & 0x1f);
768                     }
769                   /*  log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
770                 }
771               else
772                 {               /* the gnupg partial length scheme - much better :-) */
773                   c = iobuf_get (chain);
774                   a->size = c << 8;
775                   c = iobuf_get (chain);
776                   a->size |= c;
777                   if (c == -1)
778                     {
779                       log_error ("block_filter: error reading length info\n");
780                       rc = GPG_ERR_BAD_DATA;
781                     }
782                   if (!a->size)
783                     {
784                       a->eof = 1;
785                       if (!n)
786                         rc = -1;
787                       break;
788                     }
789                 }
790             }
791
792           while (!rc && size && a->size)
793             {
794               needed = size < a->size ? size : a->size;
795               c = iobuf_read (chain, p, needed);
796               if (c < needed)
797                 {
798                   if (c == -1)
799                     c = 0;
800                   log_error
801                     ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
802                      a, (ulong) size + c, (ulong) a->size + c);
803                   rc = GPG_ERR_BAD_DATA;
804                 }
805               else
806                 {
807                   size -= c;
808                   a->size -= c;
809                   p += c;
810                   n += c;
811                 }
812             }
813         }
814       *ret_len = n;
815     }
816   else if (control == IOBUFCTRL_FLUSH)
817     {
818       if (a->partial)
819         {                       /* the complicated openpgp scheme */
820           size_t blen, n, nbytes = size + a->buflen;
821
822           assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
823           if (nbytes < OP_MIN_PARTIAL_CHUNK)
824             {
825               /* not enough to write a partial block out; so we store it */
826               if (!a->buffer)
827                 a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
828               memcpy (a->buffer + a->buflen, buf, size);
829               a->buflen += size;
830             }
831           else
832             {                   /* okay, we can write out something */
833               /* do this in a loop to use the most efficient block lengths */
834               p = buf;
835               do
836                 {
837                   /* find the best matching block length - this is limited
838                    * by the size of the internal buffering */
839                   for (blen = OP_MIN_PARTIAL_CHUNK * 2,
840                        c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
841                        blen *= 2, c++)
842                     ;
843                   blen /= 2;
844                   c--;
845                   /* write the partial length header */
846                   assert (c <= 0x1f);   /*;-) */
847                   c |= 0xe0;
848                   iobuf_put (chain, c);
849                   if ((n = a->buflen))
850                     {           /* write stuff from the buffer */
851                       assert (n == OP_MIN_PARTIAL_CHUNK);
852                       if (iobuf_write (chain, a->buffer, n))
853                         rc = gpg_error_from_errno (errno);
854                       a->buflen = 0;
855                       nbytes -= n;
856                     }
857                   if ((n = nbytes) > blen)
858                     n = blen;
859                   if (n && iobuf_write (chain, p, n))
860                     rc = gpg_error_from_errno (errno);
861                   p += n;
862                   nbytes -= n;
863                 }
864               while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
865               /* store the rest in the buffer */
866               if (!rc && nbytes)
867                 {
868                   assert (!a->buflen);
869                   assert (nbytes < OP_MIN_PARTIAL_CHUNK);
870                   if (!a->buffer)
871                     a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
872                   memcpy (a->buffer, p, nbytes);
873                   a->buflen = nbytes;
874                 }
875             }
876         }
877       else
878         {                       /* the gnupg scheme (which is not openpgp compliant) */
879           size_t avail, n;
880
881           for (p = buf; !rc && size;)
882             {
883               n = size;
884               avail = a->size - a->count;
885               if (!avail)
886                 {
887                   if (n > a->size)
888                     {
889                       iobuf_put (chain, (a->size >> 8) & 0xff);
890                       iobuf_put (chain, a->size & 0xff);
891                       avail = a->size;
892                       a->count = 0;
893                     }
894                   else
895                     {
896                       iobuf_put (chain, (n >> 8) & 0xff);
897                       iobuf_put (chain, n & 0xff);
898                       avail = n;
899                       a->count = a->size - n;
900                     }
901                 }
902               if (n > avail)
903                 n = avail;
904               if (iobuf_write (chain, p, n))
905                 rc = gpg_error_from_errno (errno);
906               a->count += n;
907               p += n;
908               size -= n;
909             }
910         }
911     }
912   else if (control == IOBUFCTRL_INIT)
913     {
914       if (DBG_IOBUF)
915         log_debug ("init block_filter %p\n", a);
916       if (a->partial)
917         a->count = 0;
918       else if (a->use == 1)
919         a->count = a->size = 0;
920       else
921         a->count = a->size;     /* force first length bytes */
922       a->eof = 0;
923       a->buffer = NULL;
924       a->buflen = 0;
925     }
926   else if (control == IOBUFCTRL_DESC)
927     {
928       *(char **) buf = "block_filter";
929     }
930   else if (control == IOBUFCTRL_FREE)
931     {
932       if (a->use == 2)
933         {                       /* write the end markers */
934           if (a->partial)
935             {
936               u32 len;
937               /* write out the remaining bytes without a partial header
938                * the length of this header may be 0 - but if it is
939                * the first block we are not allowed to use a partial header
940                * and frankly we can't do so, because this length must be
941                * a power of 2. This is _really_ complicated because we
942                * have to check the possible length of a packet prior
943                * to it's creation: a chain of filters becomes complicated
944                * and we need a lot of code to handle compressed packets etc.
945                *   :-(((((((
946                */
947               /* construct header */
948               len = a->buflen;
949               /*log_debug("partial: remaining length=%u\n", len ); */
950               if (len < 192)
951                 rc = iobuf_put (chain, len);
952               else if (len < 8384)
953                 {
954                   if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
955                     rc = iobuf_put (chain, ((len - 192) % 256));
956                 }
957               else
958                 {               /* use a 4 byte header */
959                   if (!(rc = iobuf_put (chain, 0xff)))
960                     if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
961                       if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
962                         if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
963                           rc = iobuf_put (chain, len & 0xff);
964                 }
965               if (!rc && len)
966                 rc = iobuf_write (chain, a->buffer, len);
967               if (rc)
968                 {
969                   log_error ("block_filter: write error: %s\n",
970                              strerror (errno));
971                   rc = gpg_error_from_errno (errno);
972                 }
973               xfree (a->buffer);
974               a->buffer = NULL;
975               a->buflen = 0;
976             }
977           else
978             {
979               iobuf_writebyte (chain, 0);
980               iobuf_writebyte (chain, 0);
981             }
982         }
983       else if (a->size)
984         {
985           log_error ("block_filter: pending bytes!\n");
986         }
987       if (DBG_IOBUF)
988         log_debug ("free block_filter %p\n", a);
989       xfree (a);                /* we can free our context now */
990     }
991
992   return rc;
993 }
994
995
996 static void
997 print_chain (iobuf_t a)
998 {
999   if (!DBG_IOBUF)
1000     return;
1001   for (; a; a = a->chain)
1002     {
1003       size_t dummy_len = 0;
1004       const char *desc = "[none]";
1005
1006       if (a->filter)
1007         a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
1008                    (byte *) & desc, &dummy_len);
1009
1010       log_debug ("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n",
1011                  a->no, a->subno, desc, a->filter_eof,
1012                  (int) a->d.start, (int) a->d.len);
1013     }
1014 }
1015
1016 int
1017 iobuf_print_chain (iobuf_t a)
1018 {
1019   print_chain (a);
1020   return 0;
1021 }
1022
1023 /****************
1024  * Allocate a new io buffer, with no function assigned.
1025  * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer
1026  * BUFSIZE is a suggested buffer size.
1027  */
1028 iobuf_t
1029 iobuf_alloc (int use, size_t bufsize)
1030 {
1031   iobuf_t a;
1032   static int number = 0;
1033
1034   a = xcalloc (1, sizeof *a);
1035   a->use = use;
1036   a->d.buf = xmalloc (bufsize);
1037   a->d.size = bufsize;
1038   a->no = ++number;
1039   a->subno = 0;
1040   a->opaque = NULL;
1041   a->real_fname = NULL;
1042   return a;
1043 }
1044
1045 int
1046 iobuf_close (iobuf_t a)
1047 {
1048   iobuf_t a2;
1049   size_t dummy_len = 0;
1050   int rc = 0;
1051
1052   if (a && a->directfp)
1053     {
1054       fclose (a->directfp);
1055       xfree (a->real_fname);
1056       if (DBG_IOBUF)
1057         log_debug ("iobuf_close -> %p\n", a->directfp);
1058       return 0;
1059     }
1060
1061   for (; a && !rc; a = a2)
1062     {
1063       a2 = a->chain;
1064       if (a->use == 2 && (rc = iobuf_flush (a)))
1065         log_error ("iobuf_flush failed on close: %s\n", gpg_strerror (rc));
1066
1067       if (DBG_IOBUF)
1068         log_debug ("iobuf-%d.%d: close `%s'\n", a->no, a->subno, a->desc);
1069       if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1070                                         a->chain, NULL, &dummy_len)))
1071         log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1072       xfree (a->real_fname);
1073       if (a->d.buf)
1074         {
1075           memset (a->d.buf, 0, a->d.size);      /* erase the buffer */
1076           xfree (a->d.buf);
1077         }
1078       xfree (a);
1079     }
1080   return rc;
1081 }
1082
1083 int
1084 iobuf_cancel (iobuf_t a)
1085 {
1086   const char *s;
1087   iobuf_t a2;
1088   int rc;
1089 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1090   char *remove_name = NULL;
1091 #endif
1092
1093   if (a && a->use == 2)
1094     {
1095       s = iobuf_get_real_fname (a);
1096       if (s && *s)
1097         {
1098 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1099           remove_name = m_strdup (s);
1100 #else
1101           remove (s);
1102 #endif
1103         }
1104     }
1105
1106   /* send a cancel message to all filters */
1107   for (a2 = a; a2; a2 = a2->chain)
1108     {
1109       size_t dummy;
1110       if (a2->filter)
1111         a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1112     }
1113
1114   rc = iobuf_close (a);
1115 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1116   if (remove_name)
1117     {
1118       /* Argg, MSDOS does not allow to remove open files.  So
1119        * we have to do it here */
1120       remove (remove_name);
1121       xfree (remove_name);
1122     }
1123 #endif
1124   return rc;
1125 }
1126
1127
1128 /****************
1129  * create a temporary iobuf, which can be used to collect stuff
1130  * in an iobuf and later be written by iobuf_write_temp() to another
1131  * iobuf.
1132  */
1133 iobuf_t
1134 iobuf_temp ()
1135 {
1136   iobuf_t a;
1137
1138   a = iobuf_alloc (3, 8192);
1139
1140   return a;
1141 }
1142
1143 iobuf_t
1144 iobuf_temp_with_content (const char *buffer, size_t length)
1145 {
1146   iobuf_t a;
1147
1148   a = iobuf_alloc (3, length);
1149   memcpy (a->d.buf, buffer, length);
1150   a->d.len = length;
1151
1152   return a;
1153 }
1154
1155 void
1156 iobuf_enable_special_filenames (int yes)
1157 {
1158   special_names_enabled = yes;
1159 }
1160
1161 /*
1162  * see whether the filename has the for "-&nnnn", where n is a
1163  * non-zero number.
1164  * Returns this number or -1 if it is not the case.
1165  */
1166 static int
1167 check_special_filename (const char *fname)
1168 {
1169   if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
1170     {
1171       int i;
1172
1173       fname += 2;
1174       for (i = 0; digitp (fname+i); i++)
1175         ;
1176       if (!fname[i])
1177         return atoi (fname);
1178     }
1179   return -1;
1180 }
1181
1182 /****************
1183  * Create a head iobuf for reading from a file
1184  * returns: NULL if an error occures and sets errno
1185  */
1186 iobuf_t
1187 iobuf_open (const char *fname)
1188 {
1189   iobuf_t a;
1190   FILEP_OR_FD fp;
1191   file_filter_ctx_t *fcx;
1192   size_t len;
1193   int print_only = 0;
1194   int fd;
1195
1196   if (!fname || (*fname == '-' && !fname[1]))
1197     {
1198       fp = FILEP_OR_FD_FOR_STDIN;
1199 #ifdef USE_SETMODE
1200       setmode (my_fileno (fp), O_BINARY);
1201 #endif
1202       fname = "[stdin]";
1203       print_only = 1;
1204     }
1205   else if ((fd = check_special_filename (fname)) != -1)
1206     return iobuf_fdopen (translate_file_handle (fd, 0), "rb");
1207   else if ((fp = my_fopen_ro (fname, "rb")) == INVALID_FP)
1208     return NULL;
1209   a = iobuf_alloc (1, 8192);
1210   fcx = xmalloc (sizeof *fcx + strlen (fname));
1211   fcx->fp = fp;
1212   fcx->print_only_name = print_only;
1213   strcpy (fcx->fname, fname);
1214   if (!print_only)
1215     a->real_fname = xstrdup (fname);
1216   a->filter = file_filter;
1217   a->filter_ov = fcx;
1218   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1219   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1220   if (DBG_IOBUF)
1221     log_debug ("iobuf-%d.%d: open `%s' fd=%d\n",
1222                a->no, a->subno, fname, (int) my_fileno (fcx->fp));
1223
1224   return a;
1225 }
1226
1227 /****************
1228  * Create a head iobuf for reading from a file
1229  * returns: NULL if an error occures and sets errno
1230  */
1231 iobuf_t
1232 iobuf_fdopen (int fd, const char *mode)
1233 {
1234   iobuf_t a;
1235   FILEP_OR_FD fp;
1236   file_filter_ctx_t *fcx;
1237   size_t len;
1238
1239 #ifdef FILE_FILTER_USES_STDIO
1240   if (!(fp = fdopen (fd, mode)))
1241     return NULL;
1242 #else
1243   fp = (FILEP_OR_FD) fd;
1244 #endif
1245   a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192);
1246   fcx = xmalloc (sizeof *fcx + 20);
1247   fcx->fp = fp;
1248   fcx->print_only_name = 1;
1249   sprintf (fcx->fname, "[fd %d]", fd);
1250   a->filter = file_filter;
1251   a->filter_ov = fcx;
1252   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1253   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1254   if (DBG_IOBUF)
1255     log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname);
1256   iobuf_ioctl (a, 3, 1, NULL);  /* disable fd caching */
1257   return a;
1258 }
1259
1260
1261 iobuf_t
1262 iobuf_sockopen (int fd, const char *mode)
1263 {
1264   iobuf_t a;
1265 #ifdef _WIN32
1266   sock_filter_ctx_t *scx;
1267   size_t len;
1268
1269   a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192);
1270   scx = m_alloc (sizeof *scx + 25);
1271   scx->sock = fd;
1272   scx->print_only_name = 1;
1273   sprintf (scx->fname, "[sock %d]", fd);
1274   a->filter = sock_filter;
1275   a->filter_ov = scx;
1276   sock_filter (scx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1277   sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1278   if (DBG_IOBUF)
1279     log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
1280   iobuf_ioctl (a, 3, 1, NULL);  /* disable fd caching */
1281 #else
1282   a = iobuf_fdopen (fd, mode);
1283 #endif
1284   return a;
1285 }
1286
1287 /****************
1288  * create an iobuf for writing to a file; the file will be created.
1289  */
1290 iobuf_t
1291 iobuf_create (const char *fname)
1292 {
1293   iobuf_t a;
1294   FILEP_OR_FD fp;
1295   file_filter_ctx_t *fcx;
1296   size_t len;
1297   int print_only = 0;
1298   int fd;
1299
1300   if (!fname || (*fname == '-' && !fname[1]))
1301     {
1302       fp = FILEP_OR_FD_FOR_STDOUT;
1303 #ifdef USE_SETMODE
1304       setmode (my_fileno (fp), O_BINARY);
1305 #endif
1306       fname = "[stdout]";
1307       print_only = 1;
1308     }
1309   else if ((fd = check_special_filename (fname)) != -1)
1310     return iobuf_fdopen (translate_file_handle (fd, 1), "wb");
1311   else if ((fp = my_fopen (fname, "wb")) == INVALID_FP)
1312     return NULL;
1313   a = iobuf_alloc (2, 8192);
1314   fcx = xmalloc (sizeof *fcx + strlen (fname));
1315   fcx->fp = fp;
1316   fcx->print_only_name = print_only;
1317   strcpy (fcx->fname, fname);
1318   if (!print_only)
1319     a->real_fname = xstrdup (fname);
1320   a->filter = file_filter;
1321   a->filter_ov = fcx;
1322   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1323   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1324   if (DBG_IOBUF)
1325     log_debug ("iobuf-%d.%d: create `%s'\n", a->no, a->subno, a->desc);
1326
1327   return a;
1328 }
1329
1330 /****************
1331  * append to an iobuf; if the file does not exist, create it.
1332  * cannot be used for stdout.
1333  * Note: This is not used.
1334  */
1335 #if 0                           /* not used */
1336 iobuf_t
1337 iobuf_append (const char *fname)
1338 {
1339   iobuf_t a;
1340   FILE *fp;
1341   file_filter_ctx_t *fcx;
1342   size_t len;
1343
1344   if (!fname)
1345     return NULL;
1346   else if (!(fp = my_fopen (fname, "ab")))
1347     return NULL;
1348   a = iobuf_alloc (2, 8192);
1349   fcx = m_alloc (sizeof *fcx + strlen (fname));
1350   fcx->fp = fp;
1351   strcpy (fcx->fname, fname);
1352   a->real_fname = m_strdup (fname);
1353   a->filter = file_filter;
1354   a->filter_ov = fcx;
1355   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1356   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1357   if (DBG_IOBUF)
1358     log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno, a->desc);
1359
1360   return a;
1361 }
1362 #endif
1363
1364 iobuf_t
1365 iobuf_openrw (const char *fname)
1366 {
1367   iobuf_t a;
1368   FILEP_OR_FD fp;
1369   file_filter_ctx_t *fcx;
1370   size_t len;
1371
1372   if (!fname)
1373     return NULL;
1374   else if ((fp = my_fopen (fname, "r+b")) == INVALID_FP)
1375     return NULL;
1376   a = iobuf_alloc (2, 8192);
1377   fcx = xmalloc (sizeof *fcx + strlen (fname));
1378   fcx->fp = fp;
1379   strcpy (fcx->fname, fname);
1380   a->real_fname = xstrdup (fname);
1381   a->filter = file_filter;
1382   a->filter_ov = fcx;
1383   file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1384   file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1385   if (DBG_IOBUF)
1386     log_debug ("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, a->desc);
1387
1388   return a;
1389 }
1390
1391
1392 int
1393 iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
1394 {
1395   if (cmd == 1)
1396     {                           /* keep system filepointer/descriptor open */
1397       if (DBG_IOBUF)
1398         log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n",
1399                    a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?",
1400                    intval);
1401       for (; a; a = a->chain)
1402         if (!a->chain && a->filter == file_filter)
1403           {
1404             file_filter_ctx_t *b = a->filter_ov;
1405             b->keep_open = intval;
1406             return 0;
1407           }
1408 #ifdef _WIN32
1409         else if (!a->chain && a->filter == sock_filter)
1410           {
1411             sock_filter_ctx_t *b = a->filter_ov;
1412             b->keep_open = intval;
1413             return 0;
1414           }
1415 #endif
1416     }
1417   else if (cmd == 2)
1418     {                           /* invalidate cache */
1419       if (DBG_IOBUF)
1420         log_debug ("iobuf-*.*: ioctl `%s' invalidate\n",
1421                    ptrval ? (char *) ptrval : "?");
1422       if (!a && !intval && ptrval)
1423         {
1424 #ifndef FILE_FILTER_USES_STDIO
1425           fd_cache_invalidate (ptrval);
1426 #endif
1427           return 0;
1428         }
1429     }
1430   else if (cmd == 3)
1431     {                           /* disallow/allow caching */
1432       if (DBG_IOBUF)
1433         log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
1434                    a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?",
1435                    intval);
1436       for (; a; a = a->chain)
1437         if (!a->chain && a->filter == file_filter)
1438           {
1439             file_filter_ctx_t *b = a->filter_ov;
1440             b->no_cache = intval;
1441             return 0;
1442           }
1443 #ifdef _WIN32
1444         else if (!a->chain && a->filter == sock_filter)
1445           {
1446             sock_filter_ctx_t *b = a->filter_ov;
1447             b->no_cache = intval;
1448             return 0;
1449           }
1450 #endif
1451     }
1452
1453   return -1;
1454 }
1455
1456
1457 /****************
1458  * Register an i/o filter.
1459  */
1460 int
1461 iobuf_push_filter (iobuf_t a,
1462                    int (*f) (void *opaque, int control,
1463                              iobuf_t chain, byte * buf, size_t * len),
1464                    void *ov)
1465 {
1466   return iobuf_push_filter2 (a, f, ov, 0);
1467 }
1468
1469 int
1470 iobuf_push_filter2 (iobuf_t a,
1471                     int (*f) (void *opaque, int control,
1472                               iobuf_t chain, byte * buf, size_t * len),
1473                     void *ov, int rel_ov)
1474 {
1475   iobuf_t b;
1476   size_t dummy_len = 0;
1477   int rc = 0;
1478
1479   if (a->directfp)
1480     BUG ();
1481
1482   if (a->use == 2 && (rc = iobuf_flush (a)))
1483     return rc;
1484   /* make a copy of the current stream, so that
1485    * A is the new stream and B the original one.
1486    * The contents of the buffers are transferred to the
1487    * new stream.
1488    */
1489   b = xmalloc (sizeof *b);
1490   memcpy (b, a, sizeof *b);
1491   /* fixme: it is stupid to keep a copy of the name at every level
1492    * but we need the name somewhere because the name known by file_filter
1493    * may have been released when we need the name of the file */
1494   b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1495   /* remove the filter stuff from the new stream */
1496   a->filter = NULL;
1497   a->filter_ov = NULL;
1498   a->filter_ov_owner = 0;
1499   a->filter_eof = 0;
1500   if (a->use == 3)
1501     a->use = 2;                 /* make a write stream from a temp stream */
1502
1503   if (a->use == 2)
1504     {                           /* allocate a fresh buffer for the
1505                                    original stream */
1506       b->d.buf = xmalloc (a->d.size);
1507       b->d.len = 0;
1508       b->d.start = 0;
1509     }
1510   else
1511     {                           /* allocate a fresh buffer for the new
1512                                    stream */
1513       a->d.buf = xmalloc (a->d.size);
1514       a->d.len = 0;
1515       a->d.start = 0;
1516     }
1517   /* disable nlimit for the new stream */
1518   a->ntotal = b->ntotal + b->nbytes;
1519   a->nlimit = a->nbytes = 0;
1520   a->nofast &= ~1;
1521   /* make a link from the new stream to the original stream */
1522   a->chain = b;
1523   a->opaque = b->opaque;
1524
1525   /* setup the function on the new stream */
1526   a->filter = f;
1527   a->filter_ov = ov;
1528   a->filter_ov_owner = rel_ov;
1529
1530   a->subno = b->subno + 1;
1531   f (ov, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &dummy_len);
1532
1533   if (DBG_IOBUF)
1534     {
1535       log_debug ("iobuf-%d.%d: push `%s'\n", a->no, a->subno, a->desc);
1536       print_chain (a);
1537     }
1538
1539   /* now we can initialize the new function if we have one */
1540   if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1541                                     NULL, &dummy_len)))
1542     log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1543   return rc;
1544 }
1545
1546 /****************
1547  * Remove an i/o filter.
1548  */
1549 int
1550 pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1551                                iobuf_t chain, byte * buf, size_t * len),
1552             void *ov)
1553 {
1554   iobuf_t b;
1555   size_t dummy_len = 0;
1556   int rc = 0;
1557
1558   if (a->directfp)
1559     BUG ();
1560
1561   if (DBG_IOBUF)
1562     log_debug ("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, a->desc);
1563   if (!a->filter)
1564     {                           /* this is simple */
1565       b = a->chain;
1566       assert (b);
1567       xfree (a->d.buf);
1568       xfree (a->real_fname);
1569       memcpy (a, b, sizeof *a);
1570       xfree (b);
1571       return 0;
1572     }
1573   for (b = a; b; b = b->chain)
1574     if (b->filter == f && (!ov || b->filter_ov == ov))
1575       break;
1576   if (!b)
1577     log_bug ("pop_filter(): filter function not found\n");
1578
1579   /* flush this stream if it is an output stream */
1580   if (a->use == 2 && (rc = iobuf_flush (b)))
1581     {
1582       log_error ("iobuf_flush failed in pop_filter: %s\n", gpg_strerror (rc));
1583       return rc;
1584     }
1585   /* and tell the filter to free it self */
1586   if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1587                                     NULL, &dummy_len)))
1588     {
1589       log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1590       return rc;
1591     }
1592   if (b->filter_ov && b->filter_ov_owner)
1593     {
1594       xfree (b->filter_ov);
1595       b->filter_ov = NULL;
1596     }
1597
1598
1599   /* and see how to remove it */
1600   if (a == b && !b->chain)
1601     log_bug ("can't remove the last filter from the chain\n");
1602   else if (a == b)
1603     {                           /* remove the first iobuf from the chain */
1604       /* everything from b is copied to a. This is save because
1605        * a flush has been done on the to be removed entry
1606        */
1607       b = a->chain;
1608       xfree (a->d.buf);
1609       xfree (a->real_fname);
1610       memcpy (a, b, sizeof *a);
1611       xfree (b);
1612       if (DBG_IOBUF)
1613         log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1614     }
1615   else if (!b->chain)
1616     {                           /* remove the last iobuf from the chain */
1617       log_bug ("Ohh jeee, trying to remove a head filter\n");
1618     }
1619   else
1620     {                           /* remove an intermediate iobuf from the chain */
1621       log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1622     }
1623
1624   return rc;
1625 }
1626
1627
1628 /****************
1629  * read underflow: read more bytes into the buffer and return
1630  * the first byte or -1 on EOF.
1631  */
1632 static int
1633 underflow (iobuf_t a)
1634 {
1635   size_t len;
1636   int rc;
1637
1638   assert (a->d.start == a->d.len);
1639   if (a->use == 3)
1640     return -1;                  /* EOF because a temp buffer can't do an underflow */
1641
1642   if (a->filter_eof)
1643     {
1644       if (a->chain)
1645         {
1646           iobuf_t b = a->chain;
1647           if (DBG_IOBUF)
1648             log_debug ("iobuf-%d.%d: pop `%s' in underflow\n",
1649                        a->no, a->subno, a->desc);
1650           xfree (a->d.buf);
1651           xfree (a->real_fname);
1652           memcpy (a, b, sizeof *a);
1653           xfree (b);
1654           print_chain (a);
1655         }
1656       else
1657         a->filter_eof = 0;      /* for the top level filter */
1658       if (DBG_IOBUF)
1659         log_debug ("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
1660                    a->no, a->subno);
1661       return -1;                /* return one(!) EOF */
1662     }
1663   if (a->error)
1664     {
1665       if (DBG_IOBUF)
1666         log_debug ("iobuf-%d.%d: error\n", a->no, a->subno);
1667       return -1;
1668     }
1669
1670   if (a->directfp)
1671     {
1672       FILE *fp = a->directfp;
1673
1674       len = fread (a->d.buf, 1, a->d.size, fp);
1675       if (len < a->d.size)
1676         {
1677           if (ferror (fp))
1678             a->error = gpg_error_from_errno (errno);
1679         }
1680       a->d.len = len;
1681       a->d.start = 0;
1682       return len ? a->d.buf[a->d.start++] : -1;
1683     }
1684
1685
1686   if (a->filter)
1687     {
1688       len = a->d.size;
1689       if (DBG_IOBUF)
1690         log_debug ("iobuf-%d.%d: underflow: req=%lu\n",
1691                    a->no, a->subno, (ulong) len);
1692       rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1693                       a->d.buf, &len);
1694       if (DBG_IOBUF)
1695         {
1696           log_debug ("iobuf-%d.%d: underflow: got=%lu rc=%d\n",
1697                      a->no, a->subno, (ulong) len, rc);
1698 /*          if( a->no == 1 ) */
1699 /*                   log_hexdump ("     data:", a->d.buf, len); */
1700         }
1701       if (a->use == 1 && rc == -1)
1702         {                       /* EOF: we can remove the filter */
1703           size_t dummy_len = 0;
1704
1705           /* and tell the filter to free itself */
1706           if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
1707                                NULL, &dummy_len)))
1708             log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1709           if (a->filter_ov && a->filter_ov_owner)
1710             {
1711               xfree (a->filter_ov);
1712               a->filter_ov = NULL;
1713             }
1714           a->filter = NULL;
1715           a->desc = NULL;
1716           a->filter_ov = NULL;
1717           a->filter_eof = 1;
1718           if (!len && a->chain)
1719             {
1720               iobuf_t b = a->chain;
1721               if (DBG_IOBUF)
1722                 log_debug ("iobuf-%d.%d: pop `%s' in underflow (!len)\n",
1723                            a->no, a->subno, a->desc);
1724               xfree (a->d.buf);
1725               xfree (a->real_fname);
1726               memcpy (a, b, sizeof *a);
1727               xfree (b);
1728               print_chain (a);
1729             }
1730         }
1731       else if (rc)
1732         a->error = rc;
1733
1734       if (!len)
1735         {
1736           if (DBG_IOBUF)
1737             log_debug ("iobuf-%d.%d: underflow: eof\n", a->no, a->subno);
1738           return -1;
1739         }
1740       a->d.len = len;
1741       a->d.start = 0;
1742       return a->d.buf[a->d.start++];
1743     }
1744   else
1745     {
1746       if (DBG_IOBUF)
1747         log_debug ("iobuf-%d.%d: underflow: eof (no filter)\n",
1748                    a->no, a->subno);
1749       return -1;                /* no filter; return EOF */
1750     }
1751 }
1752
1753
1754 int
1755 iobuf_flush (iobuf_t a)
1756 {
1757   size_t len;
1758   int rc;
1759
1760   if (a->directfp)
1761     return 0;
1762
1763   if (a->use == 3)
1764     {                           /* increase the temp buffer */
1765       char *newbuf;
1766       size_t newsize = a->d.size + 8192;
1767
1768       if (DBG_IOBUF)
1769         log_debug ("increasing temp iobuf from %lu to %lu\n",
1770                    (ulong) a->d.size, (ulong) newsize);
1771       newbuf = xmalloc (newsize);
1772       memcpy (newbuf, a->d.buf, a->d.len);
1773       xfree (a->d.buf);
1774       a->d.buf = newbuf;
1775       a->d.size = newsize;
1776       return 0;
1777     }
1778   else if (a->use != 2)
1779     log_bug ("flush on non-output iobuf\n");
1780   else if (!a->filter)
1781     log_bug ("iobuf_flush: no filter\n");
1782   len = a->d.len;
1783   rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
1784   if (!rc && len != a->d.len)
1785     {
1786       log_info ("iobuf_flush did not write all!\n");
1787       rc = GPG_ERR_INTERNAL;
1788     }
1789   else if (rc)
1790     a->error = rc;
1791   a->d.len = 0;
1792
1793   return rc;
1794 }
1795
1796
1797 /****************
1798  * Read a byte from the iobuf; returns -1 on EOF
1799  */
1800 int
1801 iobuf_readbyte (iobuf_t a)
1802 {
1803   int c;
1804
1805   /* nlimit does not work together with unget */
1806   /* nbytes is also not valid! */
1807   if (a->unget.buf)
1808     {
1809       if (a->unget.start < a->unget.len)
1810         return a->unget.buf[a->unget.start++];
1811       xfree (a->unget.buf);
1812       a->unget.buf = NULL;
1813       a->nofast &= ~2;
1814     }
1815
1816   if (a->nlimit && a->nbytes >= a->nlimit)
1817     return -1;                  /* forced EOF */
1818
1819   if (a->d.start < a->d.len)
1820     {
1821       c = a->d.buf[a->d.start++];
1822     }
1823   else if ((c = underflow (a)) == -1)
1824     return -1;                  /* EOF */
1825
1826   a->nbytes++;
1827   return c;
1828 }
1829
1830
1831 int
1832 iobuf_read (iobuf_t a, byte * buf, unsigned buflen)
1833 {
1834   int c, n;
1835
1836   if (a->unget.buf || a->nlimit)
1837     {
1838       /* handle special cases */
1839       for (n = 0; n < buflen; n++)
1840         {
1841           if ((c = iobuf_readbyte (a)) == -1)
1842             {
1843               if (!n)
1844                 return -1;      /* eof */
1845               break;
1846             }
1847           else if (buf)
1848             *buf = c;
1849           if (buf)
1850             buf++;
1851         }
1852       return n;
1853     }
1854
1855   n = 0;
1856   do
1857     {
1858       if (n < buflen && a->d.start < a->d.len)
1859         {
1860           unsigned size = a->d.len - a->d.start;
1861           if (size > buflen - n)
1862             size = buflen - n;
1863           if (buf)
1864             memcpy (buf, a->d.buf + a->d.start, size);
1865           n += size;
1866           a->d.start += size;
1867           if (buf)
1868             buf += size;
1869         }
1870       if (n < buflen)
1871         {
1872           if ((c = underflow (a)) == -1)
1873             {
1874               a->nbytes += n;
1875               return n ? n : -1 /*EOF*/;
1876             }
1877           if (buf)
1878             *buf++ = c;
1879           n++;
1880         }
1881     }
1882   while (n < buflen);
1883   a->nbytes += n;
1884   return n;
1885 }
1886
1887
1888 /****************
1889  * Have a look at the iobuf.
1890  * NOTE: This only works in special cases.
1891  */
1892 int
1893 iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
1894 {
1895   int n = 0;
1896
1897   if (a->filter_eof)
1898     return -1;
1899
1900   if (!(a->d.start < a->d.len))
1901     {
1902       if (underflow (a) == -1)
1903         return -1;
1904       /* and unget this character */
1905       assert (a->d.start == 1);
1906       a->d.start = 0;
1907     }
1908
1909   for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++)
1910     *buf = a->d.buf[n];
1911   return n;
1912 }
1913
1914
1915
1916
1917 int
1918 iobuf_writebyte (iobuf_t a, unsigned c)
1919 {
1920   int rc;
1921
1922   if (a->directfp)
1923     BUG ();
1924
1925   if (a->d.len == a->d.size)
1926     if ((rc=iobuf_flush (a)))
1927       return rc;
1928
1929   assert (a->d.len < a->d.size);
1930   a->d.buf[a->d.len++] = c;
1931   return 0;
1932 }
1933
1934
1935 int
1936 iobuf_write (iobuf_t a, byte * buf, unsigned buflen)
1937 {
1938   int rc;
1939
1940   if (a->directfp)
1941     BUG ();
1942
1943   do
1944     {
1945       if (buflen && a->d.len < a->d.size)
1946         {
1947           unsigned size = a->d.size - a->d.len;
1948           if (size > buflen)
1949             size = buflen;
1950           memcpy (a->d.buf + a->d.len, buf, size);
1951           buflen -= size;
1952           buf += size;
1953           a->d.len += size;
1954         }
1955       if (buflen)
1956         {
1957           rc = iobuf_flush (a);
1958           if (rc)
1959             return rc;
1960         }
1961     }
1962   while (buflen);
1963   return 0;
1964 }
1965
1966
1967 int
1968 iobuf_writestr (iobuf_t a, const char *buf)
1969 {
1970   int rc;
1971
1972   for (; *buf; buf++)
1973     if ((rc=iobuf_writebyte (a, *buf)))
1974       return rc;
1975   return 0;
1976 }
1977
1978
1979
1980 /****************
1981  * copy the contents of TEMP to A.
1982  */
1983 int
1984 iobuf_write_temp (iobuf_t a, iobuf_t temp)
1985 {
1986   while (temp->chain)
1987     pop_filter (temp, temp->filter, NULL);
1988   return iobuf_write (a, temp->d.buf, temp->d.len);
1989 }
1990
1991 /****************
1992  * copy the contents of the temp io stream to BUFFER.
1993  */
1994 size_t
1995 iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
1996 {
1997   size_t n = a->d.len;
1998
1999   if (n > buflen)
2000     n = buflen;
2001   memcpy (buffer, a->d.buf, n);
2002   return n;
2003 }
2004
2005
2006 /****************
2007  * Call this function to terminate processing of the temp stream
2008  * without closing it.  This removes all filters from the stream
2009  * makes sure that iobuf_get_temp_{buffer,length}() returns correct
2010  * values.
2011  */
2012 void
2013 iobuf_flush_temp (iobuf_t temp)
2014 {
2015   while (temp->chain)
2016     pop_filter (temp, temp->filter, NULL);
2017 }
2018
2019
2020 /****************
2021  * Set a limit on how many bytes may be read from the input stream A.
2022  * Setting the limit to 0 disables this feature.
2023  */
2024 void
2025 iobuf_set_limit (iobuf_t a, off_t nlimit)
2026 {
2027   if (nlimit)
2028     a->nofast |= 1;
2029   else
2030     a->nofast &= ~1;
2031   a->nlimit = nlimit;
2032   a->ntotal += a->nbytes;
2033   a->nbytes = 0;
2034 }
2035
2036
2037
2038 /****************
2039  * Return the length of an open file
2040  */
2041 off_t
2042 iobuf_get_filelength (iobuf_t a)
2043 {
2044   struct stat st;
2045
2046   if (a->directfp)
2047     {
2048       FILE *fp = a->directfp;
2049
2050       if (!fstat (fileno (fp), &st))
2051         return st.st_size;
2052       log_error ("fstat() failed: %s\n", strerror (errno));
2053       return 0;
2054     }
2055
2056   /* Hmmm: file_filter may have already been removed */
2057   for (; a; a = a->chain)
2058     if (!a->chain && a->filter == file_filter)
2059       {
2060         file_filter_ctx_t *b = a->filter_ov;
2061         FILEP_OR_FD fp = b->fp;
2062
2063 #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
2064         ulong size;
2065
2066         if ((size = GetFileSize (fp, NULL)) != 0xffffffff)
2067           return size;
2068         log_error ("GetFileSize for handle %p failed: ec=%d\n",
2069                    fp, (int) GetLastError ());
2070 #else
2071         if (!fstat (my_fileno (fp), &st))
2072           return st.st_size;
2073         log_error ("fstat() failed: %s\n", strerror (errno));
2074 #endif
2075         break;
2076       }
2077
2078   return 0;
2079 }
2080
2081 /****************
2082  * Tell the file position, where the next read will take place
2083  */
2084 off_t
2085 iobuf_tell (iobuf_t a)
2086 {
2087   return a->ntotal + a->nbytes;
2088 }
2089
2090
2091 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2092
2093 #ifdef HAVE_LIMITS_H
2094 # include <limits.h>
2095 #endif
2096 #ifndef LONG_MAX
2097 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2098 #endif
2099 #ifndef LONG_MIN
2100 # define LONG_MIN (-1 - LONG_MAX)
2101 #endif
2102
2103 /****************
2104  * A substitute for fseeko, for hosts that don't have it.
2105  */
2106 static int
2107 fseeko (FILE * stream, off_t newpos, int whence)
2108 {
2109   while (newpos != (long) newpos)
2110     {
2111       long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2112       if (fseek (stream, pos, whence) != 0)
2113         return -1;
2114       newpos -= pos;
2115       whence = SEEK_CUR;
2116     }
2117   return fseek (stream, (long) newpos, whence);
2118 }
2119 #endif
2120
2121 /****************
2122  * This is a very limited implementation. It simply discards all internal
2123  * buffering and removes all filters but the first one.
2124  */
2125 int
2126 iobuf_seek (iobuf_t a, off_t newpos)
2127 {
2128   file_filter_ctx_t *b = NULL;
2129
2130   if (a->directfp)
2131     {
2132       FILE *fp = a->directfp;
2133       if (fseeko (fp, newpos, SEEK_SET))
2134         {
2135           log_error ("can't seek: %s\n", strerror (errno));
2136           return -1;
2137         }
2138       clearerr (fp);
2139     }
2140   else
2141     {
2142       for (; a; a = a->chain)
2143         {
2144           if (!a->chain && a->filter == file_filter)
2145             {
2146               b = a->filter_ov;
2147               break;
2148             }
2149         }
2150       if (!a)
2151         return -1;
2152 #ifdef FILE_FILTER_USES_STDIO
2153       if (fseeko (b->fp, newpos, SEEK_SET))
2154         {
2155           log_error ("can't fseek: %s\n", strerror (errno));
2156           return -1;
2157         }
2158 #else
2159 #ifdef HAVE_DOSISH_SYSTEM
2160       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2161         {
2162           log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2163                      b->fp, (int) GetLastError ());
2164           return -1;
2165         }
2166 #else
2167       if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2168         {
2169           log_error ("can't lseek: %s\n", strerror (errno));
2170           return -1;
2171         }
2172 #endif
2173 #endif
2174     }
2175   a->d.len = 0;                 /* discard buffer */
2176   a->d.start = 0;
2177   a->nbytes = 0;
2178   a->nlimit = 0;
2179   a->nofast &= ~1;
2180   a->ntotal = newpos;
2181   a->error = 0;
2182   /* remove filters, but the last */
2183   if (a->chain)
2184     log_debug ("pop_filter called in iobuf_seek - please report\n");
2185   while (a->chain)
2186     pop_filter (a, a->filter, NULL);
2187
2188   return 0;
2189 }
2190
2191
2192
2193
2194
2195
2196 /****************
2197  * Retrieve the real filename
2198  */
2199 const char *
2200 iobuf_get_real_fname (iobuf_t a)
2201 {
2202   if (a->real_fname)
2203     return a->real_fname;
2204
2205   /* the old solution */
2206   for (; a; a = a->chain)
2207     if (!a->chain && a->filter == file_filter)
2208       {
2209         file_filter_ctx_t *b = a->filter_ov;
2210         return b->print_only_name ? NULL : b->fname;
2211       }
2212
2213   return NULL;
2214 }
2215
2216
2217 /****************
2218  * Retrieve the filename
2219  */
2220 const char *
2221 iobuf_get_fname (iobuf_t a)
2222 {
2223   for (; a; a = a->chain)
2224     if (!a->chain && a->filter == file_filter)
2225       {
2226         file_filter_ctx_t *b = a->filter_ov;
2227         return b->fname;
2228       }
2229
2230   return NULL;
2231 }
2232
2233 /****************
2234  * Start the block write mode, see rfc1991.new for details.
2235  * A value of 0 for N stops this mode (flushes and writes
2236  * the end marker)
2237  */
2238 void
2239 iobuf_set_block_mode (iobuf_t a, size_t n)
2240 {
2241   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2242
2243   assert (a->use == 1 || a->use == 2);
2244   ctx->use = a->use;
2245   if (!n)
2246     {
2247       if (a->use == 1)
2248         log_debug ("pop_filter called in set_block_mode - please report\n");
2249       pop_filter (a, block_filter, NULL);
2250     }
2251   else
2252     {
2253       ctx->size = n;            /* only needed for use 2 */
2254       iobuf_push_filter (a, block_filter, ctx);
2255     }
2256 }
2257
2258 /****************
2259  * enable partial block mode as described in the OpenPGP draft.
2260  * LEN is the first length byte on read, but ignored on writes.
2261  */
2262 void
2263 iobuf_set_partial_block_mode (iobuf_t a, size_t len)
2264 {
2265   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2266
2267   assert (a->use == 1 || a->use == 2);
2268   ctx->use = a->use;
2269   if (!len)
2270     {
2271       if (a->use == 1)
2272         log_debug ("pop_filter called in set_partial_block_mode"
2273                    " - please report\n");
2274       pop_filter (a, block_filter, NULL);
2275     }
2276   else
2277     {
2278       ctx->partial = 1;
2279       ctx->size = 0;
2280       ctx->first_c = len;
2281       iobuf_push_filter (a, block_filter, ctx);
2282     }
2283 }
2284
2285
2286 /****************
2287  * Checks whether the stream is in block mode
2288  * Note: This does not work if other filters are pushed on the stream.
2289  */
2290 int
2291 iobuf_in_block_mode (iobuf_t a)
2292 {
2293   if (a && a->filter == block_filter)
2294     return 1;                   /* yes */
2295   return 0;                     /* no */
2296 }
2297
2298
2299 /****************
2300  * Same as fgets() but if the buffer is too short a larger one will
2301  * be allocated up to some limit *max_length.
2302  * A line is considered a byte stream ending in a LF.
2303  * Returns the length of the line. EOF is indicated by a line of
2304  * length zero. The last LF may be missing due to an EOF.
2305  * is max_length is zero on return, the line has been truncated.
2306  *
2307  * Note: The buffer is allocated with enough space to append a CR,LF,EOL
2308  */
2309 unsigned int
2310 iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2311                  unsigned *length_of_buffer, unsigned *max_length)
2312 {
2313   int c;
2314   char *buffer = *addr_of_buffer;
2315   unsigned length = *length_of_buffer;
2316   unsigned nbytes = 0;
2317   unsigned maxlen = *max_length;
2318   char *p;
2319
2320   if (!buffer)
2321     {                           /* must allocate a new buffer */
2322       length = 256;
2323       buffer = xmalloc (length);
2324       *addr_of_buffer = buffer;
2325       *length_of_buffer = length;
2326     }
2327
2328   length -= 3;                  /* reserve 3 bytes (cr,lf,eol) */
2329   p = buffer;
2330   while ((c = iobuf_get (a)) != -1)
2331     {
2332       if (nbytes == length)
2333         {                       /* increase the buffer */
2334           if (length > maxlen)
2335             {                   /* this is out limit */
2336               /* skip the rest of the line */
2337               while (c != '\n' && (c = iobuf_get (a)) != -1)
2338                 ;
2339               *p++ = '\n';      /* always append a LF (we have reserved space) */
2340               nbytes++;
2341               *max_length = 0;  /* indicate truncation */
2342               break;
2343             }
2344           length += 3;          /* correct for the reserved byte */
2345           length += length < 1024 ? 256 : 1024;
2346           buffer = xrealloc (buffer, length);
2347           *addr_of_buffer = buffer;
2348           *length_of_buffer = length;
2349           length -= 3;          /* and reserve again */
2350           p = buffer + nbytes;
2351         }
2352       *p++ = c;
2353       nbytes++;
2354       if (c == '\n')
2355         break;
2356     }
2357   *p = 0;                       /* make sure the line is a string */
2358
2359   return nbytes;
2360 }
2361
2362 /* This is the non iobuf specific function */
2363 int
2364 iobuf_translate_file_handle (int fd, int for_write)
2365 {
2366 #ifdef _WIN32
2367   {
2368     int x;
2369
2370     if (fd <= 2)
2371       return fd;                /* do not do this for error, stdin, stdout, stderr */
2372
2373     x = _open_osfhandle (fd, for_write ? 1 : 0);
2374     if (x == -1)
2375       log_error ("failed to translate osfhandle %p\n", (void *) fd);
2376     else
2377       {
2378         /*log_info ("_open_osfhandle %p yields %d%s\n",
2379            (void*)fd, x, for_write? " for writing":"" ); */
2380         fd = x;
2381       }
2382   }
2383 #endif
2384   return fd;
2385 }
2386
2387 static int
2388 translate_file_handle (int fd, int for_write)
2389 {
2390 #ifdef _WIN32
2391 #ifdef FILE_FILTER_USES_STDIO
2392   fd = iobuf_translate_file_handle (fd, for_write);
2393 #else
2394   {
2395     int x;
2396
2397     if (fd == 0)
2398       x = (int) GetStdHandle (STD_INPUT_HANDLE);
2399     else if (fd == 1)
2400       x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2401     else if (fd == 2)
2402       x = (int) GetStdHandle (STD_ERROR_HANDLE);
2403     else
2404       x = fd;
2405
2406     if (x == -1)
2407       log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2408                  fd, (int) GetLastError ());
2409
2410     fd = x;
2411   }
2412 #endif
2413 #endif
2414   return fd;
2415 }