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