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