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,
30 #include <sys/types.h>
34 #ifdef HAVE_DOSISH_SYSTEM
40 #endif /* __riscos__ */
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
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)
68 FILE *fp
; /* open file handle */
71 int print_only_name
; /* flags indicating that fname is not a real file*/
72 char fname
[1]; /* name of the file */
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))
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)
91 FILEP_OR_FD fp
; /* open file handle */
95 int print_only_name
; /* flags indicating that fname is not a real file*/
96 char fname
[1]; /* name of the file */
99 struct close_cache_s
{
100 struct close_cache_s
*next
;
104 typedef struct close_cache_s
*CLOSE_CACHE
;
105 static CLOSE_CACHE close_cache
;
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
;
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
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)*/
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. */
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
== '/')) )
157 return *(const unsigned char *)a
- *(const unsigned char *)b
;
159 return strcmp (a
, b
);
164 * Invalidate (i.e. close) a cached iobuf
167 fd_cache_invalidate (const char *fname
)
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
) ) {
178 log_debug (" did (%s)\n", cc
->fname
);
179 #ifdef HAVE_DOSISH_SYSTEM
180 CloseHandle (cc
->fp
);
192 direct_open (const char *fname
, const char *mode
)
194 #ifdef HAVE_DOSISH_SYSTEM
195 unsigned long da
, cd
, sm
;
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
;
208 sm
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
210 else if ( strchr (mode
, 'w') ) {
211 fd_cache_invalidate (fname
);
214 sm
= FILE_SHARE_WRITE
;
219 sm
= FILE_SHARE_READ
;
222 hfile
= CreateFile (fname
, da
, sm
, NULL
, cd
, FILE_ATTRIBUTE_NORMAL
, NULL
);
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
);
233 else if ( strchr (mode
, 'w') ) {
234 fd_cache_invalidate (fname
);
235 oflag
= O_WRONLY
| O_CREAT
| O_TRUNC
;
241 if (strchr (mode
, 'b'))
245 return open (fname
, oflag
, cflag
);
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
);
255 return open( fname
, oflag
, cflag
);
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.
267 fd_cache_close (const char *fname
, FILEP_OR_FD fp
)
272 if ( !fname
|| !*fname
) {
273 #ifdef HAVE_DOSISH_SYSTEM
279 log_debug ("fd_cache_close (%p) real\n", (void*)fp
);
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
) ) {
287 log_debug ("fd_cache_close (%s) used existing slot\n", fname
);
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
);
297 cc
->next
= close_cache
;
302 * Do an direct_open on FNAME but first try to reuse one from the fd_cache
305 fd_cache_open (const char *fname
, const char *mode
)
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
;
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
));
323 if ( lseek (fp
, 0, SEEK_SET
) == (off_t
)-1 ) {
324 log_error("can't rewind fd %d: %s\n", fp
, strerror(errno
) );
332 log_debug ("fd_cache_open (%s) not cached\n", fname
);
333 return direct_open (fname
, mode
);
337 #endif /*FILE_FILTER_USES_STDIO*/
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.
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.
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
;
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. */
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
;
394 else if( control
== IOBUFCTRL_FLUSH
) {
397 nbytes
= fwrite( buf
, 1, size
, f
);
399 log_error("%s: write error: %s\n", a
->fname
, strerror(errno
));
400 rc
= G10ERR_WRITE_FILE
;
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
) {
414 log_debug("%s: close fd %d\n", a
->fname
, fileno(f
) );
419 xfree(a
); /* we can free our context now */
421 #else /* !stdio implementation */
423 if( control
== IOBUFCTRL_UNDERFLOW
) {
424 assert( size
); /* need a buffer */
430 #ifdef HAVE_DOSISH_SYSTEM
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
,
438 rc
= G10ERR_READ_FILE
;
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 */
475 else if( control
== IOBUFCTRL_FLUSH
) {
477 #ifdef HAVE_DOSISH_SYSTEM
483 if (size
&& !WriteFile (f
, p
, nbytes
, &n
, NULL
)) {
484 log_error ("%s: write error: %s\n", a
->fname
,
486 rc
= G10ERR_WRITE_FILE
;
500 n
= write ( f
, p
, nbytes
);
501 } while ( n
== -1 && errno
== EINTR
);
506 } while ( n
!= -1 && nbytes
);
508 log_error("%s: write error: %s\n", a
->fname
, strerror(errno
));
509 rc
= G10ERR_WRITE_FILE
;
516 else if ( control
== IOBUFCTRL_INIT
) {
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
) {
528 log_debug("%s: close handle %p\n", a
->fname
, f
);
530 fd_cache_close (a
->no_cache
?NULL
:a
->fname
, f
);
533 if ( (int)f
!= 0 && (int)f
!= 1 ) {
535 log_debug("%s: close fd %d\n", a
->fname
, f
);
537 fd_cache_close (a
->no_cache
?NULL
:a
->fname
, f
);
541 xfree (a
); /* we can free our context now */
543 #endif /* !stdio implementation */
548 /* Becuase sockets are an special object under Lose32 we have to
549 * use a special filter */
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
;
558 if( control
== IOBUFCTRL_UNDERFLOW
) {
559 assert( size
); /* need a buffer */
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
;
583 else if( control
== IOBUFCTRL_FLUSH
) {
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
;
604 else if ( control
== IOBUFCTRL_INIT
) {
609 else if ( control
== IOBUFCTRL_DESC
) {
610 *(char**)buf
= "sock_filter";
612 else if ( control
== IOBUFCTRL_FREE
) {
614 closesocket (a
->sock
);
615 xfree (a
); /* we can free our context now */
622 * This is used to implement the block write mode.
623 * Block reading is done on a byte by byte basis in readbyte(),
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;
634 if( control
== IOBUFCTRL_UNDERFLOW
) {
638 assert( size
); /* need a buffer */
639 if( a
->eof
) /* don't read any further */
641 while( !rc
&& size
) {
642 if( !a
->size
) { /* get the length bytes */
643 if( a
->partial
== 2 ) {
649 else if( a
->partial
) {
650 /* These OpenPGP introduced huffman like encoded length
651 * bytes are really a mess :-( */
656 else if( (c
= iobuf_get(chain
)) == -1 ) {
657 log_error("block_filter: 1st length byte missing\n");
658 rc
= G10ERR_READ_FILE
;
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
;
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
;
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);*/
714 while( !rc
&& size
&& a
->size
) {
715 needed
= size
< a
->size
? size
: a
->size
;
716 c
= iobuf_read( chain
, p
, needed
);
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
;
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*/
741 a
->buffer
= xmalloc( OP_MIN_PARTIAL_CHUNK
);
742 memcpy( a
->buffer
+ a
->buflen
, buf
, size
);
745 else { /* okay, we can write out something */
746 /* do this in a loop to use the most efficient block lengths */
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
;
756 /* write the partial length header */
757 assert( c
<= 0x1f ); /*;-)*/
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
;
767 if( (n
= nbytes
) > blen
)
769 if( n
&& iobuf_write(chain
, p
, n
) )
770 rc
= G10ERR_WRITE_FILE
;
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
);
779 a
->buffer
= xmalloc( OP_MIN_PARTIAL_CHUNK
);
780 memcpy( a
->buffer
, p
, nbytes
);
788 else if( control
== IOBUFCTRL_INIT
) {
790 log_debug("init block_filter %p\n", a
);
793 else if( a
->use
== 1 )
794 a
->count
= a
->size
= 0;
796 a
->count
= a
->size
; /* force first length bytes */
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 */
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.
818 /* construct header */
820 /*log_debug("partial: remaining length=%u\n", len );*/
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 );
835 rc
= iobuf_write(chain
, a
->buffer
, len
);
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;
846 log_error("block_filter: pending bytes!\n");
849 log_debug("free block_filter %p\n", a
);
850 xfree(a
); /* we can free our context now */
858 print_chain( IOBUF a
)
862 for(; a
; a
= a
->chain
) {
863 size_t dummy_len
= 0;
864 const char *desc
= "[none]";
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
)
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.
889 iobuf_alloc(int use
, size_t bufsize
)
894 a
= xmalloc_clear(sizeof *a
);
896 a
->d
.buf
= xmalloc( bufsize
);
901 a
->real_fname
= NULL
;
906 iobuf_close ( IOBUF a
)
912 if( a
&& a
->directfp
) {
913 fclose( a
->directfp
);
914 xfree( a
->real_fname
);
916 log_debug("iobuf_close -> %p\n", a
->directfp
);
920 for( ; a
&& !rc
; a
= a2
) {
922 if( a
->use
== 2 && (rc
=iobuf_flush(a
)) )
923 log_error("iobuf_flush failed on close: %s\n", g10_errstr(rc
));
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
);
932 memset (a
->d
.buf
, 0, a
->d
.size
); /* erase the buffer */
941 iobuf_cancel( IOBUF a
)
946 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
947 char *remove_name
= NULL
;
950 if( a
&& a
->use
== 2 ) {
951 s
= iobuf_get_real_fname(a
);
953 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
954 remove_name
= xstrdup ( s
);
961 /* send a cancel message to all filters */
962 for( a2
= a
; a2
; a2
= a2
->chain
) {
965 a2
->filter( a2
->filter_ov
, IOBUFCTRL_CANCEL
, a2
->chain
,
970 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
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
);
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
992 a
= iobuf_alloc(3, IOBUF_BUFFER_SIZE
);
998 iobuf_temp_with_content( const char *buffer
, size_t length
)
1002 a
= iobuf_alloc(3, length
);
1003 memcpy( a
->d
.buf
, buffer
, length
);
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
1018 * Returns this number or -1 if it is not the case.
1021 check_special_filename ( const char *fname
)
1023 if ( special_names_enabled
1024 && fname
&& *fname
== '-' && fname
[1] == '&' ) {
1028 for (i
=0; digitp (fname
+i
); i
++ )
1031 return atoi (fname
);
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]) )
1043 return check_special_filename (fname
) != -1;
1047 * Create a head iobuf for reading from a file
1048 * returns: NULL if an error occures and sets errno
1051 iobuf_open( const char *fname
)
1055 file_filter_ctx_t
*fcx
;
1060 if( !fname
|| (*fname
=='-' && !fname
[1]) ) {
1061 fp
= FILEP_OR_FD_FOR_STDIN
;
1063 setmode ( my_fileno(fp
) , O_BINARY
);
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
)
1072 a
= iobuf_alloc(1, IOBUF_BUFFER_SIZE
);
1073 fcx
= xmalloc( sizeof *fcx
+ strlen(fname
) );
1075 fcx
->print_only_name
= print_only
;
1076 strcpy(fcx
->fname
, fname
);
1078 a
->real_fname
= xstrdup( fname
);
1079 a
->filter
= file_filter
;
1081 file_filter( fcx
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &len
);
1082 file_filter( fcx
, IOBUFCTRL_INIT
, NULL
, NULL
, &len
);
1084 log_debug("iobuf-%d.%d: open `%s' fd=%d\n",
1085 a
->no
, a
->subno
, fname
, (int)my_fileno(fcx
->fp
) );
1091 * Create a head iobuf for reading from a file
1092 * returns: NULL if an error occures and sets errno
1095 iobuf_fdopen( int fd
, const char *mode
)
1099 file_filter_ctx_t
*fcx
;
1102 #ifdef FILE_FILTER_USES_STDIO
1103 if( !(fp
= fdopen(fd
, mode
)) )
1106 fp
= (FILEP_OR_FD
)fd
;
1108 a
= iobuf_alloc( strchr( mode
, 'w')? 2:1, IOBUF_BUFFER_SIZE
);
1109 fcx
= xmalloc( sizeof *fcx
+ 20 );
1111 fcx
->print_only_name
= 1;
1112 sprintf(fcx
->fname
, "[fd %d]", fd
);
1113 a
->filter
= file_filter
;
1115 file_filter( fcx
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &len
);
1116 file_filter( fcx
, IOBUFCTRL_INIT
, NULL
, NULL
, &len
);
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 */
1125 iobuf_sockopen ( int fd
, const char *mode
)
1129 sock_filter_ctx_t
*scx
;
1132 a
= iobuf_alloc( strchr( mode
, 'w')? 2:1, IOBUF_BUFFER_SIZE
);
1133 scx
= xmalloc( sizeof *scx
+ 25 );
1135 scx
->print_only_name
= 1;
1136 sprintf(scx
->fname
, "[sock %d]", fd
);
1137 a
->filter
= sock_filter
;
1139 sock_filter( scx
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &len
);
1140 sock_filter( scx
, IOBUFCTRL_INIT
, NULL
, NULL
, &len
);
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 */
1145 a
= iobuf_fdopen (fd
, mode
);
1151 * create an iobuf for writing to a file; the file will be created.
1154 iobuf_create( const char *fname
)
1158 file_filter_ctx_t
*fcx
;
1163 if( !fname
|| (*fname
=='-' && !fname
[1]) ) {
1164 fp
= FILEP_OR_FD_FOR_STDOUT
;
1166 setmode ( my_fileno(fp
) , O_BINARY
);
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
)
1175 a
= iobuf_alloc(2, IOBUF_BUFFER_SIZE
);
1176 fcx
= xmalloc( sizeof *fcx
+ strlen(fname
) );
1178 fcx
->print_only_name
= print_only
;
1179 strcpy(fcx
->fname
, fname
);
1181 a
->real_fname
= xstrdup( fname
);
1182 a
->filter
= file_filter
;
1184 file_filter( fcx
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &len
);
1185 file_filter( fcx
, IOBUFCTRL_INIT
, NULL
, NULL
, &len
);
1187 log_debug("iobuf-%d.%d: create `%s'\n", a
->no
, a
->subno
, a
->desc
);
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 */
1199 iobuf_append( const char *fname
)
1203 file_filter_ctx_t
*fcx
;
1208 else if( !(fp
= my_fopen(fname
, "ab")) )
1210 a
= iobuf_alloc(2, IOBUF_BUFFER_SIZE
);
1211 fcx
= xmalloc( sizeof *fcx
+ strlen(fname
) );
1213 strcpy(fcx
->fname
, fname
);
1214 a
->real_fname
= xstrdup( fname
);
1215 a
->filter
= file_filter
;
1217 file_filter( fcx
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &len
);
1218 file_filter( fcx
, IOBUFCTRL_INIT
, NULL
, NULL
, &len
);
1220 log_debug("iobuf-%d.%d: append `%s'\n", a
->no
, a
->subno
, a
->desc
);
1227 iobuf_openrw( const char *fname
)
1231 file_filter_ctx_t
*fcx
;
1236 else if( (fp
= my_fopen(fname
, "r+b")) == INVALID_FP
)
1238 a
= iobuf_alloc(2, IOBUF_BUFFER_SIZE
);
1239 fcx
= xmalloc( sizeof *fcx
+ strlen(fname
) );
1241 strcpy(fcx
->fname
, fname
);
1242 a
->real_fname
= xstrdup( fname
);
1243 a
->filter
= file_filter
;
1245 file_filter( fcx
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &len
);
1246 file_filter( fcx
, IOBUFCTRL_INIT
, NULL
, NULL
, &len
);
1248 log_debug("iobuf-%d.%d: openrw `%s'\n", a
->no
, a
->subno
, a
->desc
);
1255 iobuf_ioctl ( IOBUF a
, int cmd
, int intval
, void *ptrval
)
1257 if ( cmd
== 1 ) { /* keep system filepointer/descriptor open */
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
;
1268 else if( !a
->chain
&& a
->filter
== sock_filter
) {
1269 sock_filter_ctx_t
*b
= a
->filter_ov
;
1270 b
->keep_open
= intval
;
1275 else if ( cmd
== 2 ) { /* invalidate cache */
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
);
1286 else if ( cmd
== 3 ) { /* disallow/allow caching */
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
;
1297 else if( !a
->chain
&& a
->filter
== sock_filter
) {
1298 sock_filter_ctx_t
*b
= a
->filter_ov
;
1299 b
->no_cache
= intval
;
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
)
1333 if( a
->use
== 2 && (rc
=iobuf_flush(a
)) )
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
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 */
1348 a
->filter_ov
= NULL
;
1349 a
->filter_ov_owner
= 0;
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
);
1359 else { /* allocate a fresh buffer for the new stream */
1360 a
->d
.buf
= xmalloc( a
->d
.size
);
1364 /* disable nlimit for the new stream */
1365 a
->ntotal
= b
->ntotal
+ b
->nbytes
;
1366 a
->nlimit
= a
->nbytes
= 0;
1368 /* make a link from the new stream to the original stream */
1370 a
->opaque
= b
->opaque
;
1372 /* setup the function on the new stream */
1375 a
->filter_ov_owner
= rel_ov
;
1377 a
->subno
= b
->subno
+ 1;
1378 f( ov
, IOBUFCTRL_DESC
, NULL
, (byte
*)&a
->desc
, &dummy_len
);
1381 log_debug("iobuf-%d.%d: push `%s'\n", a
->no
, a
->subno
, a
->desc
);
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
) );
1393 * Remove an i/o filter.
1396 pop_filter( IOBUF a
, int (*f
)(void *opaque
, int control
,
1397 IOBUF chain
, byte
*buf
, size_t *len
), void *ov
)
1407 log_debug("iobuf-%d.%d: pop `%s'\n", a
->no
, a
->subno
, a
->desc
);
1408 if( !a
->filter
) { /* this is simple */
1412 xfree(a
->real_fname
);
1413 memcpy(a
,b
, sizeof *a
);
1417 for(b
=a
; b
; b
= b
->chain
)
1418 if( b
->filter
== f
&& (!ov
|| b
->filter_ov
== ov
) )
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
));
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
) );
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
1449 xfree(a
->real_fname
);
1450 memcpy(a
,b
, sizeof *a
);
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");
1467 * read underflow: read more bytes into the buffer and return
1468 * the first byte or -1 on EOF.
1476 assert( a
->d
.start
== a
->d
.len
);
1478 return -1; /* EOF because a temp buffer can't do an underflow */
1480 if( a
->filter_eof
) {
1484 log_debug("iobuf-%d.%d: pop `%s' in underflow\n",
1485 a
->no
, a
->subno
, a
->desc
);
1487 xfree(a
->real_fname
);
1488 memcpy(a
, b
, sizeof *a
);
1493 a
->filter_eof
= 0; /* for the top level filter */
1495 log_debug("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
1497 return -1; /* return one(!) EOF */
1501 log_debug("iobuf-%d.%d: error\n", a
->no
, a
->subno
);
1506 FILE *fp
= a
->directfp
;
1508 len
= fread( a
->d
.buf
, 1, a
->d
.size
, fp
);
1509 if( len
< a
->d
.size
) {
1515 return len
? a
->d
.buf
[a
->d
.start
++] : -1;
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
,
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 */
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
;
1545 a
->filter_ov
= NULL
;
1547 if( !len
&& a
->chain
) {
1550 log_debug("iobuf-%d.%d: pop `%s' in underflow (!len)\n",
1551 a
->no
, a
->subno
, a
->desc
);
1553 xfree(a
->real_fname
);
1554 memcpy(a
,b
, sizeof *a
);
1564 log_debug("iobuf-%d.%d: underflow: eof\n", a
->no
, a
->subno
);
1569 return a
->d
.buf
[a
->d
.start
++];
1573 log_debug("iobuf-%d.%d: underflow: eof (no filter)\n",
1575 return -1; /* no filter; return EOF */
1581 iobuf_flush(IOBUF a
)
1589 if( a
->use
== 3 ) { /* increase the temp buffer */
1591 size_t newsize
= a
->d
.size
+ IOBUF_BUFFER_SIZE
;
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
);
1600 a
->d
.size
= newsize
;
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");
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
;
1622 * Read a byte from the iobuf; returns -1 on EOF
1625 iobuf_readbyte(IOBUF a
)
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
;
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 */
1654 iobuf_read(IOBUF a
, byte
*buf
, unsigned buflen
)
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 ) {
1663 return -1; /* eof */
1675 if( n
< buflen
&& a
->d
.start
< a
->d
.len
) {
1676 unsigned size
= a
->d
.len
- a
->d
.start
;
1677 if( size
> buflen
- n
)
1680 memcpy( buf
, a
->d
.buf
+ a
->d
.start
, size
);
1687 if( (c
=underflow(a
)) == -1 ) {
1689 return n
? n
: -1/*EOF*/;
1695 } while( n
< buflen
);
1702 * Have a look at the iobuf.
1703 * NOTE: This only works in special cases.
1706 iobuf_peek(IOBUF a
, byte
*buf
, unsigned buflen
)
1713 if( !(a
->d
.start
< a
->d
.len
) ) {
1714 if( underflow(a
) == -1 )
1716 /* and unget this character */
1717 assert(a
->d
.start
== 1);
1721 for(n
=0 ; n
< buflen
&& (a
->d
.start
+n
) < a
->d
.len
; n
++, buf
++ )
1730 iobuf_writebyte(IOBUF a
, unsigned c
)
1736 if( a
->d
.len
== a
->d
.size
)
1737 if( iobuf_flush(a
) )
1740 assert( a
->d
.len
< a
->d
.size
);
1741 a
->d
.buf
[a
->d
.len
++] = c
;
1747 iobuf_write(IOBUF a
, byte
*buf
, unsigned buflen
)
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
);
1763 if( iobuf_flush(a
) )
1772 iobuf_writestr(IOBUF a
, const char *buf
)
1774 for( ; *buf
; buf
++ )
1775 if( iobuf_writebyte(a
, *buf
) )
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
);
1794 * copy the contents of the temp io stream to BUFFER.
1797 iobuf_temp_to_buffer( IOBUF a
, byte
*buffer
, size_t buflen
)
1799 size_t n
= a
->d
.len
;
1803 memcpy( buffer
, a
->d
.buf
, n
);
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
1815 iobuf_flush_temp( IOBUF temp
)
1817 while( temp
->chain
)
1818 pop_filter( temp
, temp
->filter
, NULL
);
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.
1827 iobuf_set_limit( IOBUF a
, off_t nlimit
)
1834 a
->ntotal
+= a
->nbytes
;
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. */
1844 iobuf_get_filelength (IOBUF a
, int *overflow
)
1852 FILE *fp
= a
->directfp
;
1854 if( !fstat(fileno(fp
), &st
) )
1856 log_error("fstat() failed: %s\n", strerror(errno
) );
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)
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
)
1876 handle
= dlopen ("kernel32.dll", RTLD_LAZY
);
1879 get_file_size_ex
= dlsym (handle
, "GetFileSizeEx");
1880 if (!get_file_size_ex
)
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
1894 if (get_file_size_ex (fp
, &size
))
1896 if (!size
.u
.HighPart
)
1897 return size
.u
.LowPart
;
1905 if ((size
=GetFileSize (fp
, NULL
)) != 0xffffffff)
1908 log_error ("GetFileSize for handle %p failed: %s\n",
1909 fp
, w32_strerror (0));
1911 if( !fstat(my_fileno(fp
), &st
) )
1913 log_error("fstat() failed: %s\n", strerror(errno
) );
1922 /* Return the file descriptor of the underlying file or -1 if it is
1925 iobuf_get_fd (IOBUF a
)
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
);
1944 * Tell the file position, where the next read will take place
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>
1959 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
1962 # define LONG_MIN (-1 - LONG_MAX)
1966 * A substitute for fseeko, for hosts that don't have it.
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 )
1978 return fseek( stream
, (long)newpos
, whence
);
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
;
1992 FILE *fp
= a
->directfp
;
1993 if( fseeko( fp
, newpos
, SEEK_SET
) ) {
1994 log_error("can't seek: %s\n", strerror(errno
) );
2000 for( ; a
; a
= a
->chain
) {
2001 if( !a
->chain
&& a
->filter
== file_filter
) {
2008 #ifdef FILE_FILTER_USES_STDIO
2009 if( fseeko( b
->fp
, newpos
, SEEK_SET
) ) {
2010 log_error("can't fseek: %s\n", strerror(errno
) );
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));
2021 if ( lseek (b
->fp
, newpos
, SEEK_SET
) == (off_t
)-1 ) {
2022 log_error("can't lseek: %s\n", strerror(errno
) );
2028 a
->d
.len
= 0; /* discard buffer */
2035 /* remove filters, but the last */
2037 log_debug("pop_filter called in iobuf_seek - please report\n");
2039 pop_filter( a
, a
->filter
, NULL
);
2050 * Retrieve the real filename
2053 iobuf_get_real_fname( IOBUF a
)
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
;
2070 * Retrieve the filename
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
;
2086 * enable partial block mode as described in the OpenPGP draft.
2087 * LEN is the first length byte on read, but ignored on writes.
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 );
2098 log_debug("pop_filter called in set_partial_block_mode"
2099 " - please report\n");
2100 pop_filter(a
, block_filter
, NULL
);
2106 iobuf_push_filter(a
, block_filter
, ctx
);
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
2122 iobuf_read_line( IOBUF a
, byte
**addr_of_buffer
,
2123 unsigned *length_of_buffer
, unsigned *max_length
)
2126 char *buffer
= *addr_of_buffer
;
2127 unsigned length
= *length_of_buffer
;
2128 unsigned nbytes
= 0;
2129 unsigned maxlen
= *max_length
;
2132 if( !buffer
) { /* must allocate a new buffer */
2134 buffer
= xmalloc( length
);
2135 *addr_of_buffer
= buffer
;
2136 *length_of_buffer
= length
;
2139 length
-= 3; /* reserve 3 bytes (cr,lf,eol) */
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) */
2149 *max_length
= 0; /* indicate truncation */
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
;
2165 *p
= 0; /* make sure the line is a string */
2170 /* This is the non iobuf specific function */
2172 iobuf_translate_file_handle ( int fd
, int for_write
)
2179 return fd
; /* do not do this for error, stdin, stdout, stderr */
2181 x
= _open_osfhandle ( fd
, for_write
? 1:0 );
2183 log_error ("failed to translate osfhandle %p\n", (void*)fd
);
2185 /*log_info ("_open_osfhandle %p yields %d%s\n",
2186 (void*)fd, x, for_write? " for writing":"" );*/
2195 translate_file_handle ( int fd
, int for_write
)
2198 #ifdef FILE_FILTER_USES_STDIO
2199 fd
= iobuf_translate_file_handle (fd
, for_write
);
2205 x
= (int)GetStdHandle (STD_INPUT_HANDLE
);
2207 x
= (int)GetStdHandle (STD_OUTPUT_HANDLE
);
2209 x
= (int)GetStdHandle (STD_ERROR_HANDLE
);
2214 log_debug ("GetStdHandle(%d) failed: %s\n",
2215 fd
, w32_strerror (0));
2226 iobuf_skip_rest(IOBUF a
, unsigned long n
, int partial
)
2230 if (a
->nofast
|| a
->d
.start
>= a
->d
.len
) {
2231 if (iobuf_readbyte (a
) == -1) {
2235 unsigned long count
= a
->d
.len
- a
->d
.start
;
2237 a
->d
.start
= a
->d
.len
;
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) {
2249 unsigned long count
= a
->d
.len
- a
->d
.start
;
2250 if (count
> remaining
) {
2254 a
->d
.start
+= count
;