Installed revised and updated translation
[gnupg.git] / common / iobuf.c
1 /* iobuf.c  -  file handling
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3  *               2004, 2006  Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <ctype.h>
29 #include <assert.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #ifdef HAVE_DOSISH_SYSTEM
35 #include <windows.h>
36 #endif
37 #ifdef __riscos__
38 #include <kernel.h>
39 #include <swis.h>
40 #endif /* __riscos__ */
41
42 #include "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 (%d) real\n", 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_syserror ();
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_syserror ();
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_syserror ();
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_syserror ();
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_syserror ();
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_syserror ();
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_syserror ();
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_syserror ();
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   if (a->nlimit && a->nbytes >= a->nlimit)
1779     return -1;                  /* forced EOF */
1780
1781   if (a->d.start < a->d.len)
1782     {
1783       c = a->d.buf[a->d.start++];
1784     }
1785   else if ((c = underflow (a)) == -1)
1786     return -1;                  /* EOF */
1787
1788   a->nbytes++;
1789   return c;
1790 }
1791
1792
1793 int
1794 iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
1795 {
1796   unsigned char *buf = (unsigned char *)buffer;
1797   int c, n;
1798
1799   if (a->nlimit)
1800     {
1801       /* Handle special cases. */
1802       for (n = 0; n < buflen; n++)
1803         {
1804           if ((c = iobuf_readbyte (a)) == -1)
1805             {
1806               if (!n)
1807                 return -1;      /* eof */
1808               break;
1809             }
1810           else if (buf)
1811             *buf = c;
1812           if (buf)
1813             buf++;
1814         }
1815       return n;
1816     }
1817
1818   n = 0;
1819   do
1820     {
1821       if (n < buflen && a->d.start < a->d.len)
1822         {
1823           unsigned size = a->d.len - a->d.start;
1824           if (size > buflen - n)
1825             size = buflen - n;
1826           if (buf)
1827             memcpy (buf, a->d.buf + a->d.start, size);
1828           n += size;
1829           a->d.start += size;
1830           if (buf)
1831             buf += size;
1832         }
1833       if (n < buflen)
1834         {
1835           if ((c = underflow (a)) == -1)
1836             {
1837               a->nbytes += n;
1838               return n ? n : -1 /*EOF*/;
1839             }
1840           if (buf)
1841             *buf++ = c;
1842           n++;
1843         }
1844     }
1845   while (n < buflen);
1846   a->nbytes += n;
1847   return n;
1848 }
1849
1850
1851
1852 /****************
1853  * Have a look at the iobuf.
1854  * NOTE: This only works in special cases.
1855  */
1856 int
1857 iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
1858 {
1859   int n = 0;
1860
1861   if (a->filter_eof)
1862     return -1;
1863
1864   if (!(a->d.start < a->d.len))
1865     {
1866       if (underflow (a) == -1)
1867         return -1;
1868       /* And unget this character. */
1869       assert (a->d.start == 1);
1870       a->d.start = 0;
1871     }
1872
1873   for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++)
1874     *buf = a->d.buf[n];
1875   return n;
1876 }
1877
1878
1879
1880
1881 int
1882 iobuf_writebyte (iobuf_t a, unsigned int c)
1883 {
1884   int rc;
1885
1886   if (a->directfp)
1887     BUG ();
1888
1889   if (a->d.len == a->d.size)
1890     if ((rc=iobuf_flush (a)))
1891       return rc;
1892
1893   assert (a->d.len < a->d.size);
1894   a->d.buf[a->d.len++] = c;
1895   return 0;
1896 }
1897
1898
1899 int
1900 iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
1901 {
1902   const unsigned char *buf = (const unsigned char *)buffer;
1903   int rc;
1904
1905   if (a->directfp)
1906     BUG ();
1907
1908   do
1909     {
1910       if (buflen && a->d.len < a->d.size)
1911         {
1912           unsigned size = a->d.size - a->d.len;
1913           if (size > buflen)
1914             size = buflen;
1915           memcpy (a->d.buf + a->d.len, buf, size);
1916           buflen -= size;
1917           buf += size;
1918           a->d.len += size;
1919         }
1920       if (buflen)
1921         {
1922           rc = iobuf_flush (a);
1923           if (rc)
1924             return rc;
1925         }
1926     }
1927   while (buflen);
1928   return 0;
1929 }
1930
1931
1932 int
1933 iobuf_writestr (iobuf_t a, const char *buf)
1934 {
1935   int rc;
1936
1937   for (; *buf; buf++)
1938     if ((rc=iobuf_writebyte (a, *buf)))
1939       return rc;
1940   return 0;
1941 }
1942
1943
1944
1945 /****************
1946  * copy the contents of TEMP to A.
1947  */
1948 int
1949 iobuf_write_temp (iobuf_t a, iobuf_t temp)
1950 {
1951   while (temp->chain)
1952     pop_filter (temp, temp->filter, NULL);
1953   return iobuf_write (a, temp->d.buf, temp->d.len);
1954 }
1955
1956 /****************
1957  * copy the contents of the temp io stream to BUFFER.
1958  */
1959 size_t
1960 iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
1961 {
1962   size_t n = a->d.len;
1963
1964   if (n > buflen)
1965     n = buflen;
1966   memcpy (buffer, a->d.buf, n);
1967   return n;
1968 }
1969
1970
1971 /****************
1972  * Call this function to terminate processing of the temp stream
1973  * without closing it.  This removes all filters from the stream
1974  * makes sure that iobuf_get_temp_{buffer,length}() returns correct
1975  * values.
1976  */
1977 void
1978 iobuf_flush_temp (iobuf_t temp)
1979 {
1980   while (temp->chain)
1981     pop_filter (temp, temp->filter, NULL);
1982 }
1983
1984
1985 /****************
1986  * Set a limit on how many bytes may be read from the input stream A.
1987  * Setting the limit to 0 disables this feature.
1988  */
1989 void
1990 iobuf_set_limit (iobuf_t a, off_t nlimit)
1991 {
1992   if (nlimit)
1993     a->nofast |= 1;
1994   else
1995     a->nofast &= ~1;
1996   a->nlimit = nlimit;
1997   a->ntotal += a->nbytes;
1998   a->nbytes = 0;
1999 }
2000
2001
2002
2003 /* Return the length of an open file A.  IF OVERFLOW is not NULL it
2004    will be set to true if the file is larger than what off_t can cope
2005    with.  The function return 0 on error or on overflow condition.  */
2006 off_t
2007 iobuf_get_filelength (iobuf_t a, int *overflow)
2008 {
2009     struct stat st;
2010
2011     if (overflow)
2012       *overflow = 0;
2013
2014     if( a->directfp )  {
2015         FILE *fp = a->directfp;
2016
2017        if( !fstat(fileno(fp), &st) )
2018            return st.st_size;
2019         log_error("fstat() failed: %s\n", strerror(errno) );
2020         return 0;
2021     }
2022
2023     /* Hmmm: file_filter may have already been removed */
2024     for( ; a; a = a->chain )
2025         if( !a->chain && a->filter == file_filter ) {
2026             file_filter_ctx_t *b = a->filter_ov;
2027             FILEP_OR_FD fp = b->fp;
2028
2029 #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
2030             ulong size;
2031             static int (* __stdcall get_file_size_ex) 
2032               (void *handle, LARGE_INTEGER *size);
2033             static int get_file_size_ex_initialized;
2034
2035             if (!get_file_size_ex_initialized)
2036               {
2037                 void *handle;
2038                 
2039                 handle = dlopen ("kernel32.dll", RTLD_LAZY);
2040                 if (handle)
2041                   {
2042                     get_file_size_ex = dlsym (handle, "GetFileSizeEx");
2043                     if (!get_file_size_ex)
2044                     dlclose (handle);
2045                   }
2046                 get_file_size_ex_initialized = 1;
2047               }
2048
2049             if (get_file_size_ex)
2050               {
2051                 /* This is a newer system with GetFileSizeEx; we use
2052                    this then becuase it seem that GetFileSize won't
2053                    return a proper error in case a file is larger than
2054                    4GB. */
2055                 LARGE_INTEGER size;
2056                 
2057                 if (get_file_size_ex (fp, &size))
2058                   {
2059                     if (!size.u.HighPart)
2060                       return size.u.LowPart;
2061                     if (overflow)
2062                       *overflow = 1;
2063                     return 0; 
2064                   }
2065               }
2066             else
2067               {
2068                 if  ((size=GetFileSize (fp, NULL)) != 0xffffffff)
2069                   return size;
2070               }
2071             log_error ("GetFileSize for handle %p failed: %s\n",
2072                        fp, w32_strerror (0));
2073 #else
2074             if( !fstat(my_fileno(fp), &st) )
2075                 return st.st_size;
2076             log_error("fstat() failed: %s\n", strerror(errno) );
2077 #endif
2078             break;
2079         }
2080
2081     return 0;
2082 }
2083
2084
2085 /* Return the file descriptor of the underlying file or -1 if it is
2086    not available.  */
2087 int 
2088 iobuf_get_fd (iobuf_t a)
2089 {
2090   if (a->directfp)
2091     return fileno ( (FILE*)a->directfp );
2092
2093   for ( ; a; a = a->chain )
2094     if (!a->chain && a->filter == file_filter)
2095       {
2096         file_filter_ctx_t *b = a->filter_ov;
2097         FILEP_OR_FD fp = b->fp;
2098
2099         return my_fileno (fp);
2100       }
2101
2102   return -1;
2103 }
2104
2105
2106
2107 /****************
2108  * Tell the file position, where the next read will take place
2109  */
2110 off_t
2111 iobuf_tell (iobuf_t a)
2112 {
2113   return a->ntotal + a->nbytes;
2114 }
2115
2116
2117 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2118
2119 #ifdef HAVE_LIMITS_H
2120 # include <limits.h>
2121 #endif
2122 #ifndef LONG_MAX
2123 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2124 #endif
2125 #ifndef LONG_MIN
2126 # define LONG_MIN (-1 - LONG_MAX)
2127 #endif
2128
2129 /****************
2130  * A substitute for fseeko, for hosts that don't have it.
2131  */
2132 static int
2133 fseeko (FILE * stream, off_t newpos, int whence)
2134 {
2135   while (newpos != (long) newpos)
2136     {
2137       long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2138       if (fseek (stream, pos, whence) != 0)
2139         return -1;
2140       newpos -= pos;
2141       whence = SEEK_CUR;
2142     }
2143   return fseek (stream, (long) newpos, whence);
2144 }
2145 #endif
2146
2147 /****************
2148  * This is a very limited implementation. It simply discards all internal
2149  * buffering and removes all filters but the first one.
2150  */
2151 int
2152 iobuf_seek (iobuf_t a, off_t newpos)
2153 {
2154   file_filter_ctx_t *b = NULL;
2155
2156   if (a->directfp)
2157     {
2158       FILE *fp = a->directfp;
2159       if (fseeko (fp, newpos, SEEK_SET))
2160         {
2161           log_error ("can't seek: %s\n", strerror (errno));
2162           return -1;
2163         }
2164       clearerr (fp);
2165     }
2166   else
2167     {
2168       for (; a; a = a->chain)
2169         {
2170           if (!a->chain && a->filter == file_filter)
2171             {
2172               b = a->filter_ov;
2173               break;
2174             }
2175         }
2176       if (!a)
2177         return -1;
2178 #ifdef FILE_FILTER_USES_STDIO
2179       if (fseeko (b->fp, newpos, SEEK_SET))
2180         {
2181           log_error ("can't fseek: %s\n", strerror (errno));
2182           return -1;
2183         }
2184 #else
2185 #ifdef HAVE_DOSISH_SYSTEM
2186       if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2187         {
2188           log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2189                      b->fp, (int) GetLastError ());
2190           return -1;
2191         }
2192 #else
2193       if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2194         {
2195           log_error ("can't lseek: %s\n", strerror (errno));
2196           return -1;
2197         }
2198 #endif
2199 #endif
2200     }
2201   a->d.len = 0;                 /* discard buffer */
2202   a->d.start = 0;
2203   a->nbytes = 0;
2204   a->nlimit = 0;
2205   a->nofast &= ~1;
2206   a->ntotal = newpos;
2207   a->error = 0;
2208   /* remove filters, but the last */
2209   if (a->chain)
2210     log_debug ("pop_filter called in iobuf_seek - please report\n");
2211   while (a->chain)
2212     pop_filter (a, a->filter, NULL);
2213
2214   return 0;
2215 }
2216
2217
2218
2219
2220
2221
2222 /****************
2223  * Retrieve the real filename
2224  */
2225 const char *
2226 iobuf_get_real_fname (iobuf_t a)
2227 {
2228   if (a->real_fname)
2229     return a->real_fname;
2230
2231   /* the old solution */
2232   for (; a; a = a->chain)
2233     if (!a->chain && a->filter == file_filter)
2234       {
2235         file_filter_ctx_t *b = a->filter_ov;
2236         return b->print_only_name ? NULL : b->fname;
2237       }
2238
2239   return NULL;
2240 }
2241
2242
2243 /****************
2244  * Retrieve the filename
2245  */
2246 const char *
2247 iobuf_get_fname (iobuf_t a)
2248 {
2249   for (; a; a = a->chain)
2250     if (!a->chain && a->filter == file_filter)
2251       {
2252         file_filter_ctx_t *b = a->filter_ov;
2253         return b->fname;
2254       }
2255
2256   return NULL;
2257 }
2258
2259
2260 /****************
2261  * enable partial block mode as described in the OpenPGP draft.
2262  * LEN is the first length byte on read, but ignored on writes.
2263  */
2264 void
2265 iobuf_set_partial_block_mode (iobuf_t a, size_t len)
2266 {
2267   block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2268
2269   assert (a->use == 1 || a->use == 2);
2270   ctx->use = a->use;
2271   if (!len)
2272     {
2273       if (a->use == 1)
2274         log_debug ("pop_filter called in set_partial_block_mode"
2275                    " - please report\n");
2276       pop_filter (a, block_filter, NULL);
2277     }
2278   else
2279     {
2280       ctx->partial = 1;
2281       ctx->size = 0;
2282       ctx->first_c = len;
2283       iobuf_push_filter (a, block_filter, ctx);
2284     }
2285 }
2286
2287
2288
2289 /****************
2290  * Same as fgets() but if the buffer is too short a larger one will
2291  * be allocated up to some limit *max_length.
2292  * A line is considered a byte stream ending in a LF.
2293  * Returns the length of the line. EOF is indicated by a line of
2294  * length zero. The last LF may be missing due to an EOF.
2295  * is max_length is zero on return, the line has been truncated.
2296  *
2297  * Note: The buffer is allocated with enough space to append a CR,LF,EOL
2298  */
2299 unsigned int
2300 iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2301                  unsigned *length_of_buffer, unsigned *max_length)
2302 {
2303   int c;
2304   char *buffer = (char *)*addr_of_buffer;
2305   unsigned length = *length_of_buffer;
2306   unsigned nbytes = 0;
2307   unsigned maxlen = *max_length;
2308   char *p;
2309
2310   if (!buffer)
2311     {                           /* must allocate a new buffer */
2312       length = 256;
2313       buffer = xmalloc (length);
2314       *addr_of_buffer = (unsigned char *)buffer;
2315       *length_of_buffer = length;
2316     }
2317
2318   length -= 3;                  /* reserve 3 bytes (cr,lf,eol) */
2319   p = buffer;
2320   while ((c = iobuf_get (a)) != -1)
2321     {
2322       if (nbytes == length)
2323         {                       /* increase the buffer */
2324           if (length > maxlen)
2325             {                   /* this is out limit */
2326               /* skip the rest of the line */
2327               while (c != '\n' && (c = iobuf_get (a)) != -1)
2328                 ;
2329               *p++ = '\n';      /* always append a LF (we have reserved space) */
2330               nbytes++;
2331               *max_length = 0;  /* indicate truncation */
2332               break;
2333             }
2334           length += 3;          /* correct for the reserved byte */
2335           length += length < 1024 ? 256 : 1024;
2336           buffer = xrealloc (buffer, length);
2337           *addr_of_buffer = (unsigned char *)buffer;
2338           *length_of_buffer = length;
2339           length -= 3;          /* and reserve again */
2340           p = buffer + nbytes;
2341         }
2342       *p++ = c;
2343       nbytes++;
2344       if (c == '\n')
2345         break;
2346     }
2347   *p = 0;                       /* make sure the line is a string */
2348
2349   return nbytes;
2350 }
2351
2352 /* This is the non iobuf specific function */
2353 int
2354 iobuf_translate_file_handle (int fd, int for_write)
2355 {
2356 #ifdef _WIN32
2357   {
2358     int x;
2359
2360     if (fd <= 2)
2361       return fd;                /* do not do this for error, stdin, stdout, stderr */
2362
2363     x = _open_osfhandle (fd, for_write ? 1 : 0);
2364     if (x == -1)
2365       log_error ("failed to translate osfhandle %p\n", (void *) fd);
2366     else
2367       {
2368         /*log_info ("_open_osfhandle %p yields %d%s\n",
2369            (void*)fd, x, for_write? " for writing":"" ); */
2370         fd = x;
2371       }
2372   }
2373 #endif
2374   return fd;
2375 }
2376
2377 static int
2378 translate_file_handle (int fd, int for_write)
2379 {
2380 #ifdef _WIN32
2381 #ifdef FILE_FILTER_USES_STDIO
2382   fd = iobuf_translate_file_handle (fd, for_write);
2383 #else
2384   {
2385     int x;
2386
2387     if (fd == 0)
2388       x = (int) GetStdHandle (STD_INPUT_HANDLE);
2389     else if (fd == 1)
2390       x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2391     else if (fd == 2)
2392       x = (int) GetStdHandle (STD_ERROR_HANDLE);
2393     else
2394       x = fd;
2395
2396     if (x == -1)
2397       log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2398                  fd, (int) GetLastError ());
2399
2400     fd = x;
2401   }
2402 #endif
2403 #endif
2404   return fd;
2405 }
2406
2407
2408 void
2409 iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2410 {
2411   if ( partial )
2412     {
2413       for (;;)
2414         {
2415           if (a->nofast || a->d.start >= a->d.len) 
2416             {
2417               if (iobuf_readbyte (a) == -1)
2418                 {
2419                   break;
2420                 }
2421             } 
2422           else
2423             {
2424               unsigned long count = a->d.len - a->d.start;
2425               a->nbytes += count;
2426               a->d.start = a->d.len;
2427             }
2428         }
2429     } 
2430   else
2431     {
2432       unsigned long remaining = n;
2433       while (remaining > 0) 
2434         {
2435           if (a->nofast || a->d.start >= a->d.len)
2436             {
2437               if (iobuf_readbyte (a) == -1)
2438                 {
2439                   break;
2440                 }
2441               --remaining;
2442             } 
2443           else 
2444             {
2445               unsigned long count = a->d.len - a->d.start;
2446               if (count > remaining) 
2447                 {
2448                   count = remaining;
2449                 }
2450               a->nbytes += count;
2451               a->d.start += count;
2452               remaining -= count;
2453             }
2454         }
2455     }
2456 }