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