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