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