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