2006-09-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / common / iobuf.c
blob8100883e321667fa9b57cb3373da17bade6210d3
1 /* iobuf.c - file handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3 * 2004, 2006 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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 2 of the License, or
10 * (at your option) any later version.
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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA.
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <ctype.h>
29 #include <assert.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #ifdef HAVE_DOSISH_SYSTEM
35 #include <windows.h>
36 #endif
37 #ifdef __riscos__
38 #include <kernel.h>
39 #include <swis.h>
40 #endif /* __riscos__ */
42 #include "util.h"
43 #include "iobuf.h"
45 /* The size of the internal buffers.
46 NOTE: If you change this value you MUST also adjust the regression
47 test "armored_key_8192" in armor.test! */
48 #define IOBUF_BUFFER_SIZE 8192
50 #undef FILE_FILTER_USES_STDIO
52 #ifdef HAVE_DOSISH_SYSTEM
53 #define USE_SETMODE 1
54 #endif
56 #ifdef FILE_FILTER_USES_STDIO
57 #define my_fileno(a) fileno ((a))
58 #define my_fopen_ro(a,b) fopen ((a),(b))
59 #define my_fopen(a,b) fopen ((a),(b))
60 typedef FILE *FILEP_OR_FD;
61 #define INVALID_FP NULL
62 #define FILEP_OR_FD_FOR_STDIN (stdin)
63 #define FILEP_OR_FD_FOR_STDOUT (stdout)
64 typedef struct
66 FILE *fp; /* open file handle */
67 int keep_open;
68 int no_cache;
69 int print_only_name; /* flags indicating that fname is not a real file */
70 char fname[1]; /* name of the file */
72 file_filter_ctx_t;
73 #else
74 #define my_fileno(a) (a)
75 #define my_fopen_ro(a,b) fd_cache_open ((a),(b))
76 #define my_fopen(a,b) direct_open ((a),(b))
77 #ifdef HAVE_DOSISH_SYSTEM
78 typedef HANDLE FILEP_OR_FD;
79 #define INVALID_FP ((HANDLE)-1)
80 #define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
81 #define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
82 #undef USE_SETMODE
83 #else
84 typedef int FILEP_OR_FD;
85 #define INVALID_FP (-1)
86 #define FILEP_OR_FD_FOR_STDIN (0)
87 #define FILEP_OR_FD_FOR_STDOUT (1)
88 #endif
89 typedef struct
91 FILEP_OR_FD fp; /* open file handle */
92 int keep_open;
93 int no_cache;
94 int eof_seen;
95 int print_only_name; /* flags indicating that fname is not a real file */
96 char fname[1]; /* name of the file */
98 file_filter_ctx_t;
100 struct close_cache_s
102 struct close_cache_s *next;
103 FILEP_OR_FD fp;
104 char fname[1];
106 typedef struct close_cache_s *CLOSE_CACHE;
107 static CLOSE_CACHE close_cache;
108 #endif
110 #ifdef _WIN32
111 typedef struct
113 int sock;
114 int keep_open;
115 int no_cache;
116 int eof_seen;
117 int print_only_name; /* flags indicating that fname is not a real file */
118 char fname[1]; /* name of the file */
120 sock_filter_ctx_t;
121 #endif /*_WIN32*/
123 /* The first partial length header block must be of size 512
124 * to make it easier (and efficienter) we use a min. block size of 512
125 * for all chunks (but the last one) */
126 #define OP_MIN_PARTIAL_CHUNK 512
127 #define OP_MIN_PARTIAL_CHUNK_2POW 9
129 typedef struct
131 int use;
132 size_t size;
133 size_t count;
134 int partial; /* 1 = partial header, 2 in last partial packet */
135 char *buffer; /* used for partial header */
136 size_t buflen; /* used size of buffer */
137 int first_c; /* of partial header (which is > 0) */
138 int eof;
140 block_filter_ctx_t;
142 static int special_names_enabled;
144 static int underflow (iobuf_t a);
145 static int translate_file_handle (int fd, int for_write);
147 #ifndef FILE_FILTER_USES_STDIO
150 * Invalidate (i.e. close) a cached iobuf
152 static void
153 fd_cache_invalidate (const char *fname)
155 CLOSE_CACHE cc;
157 assert (fname);
158 if (DBG_IOBUF)
159 log_debug ("fd_cache_invalidate (%s)\n", fname);
161 for (cc = close_cache; cc; cc = cc->next)
163 if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname))
165 if (DBG_IOBUF)
166 log_debug (" did (%s)\n", cc->fname);
167 #ifdef HAVE_DOSISH_SYSTEM
168 CloseHandle (cc->fp);
169 #else
170 close (cc->fp);
171 #endif
172 cc->fp = INVALID_FP;
179 static FILEP_OR_FD
180 direct_open (const char *fname, const char *mode)
182 #ifdef HAVE_DOSISH_SYSTEM
183 unsigned long da, cd, sm;
184 HANDLE hfile;
186 /* Note, that we do not handle all mode combinations */
188 /* According to the ReactOS source it seems that open() of the
189 * standard MSW32 crt does open the file in share mode which is
190 * something new for MS applications ;-)
192 if (strchr (mode, '+'))
194 fd_cache_invalidate (fname);
195 da = GENERIC_READ | GENERIC_WRITE;
196 cd = OPEN_EXISTING;
197 sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
199 else if (strchr (mode, 'w'))
201 fd_cache_invalidate (fname);
202 da = GENERIC_WRITE;
203 cd = CREATE_ALWAYS;
204 sm = FILE_SHARE_WRITE;
206 else
208 da = GENERIC_READ;
209 cd = OPEN_EXISTING;
210 sm = FILE_SHARE_READ;
213 hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
214 return hfile;
215 #else
216 int oflag;
217 int cflag = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
219 /* Note, that we do not handle all mode combinations */
220 if (strchr (mode, '+'))
222 fd_cache_invalidate (fname);
223 oflag = O_RDWR;
225 else if (strchr (mode, 'w'))
227 fd_cache_invalidate (fname);
228 oflag = O_WRONLY | O_CREAT | O_TRUNC;
230 else
232 oflag = O_RDONLY;
234 #ifdef O_BINARY
235 if (strchr (mode, 'b'))
236 oflag |= O_BINARY;
237 #endif
238 #ifndef __riscos__
239 return open (fname, oflag, cflag);
240 #else
242 struct stat buf;
243 int rc = stat (fname, &buf);
245 /* Don't allow iobufs on directories */
246 if (!rc && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
247 return __set_errno (EISDIR);
248 else
249 return open (fname, oflag, cflag);
251 #endif
252 #endif
257 * Instead of closing an FD we keep it open and cache it for later reuse
258 * Note that this caching strategy only works if the process does not chdir.
260 static void
261 fd_cache_close (const char *fname, FILEP_OR_FD fp)
263 CLOSE_CACHE cc;
265 assert (fp);
266 if (!fname || !*fname)
268 #ifdef HAVE_DOSISH_SYSTEM
269 CloseHandle (fp);
270 #else
271 close (fp);
272 #endif
273 if (DBG_IOBUF)
274 log_debug ("fd_cache_close (%p) real\n", (void *) fp);
275 return;
277 /* try to reuse a slot */
278 for (cc = close_cache; cc; cc = cc->next)
280 if (cc->fp == INVALID_FP && !strcmp (cc->fname, fname))
282 cc->fp = fp;
283 if (DBG_IOBUF)
284 log_debug ("fd_cache_close (%s) used existing slot\n", fname);
285 return;
288 /* add a new one */
289 if (DBG_IOBUF)
290 log_debug ("fd_cache_close (%s) new slot created\n", fname);
291 cc = xcalloc (1, sizeof *cc + strlen (fname));
292 strcpy (cc->fname, fname);
293 cc->fp = fp;
294 cc->next = close_cache;
295 close_cache = cc;
299 * Do an direct_open on FNAME but first try to reuse one from the fd_cache
301 static FILEP_OR_FD
302 fd_cache_open (const char *fname, const char *mode)
304 CLOSE_CACHE cc;
306 assert (fname);
307 for (cc = close_cache; cc; cc = cc->next)
309 if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname))
311 FILEP_OR_FD fp = cc->fp;
312 cc->fp = INVALID_FP;
313 if (DBG_IOBUF)
314 log_debug ("fd_cache_open (%s) using cached fp\n", fname);
315 #ifdef HAVE_DOSISH_SYSTEM
316 if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff)
318 log_error ("rewind file failed on handle %p: ec=%d\n",
319 fp, (int) GetLastError ());
320 fp = INVALID_FP;
322 #else
323 if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
325 log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
326 fp = INVALID_FP;
328 #endif
329 return fp;
332 if (DBG_IOBUF)
333 log_debug ("fd_cache_open (%s) not cached\n", fname);
334 return direct_open (fname, mode);
338 #endif /*FILE_FILTER_USES_STDIO */
341 /****************
342 * Read data from a file into buf which has an allocated length of *LEN.
343 * return the number of read bytes in *LEN. OPAQUE is the FILE * of
344 * the stream. A is not used.
345 * control may be:
346 * IOBUFCTRL_INIT: called just before the function is linked into the
347 * list of function. This can be used to prepare internal
348 * data structures of the function.
349 * IOBUFCTRL_FREE: called just before the function is removed from the
350 * list of functions and can be used to release internal
351 * data structures or close a file etc.
352 * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer
353 * with new stuff. *RET_LEN is the available size of the
354 * buffer, and should be set to the number of bytes
355 * which were put into the buffer. The function
356 * returns 0 to indicate success, -1 on EOF and
357 * GPG_ERR_xxxxx for other errors.
359 * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
360 * *RET_LAN is the number of bytes in BUF.
362 * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The
363 * filter may take appropriate action on this message.
365 static int
366 file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
367 size_t * ret_len)
369 file_filter_ctx_t *a = opaque;
370 FILEP_OR_FD f = a->fp;
371 size_t size = *ret_len;
372 size_t nbytes = 0;
373 int rc = 0;
375 #ifdef FILE_FILTER_USES_STDIO
376 if (control == IOBUFCTRL_UNDERFLOW)
378 assert (size); /* need a buffer */
379 if (feof (f))
380 { /* On terminals you could easiely read as many EOFs as you call */
381 rc = -1; /* fread() or fgetc() repeatly. Every call will block until you press */
382 *ret_len = 0; /* CTRL-D. So we catch this case before we call fread() again. */
384 else
386 clearerr (f);
387 nbytes = fread (buf, 1, size, f);
388 if (feof (f) && !nbytes)
390 rc = -1; /* okay: we can return EOF now. */
392 else if (ferror (f) && errno != EPIPE)
394 rc = gpg_error_from_syserror ();
395 log_error ("%s: read error: %s\n", a->fname, strerror (errno));
397 *ret_len = nbytes;
400 else if (control == IOBUFCTRL_FLUSH)
402 if (size)
404 clearerr (f);
405 nbytes = fwrite (buf, 1, size, f);
406 if (ferror (f))
408 rc = gpg_error_from_syserror ();
409 log_error ("%s: write error: %s\n", a->fname, strerror (errno));
412 *ret_len = nbytes;
414 else if (control == IOBUFCTRL_INIT)
416 a->keep_open = a->no_cache = 0;
418 else if (control == IOBUFCTRL_DESC)
420 *(char **) buf = "file_filter";
422 else if (control == IOBUFCTRL_FREE)
424 if (f != stdin && f != stdout)
426 if (DBG_IOBUF)
427 log_debug ("%s: close fd %d\n", a->fname, fileno (f));
428 if (!a->keep_open)
429 fclose (f);
431 f = NULL;
432 xfree (a); /* we can free our context now */
434 #else /* !stdio implementation */
436 if (control == IOBUFCTRL_UNDERFLOW)
438 assert (size); /* need a buffer */
439 if (a->eof_seen)
441 rc = -1;
442 *ret_len = 0;
444 else
446 #ifdef HAVE_DOSISH_SYSTEM
447 unsigned long nread;
449 nbytes = 0;
450 if (!ReadFile (f, buf, size, &nread, NULL))
452 int ec = (int) GetLastError ();
453 if (ec != ERROR_BROKEN_PIPE)
455 rc = gpg_error_from_errno (ec);
456 log_error ("%s: read error: ec=%d\n", a->fname, ec);
459 else if (!nread)
461 a->eof_seen = 1;
462 rc = -1;
464 else
466 nbytes = nread;
469 #else
471 int n;
473 nbytes = 0;
476 n = read (f, buf, size);
478 while (n == -1 && errno == EINTR);
479 if (n == -1)
480 { /* error */
481 if (errno != EPIPE)
483 rc = gpg_error_from_syserror ();
484 log_error ("%s: read error: %s\n",
485 a->fname, strerror (errno));
488 else if (!n)
489 { /* eof */
490 a->eof_seen = 1;
491 rc = -1;
493 else
495 nbytes = n;
497 #endif
498 *ret_len = nbytes;
501 else if (control == IOBUFCTRL_FLUSH)
503 if (size)
505 #ifdef HAVE_DOSISH_SYSTEM
506 byte *p = buf;
507 unsigned long n;
509 nbytes = size;
512 if (size && !WriteFile (f, p, nbytes, &n, NULL))
514 int ec = (int) GetLastError ();
515 rc = gpg_error_from_errno (ec);
516 log_error ("%s: write error: ec=%d\n", a->fname, ec);
517 break;
519 p += n;
520 nbytes -= n;
522 while (nbytes);
523 nbytes = p - buf;
524 #else
525 byte *p = buf;
526 int n;
528 nbytes = size;
533 n = write (f, p, nbytes);
535 while (n == -1 && errno == EINTR);
536 if (n > 0)
538 p += n;
539 nbytes -= n;
542 while (n != -1 && nbytes);
543 if (n == -1)
545 rc = gpg_error_from_syserror ();
546 log_error ("%s: write error: %s\n", a->fname, strerror (errno));
548 nbytes = p - buf;
549 #endif
551 *ret_len = nbytes;
553 else if (control == IOBUFCTRL_INIT)
555 a->eof_seen = 0;
556 a->keep_open = 0;
557 a->no_cache = 0;
559 else if (control == IOBUFCTRL_DESC)
561 *(char **) buf = "file_filter(fd)";
563 else if (control == IOBUFCTRL_FREE)
565 #ifdef HAVE_DOSISH_SYSTEM
566 if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT)
568 if (DBG_IOBUF)
569 log_debug ("%s: close handle %p\n", a->fname, f);
570 if (!a->keep_open)
571 fd_cache_close (a->no_cache ? NULL : a->fname, f);
573 #else
574 if ((int) f != 0 && (int) f != 1)
576 if (DBG_IOBUF)
577 log_debug ("%s: close fd %d\n", a->fname, f);
578 if (!a->keep_open)
579 fd_cache_close (a->no_cache ? NULL : a->fname, f);
581 f = INVALID_FP;
582 #endif
583 xfree (a); /* we can free our context now */
585 #endif /* !stdio implementation */
586 return rc;
589 #ifdef _WIN32
590 /* Becuase sockets are an special object under Lose32 we have to
591 * use a special filter */
592 static int
593 sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
594 size_t * ret_len)
596 sock_filter_ctx_t *a = opaque;
597 size_t size = *ret_len;
598 size_t nbytes = 0;
599 int rc = 0;
601 if (control == IOBUFCTRL_UNDERFLOW)
603 assert (size); /* need a buffer */
604 if (a->eof_seen)
606 rc = -1;
607 *ret_len = 0;
609 else
611 int nread;
613 nread = recv (a->sock, buf, size, 0);
614 if (nread == SOCKET_ERROR)
616 int ec = (int) WSAGetLastError ();
617 rc = gpg_error_from_errno (ec);
618 log_error ("socket read error: ec=%d\n", ec);
620 else if (!nread)
622 a->eof_seen = 1;
623 rc = -1;
625 else
627 nbytes = nread;
629 *ret_len = nbytes;
632 else if (control == IOBUFCTRL_FLUSH)
634 if (size)
636 byte *p = buf;
637 int n;
639 nbytes = size;
642 n = send (a->sock, p, nbytes, 0);
643 if (n == SOCKET_ERROR)
645 int ec = (int) WSAGetLastError ();
646 rc = gpg_error_from_errno (ec);
647 log_error ("socket write error: ec=%d\n", ec);
648 break;
650 p += n;
651 nbytes -= n;
653 while (nbytes);
654 nbytes = p - buf;
656 *ret_len = nbytes;
658 else if (control == IOBUFCTRL_INIT)
660 a->eof_seen = 0;
661 a->keep_open = 0;
662 a->no_cache = 0;
664 else if (control == IOBUFCTRL_DESC)
666 *(char **) buf = "sock_filter";
668 else if (control == IOBUFCTRL_FREE)
670 if (!a->keep_open)
671 closesocket (a->sock);
672 xfree (a); /* we can free our context now */
674 return rc;
676 #endif /*_WIN32*/
678 /****************
679 * This is used to implement the block write mode.
680 * Block reading is done on a byte by byte basis in readbyte(),
681 * without a filter
683 static int
684 block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
685 size_t * ret_len)
687 block_filter_ctx_t *a = opaque;
688 char *buf = (char *)buffer;
689 size_t size = *ret_len;
690 int c, needed, rc = 0;
691 char *p;
693 if (control == IOBUFCTRL_UNDERFLOW)
695 size_t n = 0;
697 p = buf;
698 assert (size); /* need a buffer */
699 if (a->eof) /* don't read any further */
700 rc = -1;
701 while (!rc && size)
703 if (!a->size)
704 { /* get the length bytes */
705 if (a->partial == 2)
707 a->eof = 1;
708 if (!n)
709 rc = -1;
710 break;
712 else if (a->partial)
714 /* These OpenPGP introduced huffman like encoded length
715 * bytes are really a mess :-( */
716 if (a->first_c)
718 c = a->first_c;
719 a->first_c = 0;
721 else if ((c = iobuf_get (chain)) == -1)
723 log_error ("block_filter: 1st length byte missing\n");
724 rc = GPG_ERR_BAD_DATA;
725 break;
727 if (c < 192)
729 a->size = c;
730 a->partial = 2;
731 if (!a->size)
733 a->eof = 1;
734 if (!n)
735 rc = -1;
736 break;
739 else if (c < 224)
741 a->size = (c - 192) * 256;
742 if ((c = iobuf_get (chain)) == -1)
744 log_error
745 ("block_filter: 2nd length byte missing\n");
746 rc = GPG_ERR_BAD_DATA;
747 break;
749 a->size += c + 192;
750 a->partial = 2;
751 if (!a->size)
753 a->eof = 1;
754 if (!n)
755 rc = -1;
756 break;
759 else if (c == 255)
761 a->size = iobuf_get (chain) << 24;
762 a->size |= iobuf_get (chain) << 16;
763 a->size |= iobuf_get (chain) << 8;
764 if ((c = iobuf_get (chain)) == -1)
766 log_error ("block_filter: invalid 4 byte length\n");
767 rc = GPG_ERR_BAD_DATA;
768 break;
770 a->size |= c;
771 a->partial = 2;
772 if (!a->size)
774 a->eof = 1;
775 if (!n)
776 rc = -1;
777 break;
780 else
781 { /* Next partial body length. */
782 a->size = 1 << (c & 0x1f);
784 /* log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
786 else
787 BUG ();
790 while (!rc && size && a->size)
792 needed = size < a->size ? size : a->size;
793 c = iobuf_read (chain, p, needed);
794 if (c < needed)
796 if (c == -1)
797 c = 0;
798 log_error
799 ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
800 a, (ulong) size + c, (ulong) a->size + c);
801 rc = GPG_ERR_BAD_DATA;
803 else
805 size -= c;
806 a->size -= c;
807 p += c;
808 n += c;
812 *ret_len = n;
814 else if (control == IOBUFCTRL_FLUSH)
816 if (a->partial)
817 { /* the complicated openpgp scheme */
818 size_t blen, n, nbytes = size + a->buflen;
820 assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
821 if (nbytes < OP_MIN_PARTIAL_CHUNK)
823 /* not enough to write a partial block out; so we store it */
824 if (!a->buffer)
825 a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
826 memcpy (a->buffer + a->buflen, buf, size);
827 a->buflen += size;
829 else
830 { /* okay, we can write out something */
831 /* do this in a loop to use the most efficient block lengths */
832 p = buf;
835 /* find the best matching block length - this is limited
836 * by the size of the internal buffering */
837 for (blen = OP_MIN_PARTIAL_CHUNK * 2,
838 c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
839 blen *= 2, c++)
841 blen /= 2;
842 c--;
843 /* write the partial length header */
844 assert (c <= 0x1f); /*;-) */
845 c |= 0xe0;
846 iobuf_put (chain, c);
847 if ((n = a->buflen))
848 { /* write stuff from the buffer */
849 assert (n == OP_MIN_PARTIAL_CHUNK);
850 if (iobuf_write (chain, a->buffer, n))
851 rc = gpg_error_from_syserror ();
852 a->buflen = 0;
853 nbytes -= n;
855 if ((n = nbytes) > blen)
856 n = blen;
857 if (n && iobuf_write (chain, p, n))
858 rc = gpg_error_from_syserror ();
859 p += n;
860 nbytes -= n;
862 while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
863 /* store the rest in the buffer */
864 if (!rc && nbytes)
866 assert (!a->buflen);
867 assert (nbytes < OP_MIN_PARTIAL_CHUNK);
868 if (!a->buffer)
869 a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
870 memcpy (a->buffer, p, nbytes);
871 a->buflen = nbytes;
875 else
876 BUG ();
878 else if (control == IOBUFCTRL_INIT)
880 if (DBG_IOBUF)
881 log_debug ("init block_filter %p\n", a);
882 if (a->partial)
883 a->count = 0;
884 else if (a->use == 1)
885 a->count = a->size = 0;
886 else
887 a->count = a->size; /* force first length bytes */
888 a->eof = 0;
889 a->buffer = NULL;
890 a->buflen = 0;
892 else if (control == IOBUFCTRL_DESC)
894 *(char **) buf = "block_filter";
896 else if (control == IOBUFCTRL_FREE)
898 if (a->use == 2)
899 { /* write the end markers */
900 if (a->partial)
902 u32 len;
903 /* write out the remaining bytes without a partial header
904 * the length of this header may be 0 - but if it is
905 * the first block we are not allowed to use a partial header
906 * and frankly we can't do so, because this length must be
907 * a power of 2. This is _really_ complicated because we
908 * have to check the possible length of a packet prior
909 * to it's creation: a chain of filters becomes complicated
910 * and we need a lot of code to handle compressed packets etc.
911 * :-(((((((
913 /* construct header */
914 len = a->buflen;
915 /*log_debug("partial: remaining length=%u\n", len ); */
916 if (len < 192)
917 rc = iobuf_put (chain, len);
918 else if (len < 8384)
920 if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
921 rc = iobuf_put (chain, ((len - 192) % 256));
923 else
924 { /* use a 4 byte header */
925 if (!(rc = iobuf_put (chain, 0xff)))
926 if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
927 if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
928 if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
929 rc = iobuf_put (chain, len & 0xff);
931 if (!rc && len)
932 rc = iobuf_write (chain, a->buffer, len);
933 if (rc)
935 log_error ("block_filter: write error: %s\n",
936 strerror (errno));
937 rc = gpg_error_from_syserror ();
939 xfree (a->buffer);
940 a->buffer = NULL;
941 a->buflen = 0;
943 else
944 BUG ();
946 else if (a->size)
948 log_error ("block_filter: pending bytes!\n");
950 if (DBG_IOBUF)
951 log_debug ("free block_filter %p\n", a);
952 xfree (a); /* we can free our context now */
955 return rc;
959 static void
960 print_chain (iobuf_t a)
962 if (!DBG_IOBUF)
963 return;
964 for (; a; a = a->chain)
966 size_t dummy_len = 0;
967 const char *desc = "[none]";
969 if (a->filter)
970 a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
971 (byte *) & desc, &dummy_len);
973 log_debug ("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n",
974 a->no, a->subno, desc, a->filter_eof,
975 (int) a->d.start, (int) a->d.len);
980 iobuf_print_chain (iobuf_t a)
982 print_chain (a);
983 return 0;
986 /****************
987 * Allocate a new io buffer, with no function assigned.
988 * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer
989 * BUFSIZE is a suggested buffer size.
991 iobuf_t
992 iobuf_alloc (int use, size_t bufsize)
994 iobuf_t a;
995 static int number = 0;
997 a = xcalloc (1, sizeof *a);
998 a->use = use;
999 a->d.buf = xmalloc (bufsize);
1000 a->d.size = bufsize;
1001 a->no = ++number;
1002 a->subno = 0;
1003 a->opaque = NULL;
1004 a->real_fname = NULL;
1005 return a;
1009 iobuf_close (iobuf_t a)
1011 iobuf_t a2;
1012 size_t dummy_len = 0;
1013 int rc = 0;
1015 if (a && a->directfp)
1017 fclose (a->directfp);
1018 xfree (a->real_fname);
1019 if (DBG_IOBUF)
1020 log_debug ("iobuf_close -> %p\n", a->directfp);
1021 return 0;
1024 for (; a && !rc; a = a2)
1026 a2 = a->chain;
1027 if (a->use == 2 && (rc = iobuf_flush (a)))
1028 log_error ("iobuf_flush failed on close: %s\n", gpg_strerror (rc));
1030 if (DBG_IOBUF)
1031 log_debug ("iobuf-%d.%d: close `%s'\n", a->no, a->subno, a->desc);
1032 if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1033 a->chain, NULL, &dummy_len)))
1034 log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1035 xfree (a->real_fname);
1036 if (a->d.buf)
1038 memset (a->d.buf, 0, a->d.size); /* erase the buffer */
1039 xfree (a->d.buf);
1041 xfree (a);
1043 return rc;
1047 iobuf_cancel (iobuf_t a)
1049 const char *s;
1050 iobuf_t a2;
1051 int rc;
1052 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1053 char *remove_name = NULL;
1054 #endif
1056 if (a && a->use == 2)
1058 s = iobuf_get_real_fname (a);
1059 if (s && *s)
1061 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1062 remove_name = xstrdup (s);
1063 #else
1064 remove (s);
1065 #endif
1069 /* send a cancel message to all filters */
1070 for (a2 = a; a2; a2 = a2->chain)
1072 size_t dummy;
1073 if (a2->filter)
1074 a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1077 rc = iobuf_close (a);
1078 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1079 if (remove_name)
1081 /* Argg, MSDOS does not allow to remove open files. So
1082 * we have to do it here */
1083 remove (remove_name);
1084 xfree (remove_name);
1086 #endif
1087 return rc;
1091 /****************
1092 * create a temporary iobuf, which can be used to collect stuff
1093 * in an iobuf and later be written by iobuf_write_temp() to another
1094 * iobuf.
1096 iobuf_t
1097 iobuf_temp ()
1099 iobuf_t a;
1101 a = iobuf_alloc (3, 8192);
1103 return a;
1106 iobuf_t
1107 iobuf_temp_with_content (const char *buffer, size_t length)
1109 iobuf_t a;
1111 a = iobuf_alloc (3, length);
1112 memcpy (a->d.buf, buffer, length);
1113 a->d.len = length;
1115 return a;
1118 void
1119 iobuf_enable_special_filenames (int yes)
1121 special_names_enabled = yes;
1125 /* See whether the filename has the form "-&nnnn", where n is a
1126 non-zero number. Returns this number or -1 if it is not the
1127 case. */
1128 static int
1129 check_special_filename (const char *fname)
1131 if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
1133 int i;
1135 fname += 2;
1136 for (i = 0; digitp (fname+i); i++)
1138 if (!fname[i])
1139 return atoi (fname);
1141 return -1;
1145 /* This fucntion returns true if FNAME indicates a PIPE (stdout or
1146 stderr) or a special file name if those are enabled. */
1148 iobuf_is_pipe_filename (const char *fname)
1150 if (!fname || (*fname=='-' && !fname[1]) )
1151 return 1;
1152 return check_special_filename (fname) != -1;
1155 /****************
1156 * Create a head iobuf for reading from a file
1157 * returns: NULL if an error occures and sets errno
1159 iobuf_t
1160 iobuf_open (const char *fname)
1162 iobuf_t a;
1163 FILEP_OR_FD fp;
1164 file_filter_ctx_t *fcx;
1165 size_t len;
1166 int print_only = 0;
1167 int fd;
1169 if (!fname || (*fname == '-' && !fname[1]))
1171 fp = FILEP_OR_FD_FOR_STDIN;
1172 #ifdef USE_SETMODE
1173 setmode (my_fileno (fp), O_BINARY);
1174 #endif
1175 fname = "[stdin]";
1176 print_only = 1;
1178 else if ((fd = check_special_filename (fname)) != -1)
1179 return iobuf_fdopen (translate_file_handle (fd, 0), "rb");
1180 else if ((fp = my_fopen_ro (fname, "rb")) == INVALID_FP)
1181 return NULL;
1182 a = iobuf_alloc (1, 8192);
1183 fcx = xmalloc (sizeof *fcx + strlen (fname));
1184 fcx->fp = fp;
1185 fcx->print_only_name = print_only;
1186 strcpy (fcx->fname, fname);
1187 if (!print_only)
1188 a->real_fname = xstrdup (fname);
1189 a->filter = file_filter;
1190 a->filter_ov = fcx;
1191 file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1192 file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1193 if (DBG_IOBUF)
1194 log_debug ("iobuf-%d.%d: open `%s' fd=%d\n",
1195 a->no, a->subno, fname, (int) my_fileno (fcx->fp));
1197 return a;
1200 /****************
1201 * Create a head iobuf for reading from a file
1202 * returns: NULL if an error occures and sets errno
1204 iobuf_t
1205 iobuf_fdopen (int fd, const char *mode)
1207 iobuf_t a;
1208 FILEP_OR_FD fp;
1209 file_filter_ctx_t *fcx;
1210 size_t len;
1212 #ifdef FILE_FILTER_USES_STDIO
1213 if (!(fp = fdopen (fd, mode)))
1214 return NULL;
1215 #else
1216 fp = (FILEP_OR_FD) fd;
1217 #endif
1218 a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192);
1219 fcx = xmalloc (sizeof *fcx + 20);
1220 fcx->fp = fp;
1221 fcx->print_only_name = 1;
1222 sprintf (fcx->fname, "[fd %d]", fd);
1223 a->filter = file_filter;
1224 a->filter_ov = fcx;
1225 file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1226 file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1227 if (DBG_IOBUF)
1228 log_debug ("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname);
1229 iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
1230 return a;
1234 iobuf_t
1235 iobuf_sockopen (int fd, const char *mode)
1237 iobuf_t a;
1238 #ifdef _WIN32
1239 sock_filter_ctx_t *scx;
1240 size_t len;
1242 a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192);
1243 scx = xmalloc (sizeof *scx + 25);
1244 scx->sock = fd;
1245 scx->print_only_name = 1;
1246 sprintf (scx->fname, "[sock %d]", fd);
1247 a->filter = sock_filter;
1248 a->filter_ov = scx;
1249 sock_filter (scx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1250 sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1251 if (DBG_IOBUF)
1252 log_debug ("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
1253 iobuf_ioctl (a, 3, 1, NULL); /* disable fd caching */
1254 #else
1255 a = iobuf_fdopen (fd, mode);
1256 #endif
1257 return a;
1260 /****************
1261 * create an iobuf for writing to a file; the file will be created.
1263 iobuf_t
1264 iobuf_create (const char *fname)
1266 iobuf_t a;
1267 FILEP_OR_FD fp;
1268 file_filter_ctx_t *fcx;
1269 size_t len;
1270 int print_only = 0;
1271 int fd;
1273 if (!fname || (*fname == '-' && !fname[1]))
1275 fp = FILEP_OR_FD_FOR_STDOUT;
1276 #ifdef USE_SETMODE
1277 setmode (my_fileno (fp), O_BINARY);
1278 #endif
1279 fname = "[stdout]";
1280 print_only = 1;
1282 else if ((fd = check_special_filename (fname)) != -1)
1283 return iobuf_fdopen (translate_file_handle (fd, 1), "wb");
1284 else if ((fp = my_fopen (fname, "wb")) == INVALID_FP)
1285 return NULL;
1286 a = iobuf_alloc (2, 8192);
1287 fcx = xmalloc (sizeof *fcx + strlen (fname));
1288 fcx->fp = fp;
1289 fcx->print_only_name = print_only;
1290 strcpy (fcx->fname, fname);
1291 if (!print_only)
1292 a->real_fname = xstrdup (fname);
1293 a->filter = file_filter;
1294 a->filter_ov = fcx;
1295 file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1296 file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1297 if (DBG_IOBUF)
1298 log_debug ("iobuf-%d.%d: create `%s'\n", a->no, a->subno, a->desc);
1300 return a;
1303 /****************
1304 * append to an iobuf; if the file does not exist, create it.
1305 * cannot be used for stdout.
1306 * Note: This is not used.
1308 #if 0 /* not used */
1309 iobuf_t
1310 iobuf_append (const char *fname)
1312 iobuf_t a;
1313 FILE *fp;
1314 file_filter_ctx_t *fcx;
1315 size_t len;
1317 if (!fname)
1318 return NULL;
1319 else if (!(fp = my_fopen (fname, "ab")))
1320 return NULL;
1321 a = iobuf_alloc (2, 8192);
1322 fcx = m_alloc (sizeof *fcx + strlen (fname));
1323 fcx->fp = fp;
1324 strcpy (fcx->fname, fname);
1325 a->real_fname = m_strdup (fname);
1326 a->filter = file_filter;
1327 a->filter_ov = fcx;
1328 file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1329 file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1330 if (DBG_IOBUF)
1331 log_debug ("iobuf-%d.%d: append `%s'\n", a->no, a->subno, a->desc);
1333 return a;
1335 #endif
1337 iobuf_t
1338 iobuf_openrw (const char *fname)
1340 iobuf_t a;
1341 FILEP_OR_FD fp;
1342 file_filter_ctx_t *fcx;
1343 size_t len;
1345 if (!fname)
1346 return NULL;
1347 else if ((fp = my_fopen (fname, "r+b")) == INVALID_FP)
1348 return NULL;
1349 a = iobuf_alloc (2, 8192);
1350 fcx = xmalloc (sizeof *fcx + strlen (fname));
1351 fcx->fp = fp;
1352 strcpy (fcx->fname, fname);
1353 a->real_fname = xstrdup (fname);
1354 a->filter = file_filter;
1355 a->filter_ov = fcx;
1356 file_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len);
1357 file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1358 if (DBG_IOBUF)
1359 log_debug ("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, a->desc);
1361 return a;
1366 iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
1368 if (cmd == 1)
1369 { /* keep system filepointer/descriptor open */
1370 if (DBG_IOBUF)
1371 log_debug ("iobuf-%d.%d: ioctl `%s' keep=%d\n",
1372 a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?",
1373 intval);
1374 for (; a; a = a->chain)
1375 if (!a->chain && a->filter == file_filter)
1377 file_filter_ctx_t *b = a->filter_ov;
1378 b->keep_open = intval;
1379 return 0;
1381 #ifdef _WIN32
1382 else if (!a->chain && a->filter == sock_filter)
1384 sock_filter_ctx_t *b = a->filter_ov;
1385 b->keep_open = intval;
1386 return 0;
1388 #endif
1390 else if (cmd == 2)
1391 { /* invalidate cache */
1392 if (DBG_IOBUF)
1393 log_debug ("iobuf-*.*: ioctl `%s' invalidate\n",
1394 ptrval ? (char *) ptrval : "?");
1395 if (!a && !intval && ptrval)
1397 #ifndef FILE_FILTER_USES_STDIO
1398 fd_cache_invalidate (ptrval);
1399 #endif
1400 return 0;
1403 else if (cmd == 3)
1404 { /* disallow/allow caching */
1405 if (DBG_IOBUF)
1406 log_debug ("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
1407 a ? a->no : -1, a ? a->subno : -1, a ? a->desc : "?",
1408 intval);
1409 for (; a; a = a->chain)
1410 if (!a->chain && a->filter == file_filter)
1412 file_filter_ctx_t *b = a->filter_ov;
1413 b->no_cache = intval;
1414 return 0;
1416 #ifdef _WIN32
1417 else if (!a->chain && a->filter == sock_filter)
1419 sock_filter_ctx_t *b = a->filter_ov;
1420 b->no_cache = intval;
1421 return 0;
1423 #endif
1426 return -1;
1430 /****************
1431 * Register an i/o filter.
1434 iobuf_push_filter (iobuf_t a,
1435 int (*f) (void *opaque, int control,
1436 iobuf_t chain, byte * buf, size_t * len),
1437 void *ov)
1439 return iobuf_push_filter2 (a, f, ov, 0);
1443 iobuf_push_filter2 (iobuf_t a,
1444 int (*f) (void *opaque, int control,
1445 iobuf_t chain, byte * buf, size_t * len),
1446 void *ov, int rel_ov)
1448 iobuf_t b;
1449 size_t dummy_len = 0;
1450 int rc = 0;
1452 if (a->directfp)
1453 BUG ();
1455 if (a->use == 2 && (rc = iobuf_flush (a)))
1456 return rc;
1457 /* make a copy of the current stream, so that
1458 * A is the new stream and B the original one.
1459 * The contents of the buffers are transferred to the
1460 * new stream.
1462 b = xmalloc (sizeof *b);
1463 memcpy (b, a, sizeof *b);
1464 /* fixme: it is stupid to keep a copy of the name at every level
1465 * but we need the name somewhere because the name known by file_filter
1466 * may have been released when we need the name of the file */
1467 b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1468 /* remove the filter stuff from the new stream */
1469 a->filter = NULL;
1470 a->filter_ov = NULL;
1471 a->filter_ov_owner = 0;
1472 a->filter_eof = 0;
1473 if (a->use == 3)
1474 a->use = 2; /* make a write stream from a temp stream */
1476 if (a->use == 2)
1477 { /* allocate a fresh buffer for the
1478 original stream */
1479 b->d.buf = xmalloc (a->d.size);
1480 b->d.len = 0;
1481 b->d.start = 0;
1483 else
1484 { /* allocate a fresh buffer for the new
1485 stream */
1486 a->d.buf = xmalloc (a->d.size);
1487 a->d.len = 0;
1488 a->d.start = 0;
1490 /* disable nlimit for the new stream */
1491 a->ntotal = b->ntotal + b->nbytes;
1492 a->nlimit = a->nbytes = 0;
1493 a->nofast &= ~1;
1494 /* make a link from the new stream to the original stream */
1495 a->chain = b;
1496 a->opaque = b->opaque;
1498 /* setup the function on the new stream */
1499 a->filter = f;
1500 a->filter_ov = ov;
1501 a->filter_ov_owner = rel_ov;
1503 a->subno = b->subno + 1;
1504 f (ov, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &dummy_len);
1506 if (DBG_IOBUF)
1508 log_debug ("iobuf-%d.%d: push `%s'\n", a->no, a->subno, a->desc);
1509 print_chain (a);
1512 /* now we can initialize the new function if we have one */
1513 if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1514 NULL, &dummy_len)))
1515 log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1516 return rc;
1519 /****************
1520 * Remove an i/o filter.
1522 static int
1523 pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1524 iobuf_t chain, byte * buf, size_t * len),
1525 void *ov)
1527 iobuf_t b;
1528 size_t dummy_len = 0;
1529 int rc = 0;
1531 if (a->directfp)
1532 BUG ();
1534 if (DBG_IOBUF)
1535 log_debug ("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, a->desc);
1536 if (!a->filter)
1537 { /* this is simple */
1538 b = a->chain;
1539 assert (b);
1540 xfree (a->d.buf);
1541 xfree (a->real_fname);
1542 memcpy (a, b, sizeof *a);
1543 xfree (b);
1544 return 0;
1546 for (b = a; b; b = b->chain)
1547 if (b->filter == f && (!ov || b->filter_ov == ov))
1548 break;
1549 if (!b)
1550 log_bug ("pop_filter(): filter function not found\n");
1552 /* flush this stream if it is an output stream */
1553 if (a->use == 2 && (rc = iobuf_flush (b)))
1555 log_error ("iobuf_flush failed in pop_filter: %s\n", gpg_strerror (rc));
1556 return rc;
1558 /* and tell the filter to free it self */
1559 if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1560 NULL, &dummy_len)))
1562 log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1563 return rc;
1565 if (b->filter_ov && b->filter_ov_owner)
1567 xfree (b->filter_ov);
1568 b->filter_ov = NULL;
1572 /* and see how to remove it */
1573 if (a == b && !b->chain)
1574 log_bug ("can't remove the last filter from the chain\n");
1575 else if (a == b)
1576 { /* remove the first iobuf from the chain */
1577 /* everything from b is copied to a. This is save because
1578 * a flush has been done on the to be removed entry
1580 b = a->chain;
1581 xfree (a->d.buf);
1582 xfree (a->real_fname);
1583 memcpy (a, b, sizeof *a);
1584 xfree (b);
1585 if (DBG_IOBUF)
1586 log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1588 else if (!b->chain)
1589 { /* remove the last iobuf from the chain */
1590 log_bug ("Ohh jeee, trying to remove a head filter\n");
1592 else
1593 { /* remove an intermediate iobuf from the chain */
1594 log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1597 return rc;
1601 /****************
1602 * read underflow: read more bytes into the buffer and return
1603 * the first byte or -1 on EOF.
1605 static int
1606 underflow (iobuf_t a)
1608 size_t len;
1609 int rc;
1611 assert (a->d.start == a->d.len);
1612 if (a->use == 3)
1613 return -1; /* EOF because a temp buffer can't do an underflow */
1615 if (a->filter_eof)
1617 if (a->chain)
1619 iobuf_t b = a->chain;
1620 if (DBG_IOBUF)
1621 log_debug ("iobuf-%d.%d: pop `%s' in underflow\n",
1622 a->no, a->subno, a->desc);
1623 xfree (a->d.buf);
1624 xfree (a->real_fname);
1625 memcpy (a, b, sizeof *a);
1626 xfree (b);
1627 print_chain (a);
1629 else
1630 a->filter_eof = 0; /* for the top level filter */
1631 if (DBG_IOBUF)
1632 log_debug ("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
1633 a->no, a->subno);
1634 return -1; /* return one(!) EOF */
1636 if (a->error)
1638 if (DBG_IOBUF)
1639 log_debug ("iobuf-%d.%d: error\n", a->no, a->subno);
1640 return -1;
1643 if (a->directfp)
1645 FILE *fp = a->directfp;
1647 len = fread (a->d.buf, 1, a->d.size, fp);
1648 if (len < a->d.size)
1650 if (ferror (fp))
1651 a->error = gpg_error_from_syserror ();
1653 a->d.len = len;
1654 a->d.start = 0;
1655 return len ? a->d.buf[a->d.start++] : -1;
1659 if (a->filter)
1661 len = a->d.size;
1662 if (DBG_IOBUF)
1663 log_debug ("iobuf-%d.%d: underflow: req=%lu\n",
1664 a->no, a->subno, (ulong) len);
1665 rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1666 a->d.buf, &len);
1667 if (DBG_IOBUF)
1669 log_debug ("iobuf-%d.%d: underflow: got=%lu rc=%d\n",
1670 a->no, a->subno, (ulong) len, rc);
1671 /* if( a->no == 1 ) */
1672 /* log_hexdump (" data:", a->d.buf, len); */
1674 if (a->use == 1 && rc == -1)
1675 { /* EOF: we can remove the filter */
1676 size_t dummy_len = 0;
1678 /* and tell the filter to free itself */
1679 if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
1680 NULL, &dummy_len)))
1681 log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1682 if (a->filter_ov && a->filter_ov_owner)
1684 xfree (a->filter_ov);
1685 a->filter_ov = NULL;
1687 a->filter = NULL;
1688 a->desc = NULL;
1689 a->filter_ov = NULL;
1690 a->filter_eof = 1;
1691 if (!len && a->chain)
1693 iobuf_t b = a->chain;
1694 if (DBG_IOBUF)
1695 log_debug ("iobuf-%d.%d: pop `%s' in underflow (!len)\n",
1696 a->no, a->subno, a->desc);
1697 xfree (a->d.buf);
1698 xfree (a->real_fname);
1699 memcpy (a, b, sizeof *a);
1700 xfree (b);
1701 print_chain (a);
1704 else if (rc)
1705 a->error = rc;
1707 if (!len)
1709 if (DBG_IOBUF)
1710 log_debug ("iobuf-%d.%d: underflow: eof\n", a->no, a->subno);
1711 return -1;
1713 a->d.len = len;
1714 a->d.start = 0;
1715 return a->d.buf[a->d.start++];
1717 else
1719 if (DBG_IOBUF)
1720 log_debug ("iobuf-%d.%d: underflow: eof (no filter)\n",
1721 a->no, a->subno);
1722 return -1; /* no filter; return EOF */
1728 iobuf_flush (iobuf_t a)
1730 size_t len;
1731 int rc;
1733 if (a->directfp)
1734 return 0;
1736 if (a->use == 3)
1737 { /* increase the temp buffer */
1738 unsigned char *newbuf;
1739 size_t newsize = a->d.size + 8192;
1741 if (DBG_IOBUF)
1742 log_debug ("increasing temp iobuf from %lu to %lu\n",
1743 (ulong) a->d.size, (ulong) newsize);
1744 newbuf = xmalloc (newsize);
1745 memcpy (newbuf, a->d.buf, a->d.len);
1746 xfree (a->d.buf);
1747 a->d.buf = newbuf;
1748 a->d.size = newsize;
1749 return 0;
1751 else if (a->use != 2)
1752 log_bug ("flush on non-output iobuf\n");
1753 else if (!a->filter)
1754 log_bug ("iobuf_flush: no filter\n");
1755 len = a->d.len;
1756 rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
1757 if (!rc && len != a->d.len)
1759 log_info ("iobuf_flush did not write all!\n");
1760 rc = GPG_ERR_INTERNAL;
1762 else if (rc)
1763 a->error = rc;
1764 a->d.len = 0;
1766 return rc;
1770 /****************
1771 * Read a byte from the iobuf; returns -1 on EOF
1774 iobuf_readbyte (iobuf_t a)
1776 int c;
1778 /* nlimit does not work together with unget */
1779 /* nbytes is also not valid! */
1780 if (a->unget.buf)
1782 if (a->unget.start < a->unget.len)
1783 return a->unget.buf[a->unget.start++];
1784 xfree (a->unget.buf);
1785 a->unget.buf = NULL;
1786 a->nofast &= ~2;
1789 if (a->nlimit && a->nbytes >= a->nlimit)
1790 return -1; /* forced EOF */
1792 if (a->d.start < a->d.len)
1794 c = a->d.buf[a->d.start++];
1796 else if ((c = underflow (a)) == -1)
1797 return -1; /* EOF */
1799 a->nbytes++;
1800 return c;
1805 iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
1807 unsigned char *buf = (unsigned char *)buffer;
1808 int c, n;
1810 if (a->unget.buf || a->nlimit)
1812 /* handle special cases */
1813 for (n = 0; n < buflen; n++)
1815 if ((c = iobuf_readbyte (a)) == -1)
1817 if (!n)
1818 return -1; /* eof */
1819 break;
1821 else if (buf)
1822 *buf = c;
1823 if (buf)
1824 buf++;
1826 return n;
1829 n = 0;
1832 if (n < buflen && a->d.start < a->d.len)
1834 unsigned size = a->d.len - a->d.start;
1835 if (size > buflen - n)
1836 size = buflen - n;
1837 if (buf)
1838 memcpy (buf, a->d.buf + a->d.start, size);
1839 n += size;
1840 a->d.start += size;
1841 if (buf)
1842 buf += size;
1844 if (n < buflen)
1846 if ((c = underflow (a)) == -1)
1848 a->nbytes += n;
1849 return n ? n : -1 /*EOF*/;
1851 if (buf)
1852 *buf++ = c;
1853 n++;
1856 while (n < buflen);
1857 a->nbytes += n;
1858 return n;
1862 /****************
1863 * Have a look at the iobuf.
1864 * NOTE: This only works in special cases.
1867 iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
1869 int n = 0;
1871 if (a->filter_eof)
1872 return -1;
1874 if (!(a->d.start < a->d.len))
1876 if (underflow (a) == -1)
1877 return -1;
1878 /* and unget this character */
1879 assert (a->d.start == 1);
1880 a->d.start = 0;
1883 for (n = 0; n < buflen && (a->d.start + n) < a->d.len; n++, buf++)
1884 *buf = a->d.buf[n];
1885 return n;
1892 iobuf_writebyte (iobuf_t a, unsigned int c)
1894 int rc;
1896 if (a->directfp)
1897 BUG ();
1899 if (a->d.len == a->d.size)
1900 if ((rc=iobuf_flush (a)))
1901 return rc;
1903 assert (a->d.len < a->d.size);
1904 a->d.buf[a->d.len++] = c;
1905 return 0;
1910 iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
1912 const unsigned char *buf = (const unsigned char *)buffer;
1913 int rc;
1915 if (a->directfp)
1916 BUG ();
1920 if (buflen && a->d.len < a->d.size)
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;
1930 if (buflen)
1932 rc = iobuf_flush (a);
1933 if (rc)
1934 return rc;
1937 while (buflen);
1938 return 0;
1943 iobuf_writestr (iobuf_t a, const char *buf)
1945 int rc;
1947 for (; *buf; buf++)
1948 if ((rc=iobuf_writebyte (a, *buf)))
1949 return rc;
1950 return 0;
1955 /****************
1956 * copy the contents of TEMP to A.
1959 iobuf_write_temp (iobuf_t a, iobuf_t temp)
1961 while (temp->chain)
1962 pop_filter (temp, temp->filter, NULL);
1963 return iobuf_write (a, temp->d.buf, temp->d.len);
1966 /****************
1967 * copy the contents of the temp io stream to BUFFER.
1969 size_t
1970 iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
1972 size_t n = a->d.len;
1974 if (n > buflen)
1975 n = buflen;
1976 memcpy (buffer, a->d.buf, n);
1977 return n;
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.
1987 void
1988 iobuf_flush_temp (iobuf_t temp)
1990 while (temp->chain)
1991 pop_filter (temp, temp->filter, NULL);
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.
1999 void
2000 iobuf_set_limit (iobuf_t a, off_t nlimit)
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;
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)
2019 struct stat st;
2021 if (overflow)
2022 *overflow = 0;
2024 if( a->directfp ) {
2025 FILE *fp = a->directfp;
2027 if( !fstat(fileno(fp), &st) )
2028 return st.st_size;
2029 log_error("fstat() failed: %s\n", strerror(errno) );
2030 return 0;
2033 /* Hmmm: file_filter may have already been removed */
2034 for( ; a; a = a->chain )
2035 if( !a->chain && a->filter == file_filter ) {
2036 file_filter_ctx_t *b = a->filter_ov;
2037 FILEP_OR_FD fp = b->fp;
2039 #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
2040 ulong size;
2041 static int (* __stdcall get_file_size_ex)
2042 (void *handle, LARGE_INTEGER *size);
2043 static int get_file_size_ex_initialized;
2045 if (!get_file_size_ex_initialized)
2047 void *handle;
2049 handle = dlopen ("kernel32.dll", RTLD_LAZY);
2050 if (handle)
2052 get_file_size_ex = dlsym (handle, "GetFileSizeEx");
2053 if (!get_file_size_ex)
2054 dlclose (handle);
2056 get_file_size_ex_initialized = 1;
2059 if (get_file_size_ex)
2061 /* This is a newer system with GetFileSizeEx; we use
2062 this then becuase it seem that GetFileSize won't
2063 return a proper error in case a file is larger than
2064 4GB. */
2065 LARGE_INTEGER size;
2067 if (get_file_size_ex (fp, &size))
2069 if (!size.u.HighPart)
2070 return size.u.LowPart;
2071 if (overflow)
2072 *overflow = 1;
2073 return 0;
2076 else
2078 if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
2079 return size;
2081 log_error ("GetFileSize for handle %p failed: %s\n",
2082 fp, w32_strerror (0));
2083 #else
2084 if( !fstat(my_fileno(fp), &st) )
2085 return st.st_size;
2086 log_error("fstat() failed: %s\n", strerror(errno) );
2087 #endif
2088 break;
2091 return 0;
2095 /* Return the file descriptor of the underlying file or -1 if it is
2096 not available. */
2097 int
2098 iobuf_get_fd (iobuf_t a)
2100 if (a->directfp)
2101 return fileno ( (FILE*)a->directfp );
2103 for ( ; a; a = a->chain )
2104 if (!a->chain && a->filter == file_filter)
2106 file_filter_ctx_t *b = a->filter_ov;
2107 FILEP_OR_FD fp = b->fp;
2109 return my_fileno (fp);
2112 return -1;
2117 /****************
2118 * Tell the file position, where the next read will take place
2120 off_t
2121 iobuf_tell (iobuf_t a)
2123 return a->ntotal + a->nbytes;
2127 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2129 #ifdef HAVE_LIMITS_H
2130 # include <limits.h>
2131 #endif
2132 #ifndef LONG_MAX
2133 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2134 #endif
2135 #ifndef LONG_MIN
2136 # define LONG_MIN (-1 - LONG_MAX)
2137 #endif
2139 /****************
2140 * A substitute for fseeko, for hosts that don't have it.
2142 static int
2143 fseeko (FILE * stream, off_t newpos, int whence)
2145 while (newpos != (long) newpos)
2147 long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2148 if (fseek (stream, pos, whence) != 0)
2149 return -1;
2150 newpos -= pos;
2151 whence = SEEK_CUR;
2153 return fseek (stream, (long) newpos, whence);
2155 #endif
2157 /****************
2158 * This is a very limited implementation. It simply discards all internal
2159 * buffering and removes all filters but the first one.
2162 iobuf_seek (iobuf_t a, off_t newpos)
2164 file_filter_ctx_t *b = NULL;
2166 if (a->directfp)
2168 FILE *fp = a->directfp;
2169 if (fseeko (fp, newpos, SEEK_SET))
2171 log_error ("can't seek: %s\n", strerror (errno));
2172 return -1;
2174 clearerr (fp);
2176 else
2178 for (; a; a = a->chain)
2180 if (!a->chain && a->filter == file_filter)
2182 b = a->filter_ov;
2183 break;
2186 if (!a)
2187 return -1;
2188 #ifdef FILE_FILTER_USES_STDIO
2189 if (fseeko (b->fp, newpos, SEEK_SET))
2191 log_error ("can't fseek: %s\n", strerror (errno));
2192 return -1;
2194 #else
2195 #ifdef HAVE_DOSISH_SYSTEM
2196 if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2198 log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2199 b->fp, (int) GetLastError ());
2200 return -1;
2202 #else
2203 if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2205 log_error ("can't lseek: %s\n", strerror (errno));
2206 return -1;
2208 #endif
2209 #endif
2211 a->d.len = 0; /* discard buffer */
2212 a->d.start = 0;
2213 a->nbytes = 0;
2214 a->nlimit = 0;
2215 a->nofast &= ~1;
2216 a->ntotal = newpos;
2217 a->error = 0;
2218 /* remove filters, but the last */
2219 if (a->chain)
2220 log_debug ("pop_filter called in iobuf_seek - please report\n");
2221 while (a->chain)
2222 pop_filter (a, a->filter, NULL);
2224 return 0;
2232 /****************
2233 * Retrieve the real filename
2235 const char *
2236 iobuf_get_real_fname (iobuf_t a)
2238 if (a->real_fname)
2239 return a->real_fname;
2241 /* the old solution */
2242 for (; a; a = a->chain)
2243 if (!a->chain && a->filter == file_filter)
2245 file_filter_ctx_t *b = a->filter_ov;
2246 return b->print_only_name ? NULL : b->fname;
2249 return NULL;
2253 /****************
2254 * Retrieve the filename
2256 const char *
2257 iobuf_get_fname (iobuf_t a)
2259 for (; a; a = a->chain)
2260 if (!a->chain && a->filter == file_filter)
2262 file_filter_ctx_t *b = a->filter_ov;
2263 return b->fname;
2266 return NULL;
2270 /****************
2271 * enable partial block mode as described in the OpenPGP draft.
2272 * LEN is the first length byte on read, but ignored on writes.
2274 void
2275 iobuf_set_partial_block_mode (iobuf_t a, size_t len)
2277 block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2279 assert (a->use == 1 || a->use == 2);
2280 ctx->use = a->use;
2281 if (!len)
2283 if (a->use == 1)
2284 log_debug ("pop_filter called in set_partial_block_mode"
2285 " - please report\n");
2286 pop_filter (a, block_filter, NULL);
2288 else
2290 ctx->partial = 1;
2291 ctx->size = 0;
2292 ctx->first_c = len;
2293 iobuf_push_filter (a, block_filter, ctx);
2299 /****************
2300 * Same as fgets() but if the buffer is too short a larger one will
2301 * be allocated up to some limit *max_length.
2302 * A line is considered a byte stream ending in a LF.
2303 * Returns the length of the line. EOF is indicated by a line of
2304 * length zero. The last LF may be missing due to an EOF.
2305 * is max_length is zero on return, the line has been truncated.
2307 * Note: The buffer is allocated with enough space to append a CR,LF,EOL
2309 unsigned int
2310 iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2311 unsigned *length_of_buffer, unsigned *max_length)
2313 int c;
2314 char *buffer = (char *)*addr_of_buffer;
2315 unsigned length = *length_of_buffer;
2316 unsigned nbytes = 0;
2317 unsigned maxlen = *max_length;
2318 char *p;
2320 if (!buffer)
2321 { /* must allocate a new buffer */
2322 length = 256;
2323 buffer = xmalloc (length);
2324 *addr_of_buffer = (unsigned char *)buffer;
2325 *length_of_buffer = length;
2328 length -= 3; /* reserve 3 bytes (cr,lf,eol) */
2329 p = buffer;
2330 while ((c = iobuf_get (a)) != -1)
2332 if (nbytes == length)
2333 { /* increase the buffer */
2334 if (length > maxlen)
2335 { /* this is out limit */
2336 /* skip the rest of the line */
2337 while (c != '\n' && (c = iobuf_get (a)) != -1)
2339 *p++ = '\n'; /* always append a LF (we have reserved space) */
2340 nbytes++;
2341 *max_length = 0; /* indicate truncation */
2342 break;
2344 length += 3; /* correct for the reserved byte */
2345 length += length < 1024 ? 256 : 1024;
2346 buffer = xrealloc (buffer, length);
2347 *addr_of_buffer = (unsigned char *)buffer;
2348 *length_of_buffer = length;
2349 length -= 3; /* and reserve again */
2350 p = buffer + nbytes;
2352 *p++ = c;
2353 nbytes++;
2354 if (c == '\n')
2355 break;
2357 *p = 0; /* make sure the line is a string */
2359 return nbytes;
2362 /* This is the non iobuf specific function */
2364 iobuf_translate_file_handle (int fd, int for_write)
2366 #ifdef _WIN32
2368 int x;
2370 if (fd <= 2)
2371 return fd; /* do not do this for error, stdin, stdout, stderr */
2373 x = _open_osfhandle (fd, for_write ? 1 : 0);
2374 if (x == -1)
2375 log_error ("failed to translate osfhandle %p\n", (void *) fd);
2376 else
2378 /*log_info ("_open_osfhandle %p yields %d%s\n",
2379 (void*)fd, x, for_write? " for writing":"" ); */
2380 fd = x;
2383 #endif
2384 return fd;
2387 static int
2388 translate_file_handle (int fd, int for_write)
2390 #ifdef _WIN32
2391 #ifdef FILE_FILTER_USES_STDIO
2392 fd = iobuf_translate_file_handle (fd, for_write);
2393 #else
2395 int x;
2397 if (fd == 0)
2398 x = (int) GetStdHandle (STD_INPUT_HANDLE);
2399 else if (fd == 1)
2400 x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2401 else if (fd == 2)
2402 x = (int) GetStdHandle (STD_ERROR_HANDLE);
2403 else
2404 x = fd;
2406 if (x == -1)
2407 log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2408 fd, (int) GetLastError ());
2410 fd = x;
2412 #endif
2413 #endif
2414 return fd;
2418 void
2419 iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2421 if ( partial )
2423 for (;;)
2425 if (a->nofast || a->d.start >= a->d.len)
2427 if (iobuf_readbyte (a) == -1)
2429 break;
2432 else
2434 unsigned long count = a->d.len - a->d.start;
2435 a->nbytes += count;
2436 a->d.start = a->d.len;
2440 else
2442 unsigned long remaining = n;
2443 while (remaining > 0)
2445 if (a->nofast || a->d.start >= a->d.len)
2447 if (iobuf_readbyte (a) == -1)
2449 break;
2451 --remaining;
2453 else
2455 unsigned long count = a->d.len - a->d.start;
2456 if (count > remaining)
2458 count = remaining;
2460 a->nbytes += count;
2461 a->d.start += count;
2462 remaining -= count;