* exec.c (make_tempdir) [_WIN32]: Modified to properly handle
[gnupg.git] / util / iobuf.c
blob09eda49e709868b3f106f4f7c7d4775a1dbca2eb
1 /* iobuf.c - file handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3 * 2004 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 "memory.h"
43 #include "util.h"
44 #include "dynload.h"
45 #include "iobuf.h"
47 /* The size of the internal buffers.
48 NOTE: If you change this value you MUST also adjust the regression
49 test "armored_key_8192" in armor.test! */
50 #define IOBUF_BUFFER_SIZE 8192
53 #undef FILE_FILTER_USES_STDIO
55 #ifdef HAVE_DOSISH_SYSTEM
56 #define USE_SETMODE 1
57 #endif
59 #ifdef FILE_FILTER_USES_STDIO
60 #define my_fileno(a) fileno ((a))
61 #define my_fopen_ro(a,b) fopen ((a),(b))
62 #define my_fopen(a,b) fopen ((a),(b))
63 typedef FILE *FILEP_OR_FD;
64 #define INVALID_FP NULL
65 #define FILEP_OR_FD_FOR_STDIN (stdin)
66 #define FILEP_OR_FD_FOR_STDOUT (stdout)
67 typedef struct {
68 FILE *fp; /* open file handle */
69 int keep_open;
70 int no_cache;
71 int print_only_name; /* flags indicating that fname is not a real file*/
72 char fname[1]; /* name of the file */
73 } file_filter_ctx_t ;
74 #else
75 #define my_fileno(a) (a)
76 #define my_fopen_ro(a,b) fd_cache_open ((a),(b))
77 #define my_fopen(a,b) direct_open ((a),(b))
78 #ifdef HAVE_DOSISH_SYSTEM
79 typedef HANDLE FILEP_OR_FD;
80 #define INVALID_FP ((HANDLE)-1)
81 #define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
82 #define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
83 #undef USE_SETMODE
84 #else
85 typedef int FILEP_OR_FD;
86 #define INVALID_FP (-1)
87 #define FILEP_OR_FD_FOR_STDIN (0)
88 #define FILEP_OR_FD_FOR_STDOUT (1)
89 #endif
90 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 */
97 } file_filter_ctx_t ;
99 struct close_cache_s {
100 struct close_cache_s *next;
101 FILEP_OR_FD fp;
102 char fname[1];
104 typedef struct close_cache_s *CLOSE_CACHE;
105 static CLOSE_CACHE close_cache;
106 #endif
108 #ifdef _WIN32
109 typedef struct {
110 int sock;
111 int keep_open;
112 int no_cache;
113 int eof_seen;
114 int print_only_name; /* flags indicating that fname is not a real file*/
115 char fname[1]; /* name of the file */
116 } sock_filter_ctx_t ;
117 #endif /*_WIN32*/
119 /* The first partial length header block must be of size 512
120 * to make it easier (and efficienter) we use a min. block size of 512
121 * for all chunks (but the last one) */
122 #define OP_MIN_PARTIAL_CHUNK 512
123 #define OP_MIN_PARTIAL_CHUNK_2POW 9
125 typedef struct {
126 int use;
127 size_t size;
128 size_t count;
129 int partial; /* 1 = partial header, 2 in last partial packet */
130 char *buffer; /* used for partial header */
131 size_t buflen; /* used size of buffer */
132 int first_c; /* of partial header (which is > 0)*/
133 int eof;
134 } block_filter_ctx_t;
136 static int special_names_enabled;
138 static int underflow(IOBUF a);
139 static int translate_file_handle ( int fd, int for_write );
143 #ifndef FILE_FILTER_USES_STDIO
145 /* This is a replacement for strcmp. Under W32 it does not
146 distinguish between backslash and slash. */
147 static int
148 fd_cache_strcmp (const char *a, const char *b)
150 #ifdef HAVE_DOSISH_SYSTEM
151 for (; *a && *b; a++, b++)
153 if (*a != *b && !((*a == '/' && *b == '\\')
154 || (*a == '\\' && *b == '/')) )
155 break;
157 return *(const unsigned char *)a - *(const unsigned char *)b;
158 #else
159 return strcmp (a, b);
160 #endif
164 * Invalidate (i.e. close) a cached iobuf
166 static void
167 fd_cache_invalidate (const char *fname)
169 CLOSE_CACHE cc;
171 assert (fname);
172 if( DBG_IOBUF )
173 log_debug ("fd_cache_invalidate (%s)\n", fname);
175 for (cc=close_cache; cc; cc = cc->next ) {
176 if ( cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname) ) {
177 if( DBG_IOBUF )
178 log_debug (" did (%s)\n", cc->fname);
179 #ifdef HAVE_DOSISH_SYSTEM
180 CloseHandle (cc->fp);
181 #else
182 close(cc->fp);
183 #endif
184 cc->fp = INVALID_FP;
191 static FILEP_OR_FD
192 direct_open (const char *fname, const char *mode)
194 #ifdef HAVE_DOSISH_SYSTEM
195 unsigned long da, cd, sm;
196 HANDLE hfile;
198 /* Note, that we do not handle all mode combinations */
200 /* According to the ReactOS source it seems that open() of the
201 * standard MSW32 crt does open the file in share mode which is
202 * something new for MS applications ;-)
204 if ( strchr (mode, '+') ) {
205 fd_cache_invalidate (fname);
206 da = GENERIC_READ|GENERIC_WRITE;
207 cd = OPEN_EXISTING;
208 sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
210 else if ( strchr (mode, 'w') ) {
211 fd_cache_invalidate (fname);
212 da = GENERIC_WRITE;
213 cd = CREATE_ALWAYS;
214 sm = FILE_SHARE_WRITE;
216 else {
217 da = GENERIC_READ;
218 cd = OPEN_EXISTING;
219 sm = FILE_SHARE_READ;
222 hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
223 return hfile;
224 #else
225 int oflag;
226 int cflag = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
228 /* Note, that we do not handle all mode combinations */
229 if ( strchr (mode, '+') ) {
230 fd_cache_invalidate (fname);
231 oflag = O_RDWR;
233 else if ( strchr (mode, 'w') ) {
234 fd_cache_invalidate (fname);
235 oflag = O_WRONLY | O_CREAT | O_TRUNC;
237 else {
238 oflag = O_RDONLY;
240 #ifdef O_BINARY
241 if (strchr (mode, 'b'))
242 oflag |= O_BINARY;
243 #endif
244 #ifndef __riscos__
245 return open (fname, oflag, cflag );
246 #else
248 struct stat buf;
249 int rc = stat( fname, &buf );
251 /* Don't allow iobufs on directories */
252 if( !rc && S_ISDIR(buf.st_mode) && !S_ISREG(buf.st_mode) )
253 return __set_errno( EISDIR );
254 else
255 return open( fname, oflag, cflag );
257 #endif
258 #endif
263 * Instead of closing an FD we keep it open and cache it for later reuse
264 * Note that this caching strategy only works if the process does not chdir.
266 static void
267 fd_cache_close (const char *fname, FILEP_OR_FD fp)
269 CLOSE_CACHE cc;
271 assert (fp);
272 if ( !fname || !*fname ) {
273 #ifdef HAVE_DOSISH_SYSTEM
274 CloseHandle (fp);
275 #else
276 close(fp);
277 #endif
278 if( DBG_IOBUF )
279 log_debug ("fd_cache_close (%p) real\n", (void*)fp);
280 return;
282 /* try to reuse a slot */
283 for (cc=close_cache; cc; cc = cc->next ) {
284 if ( cc->fp == INVALID_FP && !fd_cache_strcmp (cc->fname, fname) ) {
285 cc->fp = fp;
286 if( DBG_IOBUF )
287 log_debug ("fd_cache_close (%s) used existing slot\n", fname);
288 return;
291 /* add a new one */
292 if( DBG_IOBUF )
293 log_debug ("fd_cache_close (%s) new slot created\n", fname);
294 cc = xmalloc_clear (sizeof *cc + strlen (fname));
295 strcpy (cc->fname, fname);
296 cc->fp = fp;
297 cc->next = close_cache;
298 close_cache = cc;
302 * Do an direct_open on FNAME but first try to reuse one from the fd_cache
304 static FILEP_OR_FD
305 fd_cache_open (const char *fname, const char *mode)
307 CLOSE_CACHE cc;
309 assert (fname);
310 for (cc=close_cache; cc; cc = cc->next ) {
311 if ( cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname) ) {
312 FILEP_OR_FD fp = cc->fp;
313 cc->fp = INVALID_FP;
314 if( DBG_IOBUF )
315 log_debug ("fd_cache_open (%s) using cached fp\n", fname);
316 #ifdef HAVE_DOSISH_SYSTEM
317 if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff ) {
318 log_error ("rewind file failed on handle %p: %s\n",
319 fp, w32_strerror (errno));
320 fp = INVALID_FP;
322 #else
323 if ( lseek (fp, 0, SEEK_SET) == (off_t)-1 ) {
324 log_error("can't rewind fd %d: %s\n", fp, strerror(errno) );
325 fp = INVALID_FP;
327 #endif
328 return fp;
331 if( DBG_IOBUF )
332 log_debug ("fd_cache_open (%s) not cached\n", fname);
333 return direct_open (fname, mode);
337 #endif /*FILE_FILTER_USES_STDIO*/
340 /****************
341 * Read data from a file into buf which has an allocated length of *LEN.
342 * return the number of read bytes in *LEN. OPAQUE is the FILE * of
343 * the stream. A is not used.
344 * control may be:
345 * IOBUFCTRL_INIT: called just before the function is linked into the
346 * list of function. This can be used to prepare internal
347 * data structures of the function.
348 * IOBUFCTRL_FREE: called just before the function is removed from the
349 * list of functions and can be used to release internal
350 * data structures or close a file etc.
351 * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer
352 * with new stuff. *RET_LEN is the available size of the
353 * buffer, and should be set to the number of bytes
354 * which were put into the buffer. The function
355 * returns 0 to indicate success, -1 on EOF and
356 * G10ERR_xxxxx for other errors.
358 * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
359 * *RET_LAN is the number of bytes in BUF.
361 * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The
362 * filter may take appropriate action on this message.
364 static int
365 file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
367 file_filter_ctx_t *a = opaque;
368 FILEP_OR_FD f = a->fp;
369 size_t size = *ret_len;
370 size_t nbytes = 0;
371 int rc = 0;
373 #ifdef FILE_FILTER_USES_STDIO
374 if( control == IOBUFCTRL_UNDERFLOW ) {
375 assert( size ); /* need a buffer */
376 if ( feof(f)) { /* On terminals you could easiely read as many EOFs as you call */
377 rc = -1; /* fread() or fgetc() repeatly. Every call will block until you press */
378 *ret_len = 0; /* CTRL-D. So we catch this case before we call fread() again. */
380 else {
381 clearerr( f );
382 nbytes = fread( buf, 1, size, f );
383 if( feof(f) && !nbytes ) {
384 rc = -1; /* okay: we can return EOF now. */
386 else if( ferror(f) && errno != EPIPE ) {
387 log_error("%s: read error: %s\n",
388 a->fname, strerror(errno));
389 rc = G10ERR_READ_FILE;
391 *ret_len = nbytes;
394 else if( control == IOBUFCTRL_FLUSH ) {
395 if( size ) {
396 clearerr( f );
397 nbytes = fwrite( buf, 1, size, f );
398 if( ferror(f) ) {
399 log_error("%s: write error: %s\n", a->fname, strerror(errno));
400 rc = G10ERR_WRITE_FILE;
403 *ret_len = nbytes;
405 else if( control == IOBUFCTRL_INIT ) {
406 a->keep_open = a->no_cache = 0;
408 else if( control == IOBUFCTRL_DESC ) {
409 *(char**)buf = "file_filter";
411 else if( control == IOBUFCTRL_FREE ) {
412 if( f != stdin && f != stdout ) {
413 if( DBG_IOBUF )
414 log_debug("%s: close fd %d\n", a->fname, fileno(f) );
415 if (!a->keep_open)
416 fclose(f);
418 f = NULL;
419 xfree(a); /* we can free our context now */
421 #else /* !stdio implementation */
423 if( control == IOBUFCTRL_UNDERFLOW ) {
424 assert( size ); /* need a buffer */
425 if ( a->eof_seen) {
426 rc = -1;
427 *ret_len = 0;
429 else {
430 #ifdef HAVE_DOSISH_SYSTEM
431 unsigned long nread;
433 nbytes = 0;
434 if ( !ReadFile ( f, buf, size, &nread, NULL ) ) {
435 if ((int)GetLastError () != ERROR_BROKEN_PIPE) {
436 log_error ("%s: read error: %s\n", a->fname,
437 w32_strerror (0));
438 rc = G10ERR_READ_FILE;
441 else if ( !nread ) {
442 a->eof_seen = 1;
443 rc = -1;
445 else {
446 nbytes = nread;
449 #else
451 int n;
453 nbytes = 0;
454 do {
455 n = read ( f, buf, size );
456 } while (n == -1 && errno == EINTR );
457 if ( n == -1 ) { /* error */
458 if (errno != EPIPE) {
459 log_error("%s: read error: %s\n",
460 a->fname, strerror(errno));
461 rc = G10ERR_READ_FILE;
464 else if ( !n ) { /* eof */
465 a->eof_seen = 1;
466 rc = -1;
468 else {
469 nbytes = n;
471 #endif
472 *ret_len = nbytes;
475 else if( control == IOBUFCTRL_FLUSH ) {
476 if( size ) {
477 #ifdef HAVE_DOSISH_SYSTEM
478 byte *p = buf;
479 unsigned long n;
481 nbytes = size;
482 do {
483 if (size && !WriteFile (f, p, nbytes, &n, NULL)) {
484 log_error ("%s: write error: %s\n", a->fname,
485 w32_strerror (0));
486 rc = G10ERR_WRITE_FILE;
487 break;
489 p += n;
490 nbytes -= n;
491 } while ( nbytes );
492 nbytes = p - buf;
493 #else
494 byte *p = buf;
495 int n;
497 nbytes = size;
498 do {
499 do {
500 n = write ( f, p, nbytes );
501 } while ( n == -1 && errno == EINTR );
502 if ( n > 0 ) {
503 p += n;
504 nbytes -= n;
506 } while ( n != -1 && nbytes );
507 if( n == -1 ) {
508 log_error("%s: write error: %s\n", a->fname, strerror(errno));
509 rc = G10ERR_WRITE_FILE;
511 nbytes = p - buf;
512 #endif
514 *ret_len = nbytes;
516 else if ( control == IOBUFCTRL_INIT ) {
517 a->eof_seen = 0;
518 a->keep_open = 0;
519 a->no_cache = 0;
521 else if ( control == IOBUFCTRL_DESC ) {
522 *(char**)buf = "file_filter(fd)";
524 else if ( control == IOBUFCTRL_FREE ) {
525 #ifdef HAVE_DOSISH_SYSTEM
526 if ( f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT ) {
527 if( DBG_IOBUF )
528 log_debug("%s: close handle %p\n", a->fname, f );
529 if (!a->keep_open)
530 fd_cache_close (a->no_cache?NULL:a->fname, f);
532 #else
533 if ( (int)f != 0 && (int)f != 1 ) {
534 if( DBG_IOBUF )
535 log_debug("%s: close fd %d\n", a->fname, f );
536 if (!a->keep_open)
537 fd_cache_close (a->no_cache?NULL:a->fname, f);
539 f = INVALID_FP;
540 #endif
541 xfree (a); /* we can free our context now */
543 #endif /* !stdio implementation */
544 return rc;
547 #ifdef _WIN32
548 /* Becuase sockets are an special object under Lose32 we have to
549 * use a special filter */
550 static int
551 sock_filter (void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
553 sock_filter_ctx_t *a = opaque;
554 size_t size = *ret_len;
555 size_t nbytes = 0;
556 int rc = 0;
558 if( control == IOBUFCTRL_UNDERFLOW ) {
559 assert( size ); /* need a buffer */
560 if ( a->eof_seen) {
561 rc = -1;
562 *ret_len = 0;
564 else {
565 int nread;
567 nread = recv ( a->sock, buf, size, 0 );
568 if ( nread == SOCKET_ERROR ) {
569 int ec = (int)WSAGetLastError ();
570 log_error("socket read error: ec=%d\n", ec);
571 rc = G10ERR_READ_FILE;
573 else if ( !nread ) {
574 a->eof_seen = 1;
575 rc = -1;
577 else {
578 nbytes = nread;
580 *ret_len = nbytes;
583 else if( control == IOBUFCTRL_FLUSH ) {
584 if( size ) {
585 byte *p = buf;
586 int n;
588 nbytes = size;
589 do {
590 n = send (a->sock, p, nbytes, 0);
591 if ( n == SOCKET_ERROR ) {
592 int ec = (int)WSAGetLastError ();
593 log_error("socket write error: ec=%d\n", ec);
594 rc = G10ERR_WRITE_FILE;
595 break;
597 p += n;
598 nbytes -= n;
599 } while ( nbytes );
600 nbytes = p - buf;
602 *ret_len = nbytes;
604 else if ( control == IOBUFCTRL_INIT ) {
605 a->eof_seen = 0;
606 a->keep_open = 0;
607 a->no_cache = 0;
609 else if ( control == IOBUFCTRL_DESC ) {
610 *(char**)buf = "sock_filter";
612 else if ( control == IOBUFCTRL_FREE ) {
613 if (!a->keep_open)
614 closesocket (a->sock);
615 xfree (a); /* we can free our context now */
617 return rc;
619 #endif /*_WIN32*/
621 /****************
622 * This is used to implement the block write mode.
623 * Block reading is done on a byte by byte basis in readbyte(),
624 * without a filter
626 static int
627 block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
629 block_filter_ctx_t *a = opaque;
630 size_t size = *ret_len;
631 int c, needed, rc = 0;
632 char *p;
634 if( control == IOBUFCTRL_UNDERFLOW ) {
635 size_t n=0;
637 p = buf;
638 assert( size ); /* need a buffer */
639 if( a->eof ) /* don't read any further */
640 rc = -1;
641 while( !rc && size ) {
642 if( !a->size ) { /* get the length bytes */
643 if( a->partial == 2 ) {
644 a->eof = 1;
645 if( !n )
646 rc = -1;
647 break;
649 else if( a->partial ) {
650 /* These OpenPGP introduced huffman like encoded length
651 * bytes are really a mess :-( */
652 if( a->first_c ) {
653 c = a->first_c;
654 a->first_c = 0;
656 else if( (c = iobuf_get(chain)) == -1 ) {
657 log_error("block_filter: 1st length byte missing\n");
658 rc = G10ERR_READ_FILE;
659 break;
661 if( c < 192 ) {
662 a->size = c;
663 a->partial = 2;
664 if( !a->size ) {
665 a->eof = 1;
666 if( !n )
667 rc = -1;
668 break;
671 else if( c < 224 ) {
672 a->size = (c - 192) * 256;
673 if( (c = iobuf_get(chain)) == -1 ) {
674 log_error("block_filter: 2nd length byte missing\n");
675 rc = G10ERR_READ_FILE;
676 break;
678 a->size += c + 192;
679 a->partial = 2;
680 if( !a->size ) {
681 a->eof = 1;
682 if( !n )
683 rc = -1;
684 break;
687 else if( c == 255 ) {
688 a->size = iobuf_get(chain) << 24;
689 a->size |= iobuf_get(chain) << 16;
690 a->size |= iobuf_get(chain) << 8;
691 if( (c = iobuf_get(chain)) == -1 ) {
692 log_error("block_filter: invalid 4 byte length\n");
693 rc = G10ERR_READ_FILE;
694 break;
696 a->size |= c;
697 a->partial = 2;
698 if( !a->size ) {
699 a->eof = 1;
700 if( !n )
701 rc = -1;
702 break;
705 else { /* next partial body length */
706 a->size = 1 << (c & 0x1f);
708 /* log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size);*/
710 else
711 BUG();
714 while( !rc && size && a->size ) {
715 needed = size < a->size ? size : a->size;
716 c = iobuf_read( chain, p, needed );
717 if( c < needed ) {
718 if( c == -1 ) c = 0;
719 log_error("block_filter %p: read error (size=%lu,a->size=%lu)\n",
720 a, (ulong)size+c, (ulong)a->size+c);
721 rc = G10ERR_READ_FILE;
723 else {
724 size -= c;
725 a->size -= c;
726 p += c;
727 n += c;
731 *ret_len = n;
733 else if( control == IOBUFCTRL_FLUSH ) {
734 if( a->partial ) { /* the complicated openpgp scheme */
735 size_t blen, n, nbytes = size + a->buflen;
737 assert( a->buflen <= OP_MIN_PARTIAL_CHUNK );
738 if( nbytes < OP_MIN_PARTIAL_CHUNK ) {
739 /* not enough to write a partial block out; so we store it*/
740 if( !a->buffer )
741 a->buffer = xmalloc( OP_MIN_PARTIAL_CHUNK );
742 memcpy( a->buffer + a->buflen, buf, size );
743 a->buflen += size;
745 else { /* okay, we can write out something */
746 /* do this in a loop to use the most efficient block lengths */
747 p = buf;
748 do {
749 /* find the best matching block length - this is limited
750 * by the size of the internal buffering */
751 for( blen=OP_MIN_PARTIAL_CHUNK*2,
752 c=OP_MIN_PARTIAL_CHUNK_2POW+1; blen <= nbytes;
753 blen *=2, c++ )
755 blen /= 2; c--;
756 /* write the partial length header */
757 assert( c <= 0x1f ); /*;-)*/
758 c |= 0xe0;
759 iobuf_put( chain, c );
760 if( (n=a->buflen) ) { /* write stuff from the buffer */
761 assert( n == OP_MIN_PARTIAL_CHUNK);
762 if( iobuf_write(chain, a->buffer, n ) )
763 rc = G10ERR_WRITE_FILE;
764 a->buflen = 0;
765 nbytes -= n;
767 if( (n = nbytes) > blen )
768 n = blen;
769 if( n && iobuf_write(chain, p, n ) )
770 rc = G10ERR_WRITE_FILE;
771 p += n;
772 nbytes -= n;
773 } while( !rc && nbytes >= OP_MIN_PARTIAL_CHUNK );
774 /* store the rest in the buffer */
775 if( !rc && nbytes ) {
776 assert( !a->buflen );
777 assert( nbytes < OP_MIN_PARTIAL_CHUNK );
778 if( !a->buffer )
779 a->buffer = xmalloc( OP_MIN_PARTIAL_CHUNK );
780 memcpy( a->buffer, p, nbytes );
781 a->buflen = nbytes;
785 else
786 BUG();
788 else if( control == IOBUFCTRL_INIT ) {
789 if( DBG_IOBUF )
790 log_debug("init block_filter %p\n", a );
791 if( a->partial )
792 a->count = 0;
793 else if( a->use == 1 )
794 a->count = a->size = 0;
795 else
796 a->count = a->size; /* force first length bytes */
797 a->eof = 0;
798 a->buffer = NULL;
799 a->buflen = 0;
801 else if( control == IOBUFCTRL_DESC ) {
802 *(char**)buf = "block_filter";
804 else if( control == IOBUFCTRL_FREE ) {
805 if( a->use == 2 ) { /* write the end markers */
806 if( a->partial ) {
807 u32 len;
808 /* write out the remaining bytes without a partial header
809 * the length of this header may be 0 - but if it is
810 * the first block we are not allowed to use a partial header
811 * and frankly we can't do so, because this length must be
812 * a power of 2. This is _really_ complicated because we
813 * have to check the possible length of a packet prior
814 * to it's creation: a chain of filters becomes complicated
815 * and we need a lot of code to handle compressed packets etc.
816 * :-(((((((
818 /* construct header */
819 len = a->buflen;
820 /*log_debug("partial: remaining length=%u\n", len );*/
821 if( len < 192 )
822 rc = iobuf_put(chain, len );
823 else if( len < 8384 ) {
824 if( !(rc=iobuf_put( chain, ((len-192) / 256) + 192)) )
825 rc = iobuf_put( chain, ((len-192) % 256));
827 else { /* use a 4 byte header */
828 if( !(rc=iobuf_put( chain, 0xff )) )
829 if( !(rc=iobuf_put( chain, (len >> 24)&0xff )) )
830 if( !(rc=iobuf_put( chain, (len >> 16)&0xff )) )
831 if( !(rc=iobuf_put( chain, (len >> 8)&0xff )))
832 rc=iobuf_put( chain, len & 0xff );
834 if( !rc && len )
835 rc = iobuf_write(chain, a->buffer, len );
836 if( rc ) {
837 log_error("block_filter: write error: %s\n",strerror(errno));
838 rc = G10ERR_WRITE_FILE;
840 xfree( a->buffer ); a->buffer = NULL; a->buflen = 0;
842 else
843 BUG();
845 else if( a->size ) {
846 log_error("block_filter: pending bytes!\n");
848 if( DBG_IOBUF )
849 log_debug("free block_filter %p\n", a );
850 xfree(a); /* we can free our context now */
853 return rc;
857 static void
858 print_chain( IOBUF a )
860 if( !DBG_IOBUF )
861 return;
862 for(; a; a = a->chain ) {
863 size_t dummy_len = 0;
864 const char *desc = "[none]";
866 if( a->filter )
867 a->filter( a->filter_ov, IOBUFCTRL_DESC, NULL,
868 (byte*)&desc, &dummy_len );
870 log_debug("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n",
871 a->no, a->subno, desc, a->filter_eof,
872 (int)a->d.start, (int)a->d.len );
877 iobuf_print_chain( IOBUF a )
879 print_chain(a);
880 return 0;
883 /****************
884 * Allocate a new io buffer, with no function assigned.
885 * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer
886 * BUFSIZE is a suggested buffer size.
888 IOBUF
889 iobuf_alloc(int use, size_t bufsize)
891 IOBUF a;
892 static int number=0;
894 a = xmalloc_clear(sizeof *a);
895 a->use = use;
896 a->d.buf = xmalloc( bufsize );
897 a->d.size = bufsize;
898 a->no = ++number;
899 a->subno = 0;
900 a->opaque = NULL;
901 a->real_fname = NULL;
902 return a;
906 iobuf_close ( IOBUF a )
908 IOBUF a2;
909 size_t dummy_len=0;
910 int rc=0;
912 if( a && a->directfp ) {
913 fclose( a->directfp );
914 xfree( a->real_fname );
915 if( DBG_IOBUF )
916 log_debug("iobuf_close -> %p\n", a->directfp );
917 return 0;
920 for( ; a && !rc ; a = a2 ) {
921 a2 = a->chain;
922 if( a->use == 2 && (rc=iobuf_flush(a)) )
923 log_error("iobuf_flush failed on close: %s\n", g10_errstr(rc));
925 if( DBG_IOBUF )
926 log_debug("iobuf-%d.%d: close `%s'\n", a->no, a->subno, a->desc );
927 if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE,
928 a->chain, NULL, &dummy_len)) )
929 log_error("IOBUFCTRL_FREE failed on close: %s\n", g10_errstr(rc) );
930 xfree(a->real_fname);
931 if (a->d.buf) {
932 memset (a->d.buf, 0, a->d.size); /* erase the buffer */
933 xfree(a->d.buf);
935 xfree(a);
937 return rc;
941 iobuf_cancel( IOBUF a )
943 const char *s;
944 IOBUF a2;
945 int rc;
946 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
947 char *remove_name = NULL;
948 #endif
950 if( a && a->use == 2 ) {
951 s = iobuf_get_real_fname(a);
952 if( s && *s ) {
953 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
954 remove_name = xstrdup ( s );
955 #else
956 remove(s);
957 #endif
961 /* send a cancel message to all filters */
962 for( a2 = a; a2 ; a2 = a2->chain ) {
963 size_t dummy;
964 if( a2->filter )
965 a2->filter( a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain,
966 NULL, &dummy );
969 rc = iobuf_close(a);
970 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
971 if ( remove_name ) {
972 /* Argg, MSDOS does not allow to remove open files. So
973 * we have to do it here */
974 remove ( remove_name );
975 xfree ( remove_name );
977 #endif
978 return rc;
982 /****************
983 * create a temporary iobuf, which can be used to collect stuff
984 * in an iobuf and later be written by iobuf_write_temp() to another
985 * iobuf.
987 IOBUF
988 iobuf_temp()
990 IOBUF a;
992 a = iobuf_alloc(3, IOBUF_BUFFER_SIZE );
994 return a;
997 IOBUF
998 iobuf_temp_with_content( const char *buffer, size_t length )
1000 IOBUF a;
1002 a = iobuf_alloc(3, length );
1003 memcpy( a->d.buf, buffer, length );
1004 a->d.len = length;
1006 return a;
1009 void
1010 iobuf_enable_special_filenames ( int yes )
1012 special_names_enabled = yes;
1016 * see whether the filename has the for "-&nnnn", where n is a
1017 * non-zero number.
1018 * Returns this number or -1 if it is not the case.
1020 static int
1021 check_special_filename ( const char *fname )
1023 if ( special_names_enabled
1024 && fname && *fname == '-' && fname[1] == '&' ) {
1025 int i;
1027 fname += 2;
1028 for (i=0; digitp (fname+i); i++ )
1030 if ( !fname[i] )
1031 return atoi (fname);
1033 return -1;
1036 /* This fucntion returns true if FNAME indicates a PIPE (stdout or
1037 stderr) or a special file name if those are enabled. */
1039 iobuf_is_pipe_filename (const char *fname)
1041 if (!fname || (*fname=='-' && !fname[1]) )
1042 return 1;
1043 return check_special_filename (fname) != -1;
1046 /****************
1047 * Create a head iobuf for reading from a file
1048 * returns: NULL if an error occures and sets errno
1050 IOBUF
1051 iobuf_open( const char *fname )
1053 IOBUF a;
1054 FILEP_OR_FD fp;
1055 file_filter_ctx_t *fcx;
1056 size_t len;
1057 int print_only = 0;
1058 int fd;
1060 if( !fname || (*fname=='-' && !fname[1]) ) {
1061 fp = FILEP_OR_FD_FOR_STDIN;
1062 #ifdef USE_SETMODE
1063 setmode ( my_fileno(fp) , O_BINARY );
1064 #endif
1065 fname = "[stdin]";
1066 print_only = 1;
1068 else if ( (fd = check_special_filename ( fname )) != -1 )
1069 return iobuf_fdopen ( translate_file_handle (fd,0), "rb" );
1070 else if( (fp = my_fopen_ro(fname, "rb")) == INVALID_FP )
1071 return NULL;
1072 a = iobuf_alloc(1, IOBUF_BUFFER_SIZE );
1073 fcx = xmalloc( sizeof *fcx + strlen(fname) );
1074 fcx->fp = fp;
1075 fcx->print_only_name = print_only;
1076 strcpy(fcx->fname, fname );
1077 if( !print_only )
1078 a->real_fname = xstrdup( fname );
1079 a->filter = file_filter;
1080 a->filter_ov = fcx;
1081 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
1082 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
1083 if( DBG_IOBUF )
1084 log_debug("iobuf-%d.%d: open `%s' fd=%d\n",
1085 a->no, a->subno, fname, (int)my_fileno(fcx->fp) );
1087 return a;
1090 /****************
1091 * Create a head iobuf for reading from a file
1092 * returns: NULL if an error occures and sets errno
1094 IOBUF
1095 iobuf_fdopen( int fd, const char *mode )
1097 IOBUF a;
1098 FILEP_OR_FD fp;
1099 file_filter_ctx_t *fcx;
1100 size_t len;
1102 #ifdef FILE_FILTER_USES_STDIO
1103 if( !(fp = fdopen(fd, mode)) )
1104 return NULL;
1105 #else
1106 fp = (FILEP_OR_FD)fd;
1107 #endif
1108 a = iobuf_alloc( strchr( mode, 'w')? 2:1, IOBUF_BUFFER_SIZE );
1109 fcx = xmalloc( sizeof *fcx + 20 );
1110 fcx->fp = fp;
1111 fcx->print_only_name = 1;
1112 sprintf(fcx->fname, "[fd %d]", fd );
1113 a->filter = file_filter;
1114 a->filter_ov = fcx;
1115 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
1116 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
1117 if( DBG_IOBUF )
1118 log_debug("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname );
1119 iobuf_ioctl (a,3,1,NULL); /* disable fd caching */
1120 return a;
1124 IOBUF
1125 iobuf_sockopen ( int fd, const char *mode )
1127 IOBUF a;
1128 #ifdef _WIN32
1129 sock_filter_ctx_t *scx;
1130 size_t len;
1132 a = iobuf_alloc( strchr( mode, 'w')? 2:1, IOBUF_BUFFER_SIZE );
1133 scx = xmalloc( sizeof *scx + 25 );
1134 scx->sock = fd;
1135 scx->print_only_name = 1;
1136 sprintf(scx->fname, "[sock %d]", fd );
1137 a->filter = sock_filter;
1138 a->filter_ov = scx;
1139 sock_filter( scx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
1140 sock_filter( scx, IOBUFCTRL_INIT, NULL, NULL, &len );
1141 if( DBG_IOBUF )
1142 log_debug("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
1143 iobuf_ioctl (a,3,1,NULL); /* disable fd caching */
1144 #else
1145 a = iobuf_fdopen (fd, mode);
1146 #endif
1147 return a;
1150 /****************
1151 * create an iobuf for writing to a file; the file will be created.
1153 IOBUF
1154 iobuf_create( const char *fname )
1156 IOBUF a;
1157 FILEP_OR_FD fp;
1158 file_filter_ctx_t *fcx;
1159 size_t len;
1160 int print_only = 0;
1161 int fd;
1163 if( !fname || (*fname=='-' && !fname[1]) ) {
1164 fp = FILEP_OR_FD_FOR_STDOUT;
1165 #ifdef USE_SETMODE
1166 setmode ( my_fileno(fp) , O_BINARY );
1167 #endif
1168 fname = "[stdout]";
1169 print_only = 1;
1171 else if ( (fd = check_special_filename ( fname )) != -1 )
1172 return iobuf_fdopen ( translate_file_handle (fd, 1), "wb" );
1173 else if( (fp = my_fopen(fname, "wb")) == INVALID_FP )
1174 return NULL;
1175 a = iobuf_alloc(2, IOBUF_BUFFER_SIZE );
1176 fcx = xmalloc( sizeof *fcx + strlen(fname) );
1177 fcx->fp = fp;
1178 fcx->print_only_name = print_only;
1179 strcpy(fcx->fname, fname );
1180 if( !print_only )
1181 a->real_fname = xstrdup( fname );
1182 a->filter = file_filter;
1183 a->filter_ov = fcx;
1184 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
1185 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
1186 if( DBG_IOBUF )
1187 log_debug("iobuf-%d.%d: create `%s'\n", a->no, a->subno, a->desc );
1189 return a;
1192 /****************
1193 * append to an iobuf; if the file does not exist, create it.
1194 * cannot be used for stdout.
1195 * Note: This is not used.
1197 #if 0 /* not used */
1198 IOBUF
1199 iobuf_append( const char *fname )
1201 IOBUF a;
1202 FILE *fp;
1203 file_filter_ctx_t *fcx;
1204 size_t len;
1206 if( !fname )
1207 return NULL;
1208 else if( !(fp = my_fopen(fname, "ab")) )
1209 return NULL;
1210 a = iobuf_alloc(2, IOBUF_BUFFER_SIZE );
1211 fcx = xmalloc( sizeof *fcx + strlen(fname) );
1212 fcx->fp = fp;
1213 strcpy(fcx->fname, fname );
1214 a->real_fname = xstrdup( fname );
1215 a->filter = file_filter;
1216 a->filter_ov = fcx;
1217 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
1218 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
1219 if( DBG_IOBUF )
1220 log_debug("iobuf-%d.%d: append `%s'\n", a->no, a->subno, a->desc );
1222 return a;
1224 #endif
1226 IOBUF
1227 iobuf_openrw( const char *fname )
1229 IOBUF a;
1230 FILEP_OR_FD fp;
1231 file_filter_ctx_t *fcx;
1232 size_t len;
1234 if( !fname )
1235 return NULL;
1236 else if( (fp = my_fopen(fname, "r+b")) == INVALID_FP )
1237 return NULL;
1238 a = iobuf_alloc(2, IOBUF_BUFFER_SIZE );
1239 fcx = xmalloc( sizeof *fcx + strlen(fname) );
1240 fcx->fp = fp;
1241 strcpy(fcx->fname, fname );
1242 a->real_fname = xstrdup( fname );
1243 a->filter = file_filter;
1244 a->filter_ov = fcx;
1245 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
1246 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
1247 if( DBG_IOBUF )
1248 log_debug("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, a->desc );
1250 return a;
1255 iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval )
1257 if ( cmd == 1 ) { /* keep system filepointer/descriptor open */
1258 if( DBG_IOBUF )
1259 log_debug("iobuf-%d.%d: ioctl `%s' keep=%d\n",
1260 a? a->no:-1, a?a->subno:-1, a?a->desc:"?", intval );
1261 for( ; a; a = a->chain )
1262 if( !a->chain && a->filter == file_filter ) {
1263 file_filter_ctx_t *b = a->filter_ov;
1264 b->keep_open = intval;
1265 return 0;
1267 #ifdef _WIN32
1268 else if( !a->chain && a->filter == sock_filter ) {
1269 sock_filter_ctx_t *b = a->filter_ov;
1270 b->keep_open = intval;
1271 return 0;
1273 #endif
1275 else if ( cmd == 2 ) { /* invalidate cache */
1276 if( DBG_IOBUF )
1277 log_debug("iobuf-*.*: ioctl `%s' invalidate\n",
1278 ptrval? (char*)ptrval:"?");
1279 if ( !a && !intval && ptrval ) {
1280 #ifndef FILE_FILTER_USES_STDIO
1281 fd_cache_invalidate (ptrval);
1282 #endif
1283 return 0;
1286 else if ( cmd == 3 ) { /* disallow/allow caching */
1287 if( DBG_IOBUF )
1288 log_debug("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
1289 a? a->no:-1, a?a->subno:-1, a?a->desc:"?", intval );
1290 for( ; a; a = a->chain )
1291 if( !a->chain && a->filter == file_filter ) {
1292 file_filter_ctx_t *b = a->filter_ov;
1293 b->no_cache = intval;
1294 return 0;
1296 #ifdef _WIN32
1297 else if( !a->chain && a->filter == sock_filter ) {
1298 sock_filter_ctx_t *b = a->filter_ov;
1299 b->no_cache = intval;
1300 return 0;
1302 #endif
1305 return -1;
1309 /****************
1310 * Register an i/o filter.
1313 iobuf_push_filter( IOBUF a,
1314 int (*f)(void *opaque, int control,
1315 IOBUF chain, byte *buf, size_t *len), void *ov )
1317 return iobuf_push_filter2( a, f, ov, 0 );
1321 iobuf_push_filter2( IOBUF a,
1322 int (*f)(void *opaque, int control,
1323 IOBUF chain, byte *buf, size_t *len),
1324 void *ov, int rel_ov )
1326 IOBUF b;
1327 size_t dummy_len=0;
1328 int rc=0;
1330 if( a->directfp )
1331 BUG();
1333 if( a->use == 2 && (rc=iobuf_flush(a)) )
1334 return rc;
1335 /* make a copy of the current stream, so that
1336 * A is the new stream and B the original one.
1337 * The contents of the buffers are transferred to the
1338 * new stream.
1340 b = xmalloc(sizeof *b);
1341 memcpy(b, a, sizeof *b );
1342 /* fixme: it is stupid to keep a copy of the name at every level
1343 * but we need the name somewhere because the name known by file_filter
1344 * may have been released when we need the name of the file */
1345 b->real_fname = a->real_fname? xstrdup(a->real_fname):NULL;
1346 /* remove the filter stuff from the new stream */
1347 a->filter = NULL;
1348 a->filter_ov = NULL;
1349 a->filter_ov_owner = 0;
1350 a->filter_eof = 0;
1351 if( a->use == 3 )
1352 a->use = 2; /* make a write stream from a temp stream */
1354 if( a->use == 2 ) { /* allocate a fresh buffer for the original stream */
1355 b->d.buf = xmalloc( a->d.size );
1356 b->d.len = 0;
1357 b->d.start = 0;
1359 else { /* allocate a fresh buffer for the new stream */
1360 a->d.buf = xmalloc( a->d.size );
1361 a->d.len = 0;
1362 a->d.start = 0;
1364 /* disable nlimit for the new stream */
1365 a->ntotal = b->ntotal + b->nbytes;
1366 a->nlimit = a->nbytes = 0;
1367 a->nofast &= ~1;
1368 /* make a link from the new stream to the original stream */
1369 a->chain = b;
1370 a->opaque = b->opaque;
1372 /* setup the function on the new stream */
1373 a->filter = f;
1374 a->filter_ov = ov;
1375 a->filter_ov_owner = rel_ov;
1377 a->subno = b->subno + 1;
1378 f( ov, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &dummy_len );
1380 if( DBG_IOBUF ) {
1381 log_debug("iobuf-%d.%d: push `%s'\n", a->no, a->subno, a->desc );
1382 print_chain( a );
1385 /* now we can initialize the new function if we have one */
1386 if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_INIT, a->chain,
1387 NULL, &dummy_len)) )
1388 log_error("IOBUFCTRL_INIT failed: %s\n", g10_errstr(rc) );
1389 return rc;
1392 /****************
1393 * Remove an i/o filter.
1395 static int
1396 pop_filter( IOBUF a, int (*f)(void *opaque, int control,
1397 IOBUF chain, byte *buf, size_t *len), void *ov )
1399 IOBUF b;
1400 size_t dummy_len=0;
1401 int rc=0;
1403 if( a->directfp )
1404 BUG();
1406 if( DBG_IOBUF )
1407 log_debug("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, a->desc );
1408 if( !a->filter ) { /* this is simple */
1409 b = a->chain;
1410 assert(b);
1411 xfree(a->d.buf);
1412 xfree(a->real_fname);
1413 memcpy(a,b, sizeof *a);
1414 xfree(b);
1415 return 0;
1417 for(b=a ; b; b = b->chain )
1418 if( b->filter == f && (!ov || b->filter_ov == ov) )
1419 break;
1420 if( !b )
1421 log_bug("pop_filter(): filter function not found\n");
1423 /* flush this stream if it is an output stream */
1424 if( a->use == 2 && (rc=iobuf_flush(b)) ) {
1425 log_error("iobuf_flush failed in pop_filter: %s\n", g10_errstr(rc));
1426 return rc;
1428 /* and tell the filter to free it self */
1429 if( b->filter && (rc = b->filter(b->filter_ov, IOBUFCTRL_FREE, b->chain,
1430 NULL, &dummy_len)) ) {
1431 log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
1432 return rc;
1434 if( b->filter_ov && b->filter_ov_owner ) {
1435 xfree( b->filter_ov );
1436 b->filter_ov = NULL;
1440 /* and see how to remove it */
1441 if( a == b && !b->chain )
1442 log_bug("can't remove the last filter from the chain\n");
1443 else if( a == b ) { /* remove the first iobuf from the chain */
1444 /* everything from b is copied to a. This is save because
1445 * a flush has been done on the to be removed entry
1447 b = a->chain;
1448 xfree(a->d.buf);
1449 xfree(a->real_fname);
1450 memcpy(a,b, sizeof *a);
1451 xfree(b);
1452 if( DBG_IOBUF )
1453 log_debug("iobuf-%d.%d: popped filter\n", a->no, a->subno );
1455 else if( !b->chain ) { /* remove the last iobuf from the chain */
1456 log_bug("Ohh jeee, trying to remove a head filter\n");
1458 else { /* remove an intermediate iobuf from the chain */
1459 log_bug("Ohh jeee, trying to remove an intermediate filter\n");
1462 return rc;
1466 /****************
1467 * read underflow: read more bytes into the buffer and return
1468 * the first byte or -1 on EOF.
1470 static int
1471 underflow(IOBUF a)
1473 size_t len;
1474 int rc;
1476 assert( a->d.start == a->d.len );
1477 if( a->use == 3 )
1478 return -1; /* EOF because a temp buffer can't do an underflow */
1480 if( a->filter_eof ) {
1481 if( a->chain ) {
1482 IOBUF b = a->chain;
1483 if( DBG_IOBUF )
1484 log_debug("iobuf-%d.%d: pop `%s' in underflow\n",
1485 a->no, a->subno, a->desc );
1486 xfree(a->d.buf);
1487 xfree(a->real_fname);
1488 memcpy(a, b, sizeof *a);
1489 xfree(b);
1490 print_chain(a);
1492 else
1493 a->filter_eof = 0; /* for the top level filter */
1494 if( DBG_IOBUF )
1495 log_debug("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
1496 a->no, a->subno );
1497 return -1; /* return one(!) EOF */
1499 if( a->error ) {
1500 if( DBG_IOBUF )
1501 log_debug("iobuf-%d.%d: error\n", a->no, a->subno );
1502 return -1;
1505 if( a->directfp ) {
1506 FILE *fp = a->directfp;
1508 len = fread( a->d.buf, 1, a->d.size, fp);
1509 if( len < a->d.size ) {
1510 if( ferror(fp) )
1511 a->error = 1;
1513 a->d.len = len;
1514 a->d.start = 0;
1515 return len? a->d.buf[a->d.start++] : -1;
1519 if( a->filter ) {
1520 len = a->d.size;
1521 if( DBG_IOBUF )
1522 log_debug("iobuf-%d.%d: underflow: req=%lu\n",
1523 a->no, a->subno, (ulong)len );
1524 rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1525 a->d.buf, &len );
1526 if( DBG_IOBUF ) {
1527 log_debug("iobuf-%d.%d: underflow: got=%lu rc=%d\n",
1528 a->no, a->subno, (ulong)len, rc );
1529 /* if( a->no == 1 ) */
1530 /* log_hexdump (" data:", a->d.buf, len); */
1532 if( a->use == 1 && rc == -1 ) { /* EOF: we can remove the filter */
1533 size_t dummy_len=0;
1535 /* and tell the filter to free itself */
1536 if( (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain,
1537 NULL, &dummy_len)) )
1538 log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
1539 if( a->filter_ov && a->filter_ov_owner ) {
1540 xfree( a->filter_ov );
1541 a->filter_ov = NULL;
1543 a->filter = NULL;
1544 a->desc = NULL;
1545 a->filter_ov = NULL;
1546 a->filter_eof = 1;
1547 if( !len && a->chain ) {
1548 IOBUF b = a->chain;
1549 if( DBG_IOBUF )
1550 log_debug("iobuf-%d.%d: pop `%s' in underflow (!len)\n",
1551 a->no, a->subno, a->desc );
1552 xfree(a->d.buf);
1553 xfree(a->real_fname);
1554 memcpy(a,b, sizeof *a);
1555 xfree(b);
1556 print_chain(a);
1559 else if( rc )
1560 a->error = 1;
1562 if( !len ) {
1563 if( DBG_IOBUF )
1564 log_debug("iobuf-%d.%d: underflow: eof\n", a->no, a->subno );
1565 return -1;
1567 a->d.len = len;
1568 a->d.start = 0;
1569 return a->d.buf[a->d.start++];
1571 else {
1572 if( DBG_IOBUF )
1573 log_debug("iobuf-%d.%d: underflow: eof (no filter)\n",
1574 a->no, a->subno );
1575 return -1; /* no filter; return EOF */
1581 iobuf_flush(IOBUF a)
1583 size_t len;
1584 int rc;
1586 if( a->directfp )
1587 return 0;
1589 if( a->use == 3 ) { /* increase the temp buffer */
1590 char *newbuf;
1591 size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
1593 if( DBG_IOBUF )
1594 log_debug("increasing temp iobuf from %lu to %lu\n",
1595 (ulong)a->d.size, (ulong)newsize );
1596 newbuf = xmalloc( newsize );
1597 memcpy( newbuf, a->d.buf, a->d.len );
1598 xfree(a->d.buf);
1599 a->d.buf = newbuf;
1600 a->d.size = newsize;
1601 return 0;
1603 else if( a->use != 2 )
1604 log_bug("flush on non-output iobuf\n");
1605 else if( !a->filter )
1606 log_bug("iobuf_flush: no filter\n");
1607 len = a->d.len;
1608 rc = a->filter( a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len );
1609 if( !rc && len != a->d.len ) {
1610 log_info("iobuf_flush did not write all!\n");
1611 rc = G10ERR_WRITE_FILE;
1613 else if( rc )
1614 a->error = 1;
1615 a->d.len = 0;
1617 return rc;
1621 /****************
1622 * Read a byte from the iobuf; returns -1 on EOF
1625 iobuf_readbyte(IOBUF a)
1627 int c;
1629 /* nlimit does not work together with unget */
1630 /* nbytes is also not valid! */
1631 if( a->unget.buf ) {
1632 if( a->unget.start < a->unget.len )
1633 return a->unget.buf[a->unget.start++];
1634 xfree(a->unget.buf);
1635 a->unget.buf = NULL;
1636 a->nofast &= ~2;
1639 if( a->nlimit && a->nbytes >= a->nlimit )
1640 return -1; /* forced EOF */
1642 if( a->d.start < a->d.len ) {
1643 c = a->d.buf[a->d.start++];
1645 else if( (c=underflow(a)) == -1 )
1646 return -1; /* EOF */
1648 a->nbytes++;
1649 return c;
1654 iobuf_read(IOBUF a, byte *buf, unsigned buflen )
1656 int c, n;
1658 if( a->unget.buf || a->nlimit ) {
1659 /* handle special cases */
1660 for(n=0 ; n < buflen; n++ ) {
1661 if( (c = iobuf_readbyte(a)) == -1 ) {
1662 if( !n )
1663 return -1; /* eof */
1664 break;
1666 else
1667 if( buf ) *buf = c;
1668 if( buf ) buf++;
1670 return n;
1673 n = 0;
1674 do {
1675 if( n < buflen && a->d.start < a->d.len ) {
1676 unsigned size = a->d.len - a->d.start;
1677 if( size > buflen - n )
1678 size = buflen - n;
1679 if( buf )
1680 memcpy( buf, a->d.buf + a->d.start, size );
1681 n += size;
1682 a->d.start += size;
1683 if( buf )
1684 buf += size;
1686 if( n < buflen ) {
1687 if( (c=underflow(a)) == -1 ) {
1688 a->nbytes += n;
1689 return n? n : -1/*EOF*/;
1691 if( buf )
1692 *buf++ = c;
1693 n++;
1695 } while( n < buflen );
1696 a->nbytes += n;
1697 return n;
1701 /****************
1702 * Have a look at the iobuf.
1703 * NOTE: This only works in special cases.
1706 iobuf_peek(IOBUF a, byte *buf, unsigned buflen )
1708 int n=0;
1710 if( a->filter_eof )
1711 return -1;
1713 if( !(a->d.start < a->d.len) ) {
1714 if( underflow(a) == -1 )
1715 return -1;
1716 /* and unget this character */
1717 assert(a->d.start == 1);
1718 a->d.start = 0;
1721 for(n=0 ; n < buflen && (a->d.start+n) < a->d.len ; n++, buf++ )
1722 *buf = a->d.buf[n];
1723 return n;
1730 iobuf_writebyte(IOBUF a, unsigned c)
1733 if( a->directfp )
1734 BUG();
1736 if( a->d.len == a->d.size )
1737 if( iobuf_flush(a) )
1738 return -1;
1740 assert( a->d.len < a->d.size );
1741 a->d.buf[a->d.len++] = c;
1742 return 0;
1747 iobuf_write(IOBUF a, byte *buf, unsigned buflen )
1750 if( a->directfp )
1751 BUG();
1753 do {
1754 if( buflen && a->d.len < a->d.size ) {
1755 unsigned size = a->d.size - a->d.len;
1756 if( size > buflen ) size = buflen;
1757 memcpy( a->d.buf + a->d.len, buf, size );
1758 buflen -= size;
1759 buf += size;
1760 a->d.len += size;
1762 if( buflen ) {
1763 if( iobuf_flush(a) )
1764 return -1;
1766 } while( buflen );
1767 return 0;
1772 iobuf_writestr(IOBUF a, const char *buf )
1774 for( ; *buf; buf++ )
1775 if( iobuf_writebyte(a, *buf) )
1776 return -1;
1777 return 0;
1782 /****************
1783 * copy the contents of TEMP to A.
1786 iobuf_write_temp( IOBUF a, IOBUF temp )
1788 while( temp->chain )
1789 pop_filter( temp, temp->filter, NULL );
1790 return iobuf_write(a, temp->d.buf, temp->d.len );
1793 /****************
1794 * copy the contents of the temp io stream to BUFFER.
1796 size_t
1797 iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen )
1799 size_t n = a->d.len;
1801 if( n > buflen )
1802 n = buflen;
1803 memcpy( buffer, a->d.buf, n );
1804 return n;
1808 /****************
1809 * Call this function to terminate processing of the temp stream
1810 * without closing it. This removes all filters from the stream
1811 * makes sure that iobuf_get_temp_{buffer,length}() returns correct
1812 * values.
1814 void
1815 iobuf_flush_temp( IOBUF temp )
1817 while( temp->chain )
1818 pop_filter( temp, temp->filter, NULL );
1822 /****************
1823 * Set a limit on how many bytes may be read from the input stream A.
1824 * Setting the limit to 0 disables this feature.
1826 void
1827 iobuf_set_limit( IOBUF a, off_t nlimit )
1829 if( nlimit )
1830 a->nofast |= 1;
1831 else
1832 a->nofast &= ~1;
1833 a->nlimit = nlimit;
1834 a->ntotal += a->nbytes;
1835 a->nbytes = 0;
1840 /* Return the length of an open file A. IF OVERFLOW is not NULL it
1841 will be set to true if the file is larger than what off_t can cope
1842 with. The function return 0 on error or on overflow condition. */
1843 off_t
1844 iobuf_get_filelength (IOBUF a, int *overflow )
1846 struct stat st;
1848 if (overflow)
1849 *overflow = 0;
1851 if( a->directfp ) {
1852 FILE *fp = a->directfp;
1854 if( !fstat(fileno(fp), &st) )
1855 return st.st_size;
1856 log_error("fstat() failed: %s\n", strerror(errno) );
1857 return 0;
1860 /* Hmmm: file_filter may have already been removed */
1861 for( ; a; a = a->chain )
1862 if( !a->chain && a->filter == file_filter ) {
1863 file_filter_ctx_t *b = a->filter_ov;
1864 FILEP_OR_FD fp = b->fp;
1866 #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
1867 ulong size;
1868 static int (* __stdcall get_file_size_ex)
1869 (void *handle, LARGE_INTEGER *size);
1870 static int get_file_size_ex_initialized;
1872 if (!get_file_size_ex_initialized)
1874 void *handle;
1876 handle = dlopen ("kernel32.dll", RTLD_LAZY);
1877 if (handle)
1879 get_file_size_ex = dlsym (handle, "GetFileSizeEx");
1880 if (!get_file_size_ex)
1881 dlclose (handle);
1883 get_file_size_ex_initialized = 1;
1886 if (get_file_size_ex)
1888 /* This is a newer system with GetFileSizeEx; we use
1889 this then becuase it seem that GetFileSize won't
1890 return a proper error in case a file is larger than
1891 4GB. */
1892 LARGE_INTEGER size;
1894 if (get_file_size_ex (fp, &size))
1896 if (!size.u.HighPart)
1897 return size.u.LowPart;
1898 if (overflow)
1899 *overflow = 1;
1900 return 0;
1903 else
1905 if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
1906 return size;
1908 log_error ("GetFileSize for handle %p failed: %s\n",
1909 fp, w32_strerror (0));
1910 #else
1911 if( !fstat(my_fileno(fp), &st) )
1912 return st.st_size;
1913 log_error("fstat() failed: %s\n", strerror(errno) );
1914 #endif
1915 break;
1918 return 0;
1922 /* Return the file descriptor of the underlying file or -1 if it is
1923 not available. */
1924 int
1925 iobuf_get_fd (IOBUF a)
1927 if (a->directfp)
1928 return fileno ( (FILE*)a->directfp );
1930 for ( ; a; a = a->chain )
1931 if (!a->chain && a->filter == file_filter)
1933 file_filter_ctx_t *b = a->filter_ov;
1934 FILEP_OR_FD fp = b->fp;
1936 return my_fileno (fp);
1939 return -1;
1943 /****************
1944 * Tell the file position, where the next read will take place
1946 off_t
1947 iobuf_tell( IOBUF a )
1949 return a->ntotal + a->nbytes;
1953 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
1955 #ifdef HAVE_LIMITS_H
1956 # include <limits.h>
1957 #endif
1958 #ifndef LONG_MAX
1959 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
1960 #endif
1961 #ifndef LONG_MIN
1962 # define LONG_MIN (-1 - LONG_MAX)
1963 #endif
1965 /****************
1966 * A substitute for fseeko, for hosts that don't have it.
1968 static int
1969 fseeko( FILE *stream, off_t newpos, int whence )
1971 while( newpos != (long) newpos ) {
1972 long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
1973 if( fseek( stream, pos, whence ) != 0 )
1974 return -1;
1975 newpos -= pos;
1976 whence = SEEK_CUR;
1978 return fseek( stream, (long)newpos, whence );
1980 #endif
1982 /****************
1983 * This is a very limited implementation. It simply discards all internal
1984 * buffering and removes all filters but the first one.
1987 iobuf_seek( IOBUF a, off_t newpos )
1989 file_filter_ctx_t *b = NULL;
1991 if( a->directfp ) {
1992 FILE *fp = a->directfp;
1993 if( fseeko( fp, newpos, SEEK_SET ) ) {
1994 log_error("can't seek: %s\n", strerror(errno) );
1995 return -1;
1997 clearerr(fp);
1999 else {
2000 for( ; a; a = a->chain ) {
2001 if( !a->chain && a->filter == file_filter ) {
2002 b = a->filter_ov;
2003 break;
2006 if( !a )
2007 return -1;
2008 #ifdef FILE_FILTER_USES_STDIO
2009 if( fseeko( b->fp, newpos, SEEK_SET ) ) {
2010 log_error("can't fseek: %s\n", strerror(errno) );
2011 return -1;
2013 #else
2014 #ifdef HAVE_DOSISH_SYSTEM
2015 if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff ) {
2016 log_error ("SetFilePointer failed on handle %p: %s\n",
2017 b->fp, w32_strerror (0));
2018 return -1;
2020 #else
2021 if ( lseek (b->fp, newpos, SEEK_SET) == (off_t)-1 ) {
2022 log_error("can't lseek: %s\n", strerror(errno) );
2023 return -1;
2025 #endif
2026 #endif
2028 a->d.len = 0; /* discard buffer */
2029 a->d.start = 0;
2030 a->nbytes = 0;
2031 a->nlimit = 0;
2032 a->nofast &= ~1;
2033 a->ntotal = newpos;
2034 a->error = 0;
2035 /* remove filters, but the last */
2036 if( a->chain )
2037 log_debug("pop_filter called in iobuf_seek - please report\n");
2038 while( a->chain )
2039 pop_filter( a, a->filter, NULL );
2041 return 0;
2049 /****************
2050 * Retrieve the real filename
2052 const char *
2053 iobuf_get_real_fname( IOBUF a )
2055 if( a->real_fname )
2056 return a->real_fname;
2058 /* the old solution */
2059 for( ; a; a = a->chain )
2060 if( !a->chain && a->filter == file_filter ) {
2061 file_filter_ctx_t *b = a->filter_ov;
2062 return b->print_only_name? NULL : b->fname;
2065 return NULL;
2069 /****************
2070 * Retrieve the filename
2072 const char *
2073 iobuf_get_fname( IOBUF a )
2075 for( ; a; a = a->chain )
2076 if( !a->chain && a->filter == file_filter ) {
2077 file_filter_ctx_t *b = a->filter_ov;
2078 return b->fname;
2081 return NULL;
2085 /****************
2086 * enable partial block mode as described in the OpenPGP draft.
2087 * LEN is the first length byte on read, but ignored on writes.
2089 void
2090 iobuf_set_partial_block_mode( IOBUF a, size_t len )
2092 block_filter_ctx_t *ctx = xmalloc_clear( sizeof *ctx );
2094 assert( a->use == 1 || a->use == 2 );
2095 ctx->use = a->use;
2096 if( !len ) {
2097 if( a->use == 1 )
2098 log_debug("pop_filter called in set_partial_block_mode"
2099 " - please report\n");
2100 pop_filter(a, block_filter, NULL );
2102 else {
2103 ctx->partial = 1;
2104 ctx->size = 0;
2105 ctx->first_c = len;
2106 iobuf_push_filter(a, block_filter, ctx );
2111 /****************
2112 * Same as fgets() but if the buffer is too short a larger one will
2113 * be allocated up to some limit *max_length.
2114 * A line is considered a byte stream ending in a LF.
2115 * Returns the length of the line. EOF is indicated by a line of
2116 * length zero. The last LF may be missing due to an EOF.
2117 * is max_length is zero on return, the line has been truncated.
2119 * Note: The buffer is allocated with enough space to append a CR,LF,EOL
2121 unsigned
2122 iobuf_read_line( IOBUF a, byte **addr_of_buffer,
2123 unsigned *length_of_buffer, unsigned *max_length )
2125 int c;
2126 char *buffer = *addr_of_buffer;
2127 unsigned length = *length_of_buffer;
2128 unsigned nbytes = 0;
2129 unsigned maxlen = *max_length;
2130 char *p;
2132 if( !buffer ) { /* must allocate a new buffer */
2133 length = 256;
2134 buffer = xmalloc( length );
2135 *addr_of_buffer = buffer;
2136 *length_of_buffer = length;
2139 length -= 3; /* reserve 3 bytes (cr,lf,eol) */
2140 p = buffer;
2141 while( (c=iobuf_get(a)) != -1 ) {
2142 if( nbytes == length ) { /* increase the buffer */
2143 if( length > maxlen ) { /* this is out limit */
2144 /* skip the rest of the line */
2145 while( c != '\n' && (c=iobuf_get(a)) != -1 )
2147 *p++ = '\n'; /* always append a LF (we have reserved space) */
2148 nbytes++;
2149 *max_length = 0; /* indicate truncation */
2150 break;
2152 length += 3; /* correct for the reserved byte */
2153 length += length < 1024? 256 : 1024;
2154 buffer = xrealloc( buffer, length );
2155 *addr_of_buffer = buffer;
2156 *length_of_buffer = length;
2157 length -= 3; /* and reserve again */
2158 p = buffer + nbytes;
2160 *p++ = c;
2161 nbytes++;
2162 if( c == '\n' )
2163 break;
2165 *p = 0; /* make sure the line is a string */
2167 return nbytes;
2170 /* This is the non iobuf specific function */
2172 iobuf_translate_file_handle ( int fd, int for_write )
2174 #ifdef _WIN32
2176 int x;
2178 if ( fd <= 2 )
2179 return fd; /* do not do this for error, stdin, stdout, stderr */
2181 x = _open_osfhandle ( fd, for_write? 1:0 );
2182 if (x==-1 )
2183 log_error ("failed to translate osfhandle %p\n", (void*)fd );
2184 else {
2185 /*log_info ("_open_osfhandle %p yields %d%s\n",
2186 (void*)fd, x, for_write? " for writing":"" );*/
2187 fd = x;
2190 #endif
2191 return fd;
2194 static int
2195 translate_file_handle ( int fd, int for_write )
2197 #ifdef _WIN32
2198 #ifdef FILE_FILTER_USES_STDIO
2199 fd = iobuf_translate_file_handle (fd, for_write);
2200 #else
2202 int x;
2204 if ( fd == 0 )
2205 x = (int)GetStdHandle (STD_INPUT_HANDLE);
2206 else if (fd == 1)
2207 x = (int)GetStdHandle (STD_OUTPUT_HANDLE);
2208 else if (fd == 2)
2209 x = (int)GetStdHandle (STD_ERROR_HANDLE);
2210 else
2211 x = fd;
2213 if (x == -1)
2214 log_debug ("GetStdHandle(%d) failed: %s\n",
2215 fd, w32_strerror (0));
2217 fd = x;
2219 #endif
2220 #endif
2221 return fd;
2225 void
2226 iobuf_skip_rest(IOBUF a, unsigned long n, int partial)
2228 if ( partial ) {
2229 for (;;) {
2230 if (a->nofast || a->d.start >= a->d.len) {
2231 if (iobuf_readbyte (a) == -1) {
2232 break;
2234 } else {
2235 unsigned long count = a->d.len - a->d.start;
2236 a->nbytes += count;
2237 a->d.start = a->d.len;
2240 } else {
2241 unsigned long remaining = n;
2242 while (remaining > 0) {
2243 if (a->nofast || a->d.start >= a->d.len) {
2244 if (iobuf_readbyte (a) == -1) {
2245 break;
2247 --remaining;
2248 } else {
2249 unsigned long count = a->d.len - a->d.start;
2250 if (count > remaining) {
2251 count = remaining;
2253 a->nbytes += count;
2254 a->d.start += count;
2255 remaining -= count;