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