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