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