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