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