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