/[winpt]/trunk/Gnupg/iobuf.c
ViewVC logotype

Contents of /trunk/Gnupg/iobuf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (show annotations)
Fri Oct 28 12:57:05 2005 UTC (19 years, 4 months ago) by werner
File MIME type: text/plain
File size: 42725 byte(s)
Second set of changes to use autotools for building.
1 /* iobuf.c - file handling
2 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 *
4 * This file is part of GnuPG.
5 *
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <ctype.h>
31 #include <assert.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <io.h>
36 #include <windows.h>
37
38 #include "openpgp.h"
39
40 #define my_fileno(a) (a)
41 #define my_fopen_ro(a,b) fd_cache_open ((a),(b))
42 #define my_fopen(a,b) direct_open ((a),(b))
43 typedef HANDLE FILEP_OR_FD;
44 #define INVALID_FP ((HANDLE)-1)
45 #define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
46 #define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
47 #undef USE_SETMODE
48 typedef struct {
49 FILEP_OR_FD fp; /* open file handle */
50 int keep_open;
51 int no_cache;
52 int eof_seen;
53 int print_only_name; /* flags indicating that fname is not a real file*/
54 char fname[1]; /* name of the file */
55 } file_filter_ctx_t ;
56
57 struct close_cache_s {
58 struct close_cache_s *next;
59 FILEP_OR_FD fp;
60 char fname[1];
61 };
62 typedef struct close_cache_s *CLOSE_CACHE;
63 static CLOSE_CACHE close_cache;
64
65 /* The first partial length header block must be of size 512
66 * to make it easier (and efficienter) we use a min. block size of 512
67 * for all chunks (but the last one) */
68 #define OP_MIN_PARTIAL_CHUNK 512
69 #define OP_MIN_PARTIAL_CHUNK_2POW 9
70
71 typedef struct {
72 int use;
73 size_t size;
74 size_t count;
75 int partial; /* 1 = partial header, 2 in last partial packet */
76 char *buffer; /* used for partial header */
77 size_t buflen; /* used size of buffer */
78 int first_c; /* of partial header (which is > 0)*/
79 int eof;
80 } block_filter_ctx_t;
81
82 static int special_names_enabled;
83
84 static int underflow(gpg_iobuf_t a);
85 static int translate_file_handle ( int fd, int for_write );
86
87 /*
88 * Invalidate (i.e. close) a cached iobuf
89 */
90 static void
91 fd_cache_invalidate (const char *fname)
92 {
93 CLOSE_CACHE cc;
94
95 assert (fname);
96
97 for (cc=close_cache; cc; cc = cc->next ) {
98 if ( cc->fp != INVALID_FP && !strcmp (cc->fname, fname) ) {
99 CloseHandle (cc->fp);
100 cc->fp = INVALID_FP;
101 }
102 }
103 }
104
105 static FILEP_OR_FD
106 direct_open (const char *fname, const char *mode)
107 {
108 unsigned long da, cd, sm;
109 HANDLE hfile;
110
111 /* Note, that we do not handle all mode combinations */
112
113 /* According to the ReactOS source it seems that open() of the
114 * standard MSW32 crt does open the file in share mode which is
115 * something new for MS applications ;-)
116 */
117 if ( strchr (mode, '+') ) {
118 fd_cache_invalidate (fname);
119 da = GENERIC_READ|GENERIC_WRITE;
120 cd = OPEN_EXISTING;
121 sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
122 }
123 else if ( strchr (mode, 'w') ) {
124 fd_cache_invalidate (fname);
125 da = GENERIC_WRITE;
126 cd = CREATE_ALWAYS;
127 sm = FILE_SHARE_WRITE;
128 }
129 else {
130 da = GENERIC_READ;
131 cd = OPEN_EXISTING;
132 sm = FILE_SHARE_READ;
133 }
134
135 hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
136 return hfile;
137 }
138
139
140 /*
141 * Instead of closing an FD we keep it open and cache it for later reuse
142 * Note that this caching strategy only works if the process does not chdir.
143 */
144 static void
145 fd_cache_close (const char *fname, FILEP_OR_FD fp)
146 {
147 CLOSE_CACHE cc;
148
149 assert (fp);
150 if ( !fname || !*fname ) {
151 CloseHandle (fp);
152 return;
153 }
154 /* try to reuse a slot */
155 for (cc=close_cache; cc; cc = cc->next ) {
156 if ( cc->fp == INVALID_FP && !strcmp (cc->fname, fname) ) {
157 cc->fp = fp;
158 return;
159 }
160 }
161 /* add a new one */
162 cc = calloc (1, sizeof *cc + strlen (fname));
163 strcpy (cc->fname, fname);
164 cc->fp = fp;
165 cc->next = close_cache;
166 close_cache = cc;
167 }
168
169 /*
170 * Do an direct_open on FNAME but first try to reuse one from the fd_cache
171 */
172 static FILEP_OR_FD
173 fd_cache_open (const char *fname, const char *mode)
174 {
175 CLOSE_CACHE cc;
176
177 assert (fname);
178 for (cc=close_cache; cc; cc = cc->next ) {
179 if ( cc->fp != INVALID_FP && !strcmp (cc->fname, fname) ) {
180 FILEP_OR_FD fp = cc->fp;
181 cc->fp = INVALID_FP;
182 if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff ) {
183 printf ("rewind file failed on handle %p: ec=%d\n",
184 fp, (int)GetLastError () );
185 fp = INVALID_FP;
186 }
187 return fp;
188 }
189 }
190 return direct_open (fname, mode);
191 }
192
193
194 /****************
195 * Read data from a file into buf which has an allocated length of *LEN.
196 * return the number of read bytes in *LEN. OPAQUE is the FILE * of
197 * the stream. A is not used.
198 * control may be:
199 * IOBUFCTRL_INIT: called just before the function is linked into the
200 * list of function. This can be used to prepare internal
201 * data structures of the function.
202 * IOBUFCTRL_FREE: called just before the function is removed from the
203 * list of functions and can be used to release internal
204 * data structures or close a file etc.
205 * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer
206 * with new stuff. *RET_LEN is the available size of the
207 * buffer, and should be set to the number of bytes
208 * which were put into the buffer. The function
209 * returns 0 to indicate success, -1 on EOF and
210 * G10ERR_xxxxx for other errors.
211 *
212 * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
213 * *RET_LAN is the number of bytes in BUF.
214 *
215 * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The
216 * filter may take appropriate action on this message.
217 */
218 static int
219 file_filter(void *opaque, int control, gpg_iobuf_t chain, byte *buf, size_t *ret_len)
220 {
221 file_filter_ctx_t *a = opaque;
222 FILEP_OR_FD f = a->fp;
223 size_t size = *ret_len;
224 size_t nbytes = 0;
225 int rc = 0;
226
227 if( control == IOBUFCTRL_UNDERFLOW ) {
228 assert( size ); /* need a buffer */
229 if ( a->eof_seen) {
230 rc = -1;
231 *ret_len = 0;
232 }
233 else {
234 unsigned long nread;
235
236 nbytes = 0;
237 if ( !ReadFile ( f, buf, size, &nread, NULL ) ) {
238 int ec = (int)GetLastError ();
239 if ( ec != ERROR_BROKEN_PIPE ) {
240 printf("%s: read error: ec=%d\n", a->fname, ec);
241 rc = G10ERR_READ_FILE;
242 }
243 }
244 else if ( !nread ) {
245 a->eof_seen = 1;
246 rc = -1;
247 }
248 else {
249 nbytes = nread;
250 }
251 *ret_len = nbytes;
252 }
253 }
254 else if( control == IOBUFCTRL_FLUSH ) {
255 if( size ) {
256 byte *p = buf;
257 unsigned long n;
258
259 nbytes = size;
260 do {
261 if ( size && !WriteFile ( f, p, nbytes, &n, NULL) ) {
262 int ec = (int)GetLastError ();
263 printf("%s: write error: ec=%d\n", a->fname, ec);
264 rc = G10ERR_WRITE_FILE;
265 break;
266 }
267 p += n;
268 nbytes -= n;
269 } while ( nbytes );
270 nbytes = p - buf;
271 }
272 *ret_len = nbytes;
273 }
274 else if ( control == IOBUFCTRL_INIT ) {
275 a->eof_seen = 0;
276 a->keep_open = 0;
277 a->no_cache = 0;
278 }
279 else if ( control == IOBUFCTRL_DESC ) {
280 *(char**)buf = "file_filter(fd)";
281 }
282 else if ( control == IOBUFCTRL_FREE ) {
283 if ( f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT ) {
284 if (!a->keep_open)
285 fd_cache_close (a->no_cache?NULL:a->fname, f);
286 }
287 safe_free (a); /* we can free our context now */
288 }
289 return rc;
290 }
291
292 /****************
293 * This is used to implement the block write mode.
294 * Block reading is done on a byte by byte basis in readbyte(),
295 * without a filter
296 */
297 static int
298 block_filter(void *opaque, int control, gpg_iobuf_t chain, byte *buf, size_t *ret_len)
299 {
300 block_filter_ctx_t *a = opaque;
301 size_t size = *ret_len;
302 int c, needed, rc = 0;
303 char *p;
304
305 if( control == IOBUFCTRL_UNDERFLOW ) {
306 size_t n=0;
307
308 p = buf;
309 assert( size ); /* need a buffer */
310 if( a->eof ) /* don't read any further */
311 rc = -1;
312 while( !rc && size ) {
313 if( !a->size ) { /* get the length bytes */
314 if( a->partial == 2 ) {
315 a->eof = 1;
316 if( !n )
317 rc = -1;
318 break;
319 }
320 else if( a->partial ) {
321 /* These OpenPGP introduced huffman like encoded length
322 * bytes are really a mess :-( */
323 if( a->first_c ) {
324 c = a->first_c;
325 a->first_c = 0;
326 }
327 else if( (c = gpg_iobuf_get(chain)) == -1 ) {
328 printf("block_filter: 1st length byte missing\n");
329 rc = G10ERR_READ_FILE;
330 break;
331 }
332 if( c < 192 ) {
333 a->size = c;
334 a->partial = 2;
335 if( !a->size ) {
336 a->eof = 1;
337 if( !n )
338 rc = -1;
339 break;
340 }
341 }
342 else if( c < 224 ) {
343 a->size = (c - 192) * 256;
344 if( (c = gpg_iobuf_get(chain)) == -1 ) {
345 printf("block_filter: 2nd length byte missing\n");
346 rc = G10ERR_READ_FILE;
347 break;
348 }
349 a->size += c + 192;
350 a->partial = 2;
351 if( !a->size ) {
352 a->eof = 1;
353 if( !n )
354 rc = -1;
355 break;
356 }
357 }
358 else if( c == 255 ) {
359 a->size = gpg_iobuf_get(chain) << 24;
360 a->size |= gpg_iobuf_get(chain) << 16;
361 a->size |= gpg_iobuf_get(chain) << 8;
362 if( (c = gpg_iobuf_get(chain)) == -1 ) {
363 printf("block_filter: invalid 4 byte length\n");
364 rc = G10ERR_READ_FILE;
365 break;
366 }
367 a->size |= c;
368 }
369 else { /* next partial body length */
370 a->size = 1 << (c & 0x1f);
371 }
372 /* printf("partial: ctx=%p c=%02x size=%u\n", a, c, a->size);*/
373 }
374 else { /* the gnupg partial length scheme - much better :-) */
375 c = gpg_iobuf_get(chain);
376 a->size = c << 8;
377 c = gpg_iobuf_get(chain);
378 a->size |= c;
379 if( c == -1 ) {
380 printf("block_filter: error reading length info\n");
381 rc = G10ERR_READ_FILE;
382 }
383 if( !a->size ) {
384 a->eof = 1;
385 if( !n )
386 rc = -1;
387 break;
388 }
389 }
390 }
391
392 while( !rc && size && a->size ) {
393 needed = size < a->size ? size : a->size;
394 c = gpg_iobuf_read( chain, p, needed );
395 if( c < needed ) {
396 if( c == -1 ) c = 0;
397 printf("block_filter %p: read error (size=%lu,a->size=%lu)\n",
398 a, (ulong)size+c, (ulong)a->size+c);
399 rc = G10ERR_READ_FILE;
400 }
401 else {
402 size -= c;
403 a->size -= c;
404 p += c;
405 n += c;
406 }
407 }
408 }
409 *ret_len = n;
410 }
411 else if( control == IOBUFCTRL_FLUSH ) {
412 if( a->partial ) { /* the complicated openpgp scheme */
413 size_t blen, n, nbytes = size + a->buflen;
414
415 assert( a->buflen <= OP_MIN_PARTIAL_CHUNK );
416 if( nbytes < OP_MIN_PARTIAL_CHUNK ) {
417 /* not enough to write a partial block out; so we store it*/
418 if( !a->buffer )
419 a->buffer = malloc( OP_MIN_PARTIAL_CHUNK );
420 memcpy( a->buffer + a->buflen, buf, size );
421 a->buflen += size;
422 }
423 else { /* okay, we can write out something */
424 /* do this in a loop to use the most efficient block lengths */
425 p = buf;
426 do {
427 /* find the best matching block length - this is limited
428 * by the size of the internal buffering */
429 for( blen=OP_MIN_PARTIAL_CHUNK*2,
430 c=OP_MIN_PARTIAL_CHUNK_2POW+1; blen <= nbytes;
431 blen *=2, c++ )
432 ;
433 blen /= 2; c--;
434 /* write the partial length header */
435 assert( c <= 0x1f ); /*;-)*/
436 c |= 0xe0;
437 gpg_iobuf_put( chain, c );
438 if( (n=a->buflen) ) { /* write stuff from the buffer */
439 assert( n == OP_MIN_PARTIAL_CHUNK);
440 if( gpg_iobuf_write(chain, a->buffer, n ) )
441 rc = G10ERR_WRITE_FILE;
442 a->buflen = 0;
443 nbytes -= n;
444 }
445 if( (n = nbytes) > blen )
446 n = blen;
447 if( n && gpg_iobuf_write(chain, p, n ) )
448 rc = G10ERR_WRITE_FILE;
449 p += n;
450 nbytes -= n;
451 } while( !rc && nbytes >= OP_MIN_PARTIAL_CHUNK );
452 /* store the rest in the buffer */
453 if( !rc && nbytes ) {
454 assert( !a->buflen );
455 assert( nbytes < OP_MIN_PARTIAL_CHUNK );
456 if( !a->buffer )
457 a->buffer = malloc( OP_MIN_PARTIAL_CHUNK );
458 memcpy( a->buffer, p, nbytes );
459 a->buflen = nbytes;
460 }
461 }
462 }
463 else { /* the gnupg scheme (which is not openpgp compliant) */
464 size_t avail, n;
465
466 for(p=buf; !rc && size; ) {
467 n = size;
468 avail = a->size - a->count;
469 if( !avail ) {
470 if( n > a->size ) {
471 gpg_iobuf_put( chain, (a->size >> 8) & 0xff );
472 gpg_iobuf_put( chain, a->size & 0xff );
473 avail = a->size;
474 a->count = 0;
475 }
476 else {
477 gpg_iobuf_put( chain, (n >> 8) & 0xff );
478 gpg_iobuf_put( chain, n & 0xff );
479 avail = n;
480 a->count = a->size - n;
481 }
482 }
483 if( n > avail )
484 n = avail;
485 if( gpg_iobuf_write(chain, p, n ) )
486 rc = G10ERR_WRITE_FILE;
487 a->count += n;
488 p += n;
489 size -= n;
490 }
491 }
492 }
493 else if( control == IOBUFCTRL_INIT ) {
494 if( a->partial )
495 a->count = 0;
496 else if( a->use == 1 )
497 a->count = a->size = 0;
498 else
499 a->count = a->size; /* force first length bytes */
500 a->eof = 0;
501 a->buffer = NULL;
502 a->buflen = 0;
503 }
504 else if( control == IOBUFCTRL_DESC ) {
505 *(char**)buf = "block_filter";
506 }
507 else if( control == IOBUFCTRL_FREE ) {
508 if( a->use == 2 ) { /* write the end markers */
509 if( a->partial ) {
510 u32 len;
511 /* write out the remaining bytes without a partial header
512 * the length of this header may be 0 - but if it is
513 * the first block we are not allowed to use a partial header
514 * and frankly we can't do so, because this length must be
515 * a power of 2. This is _really_ complicated because we
516 * have to check the possible length of a packet prior
517 * to it's creation: a chain of filters becomes complicated
518 * and we need a lot of code to handle compressed packets etc.
519 * :-(((((((
520 */
521 /* construct header */
522 len = a->buflen;
523 /*printf("partial: remaining length=%u\n", len );*/
524 if( len < 192 )
525 rc = gpg_iobuf_put(chain, len );
526 else if( len < 8384 ) {
527 if( !(rc=gpg_iobuf_put( chain, ((len-192) / 256) + 192)) )
528 rc = gpg_iobuf_put( chain, ((len-192) % 256));
529 }
530 else { /* use a 4 byte header */
531 if( !(rc=gpg_iobuf_put( chain, 0xff )) )
532 if( !(rc=gpg_iobuf_put( chain, (len >> 24)&0xff )) )
533 if( !(rc=gpg_iobuf_put( chain, (len >> 16)&0xff )) )
534 if( !(rc=gpg_iobuf_put( chain, (len >> 8)&0xff )))
535 rc=gpg_iobuf_put( chain, len & 0xff );
536 }
537 if( !rc && len )
538 rc = gpg_iobuf_write(chain, a->buffer, len );
539 if( rc ) {
540 printf("block_filter: write error: %s\n",strerror(errno));
541 rc = G10ERR_WRITE_FILE;
542 }
543 safe_free( a->buffer ); a->buffer = NULL; a->buflen = 0;
544 }
545 else {
546 gpg_iobuf_writebyte(chain, 0);
547 gpg_iobuf_writebyte(chain, 0);
548 }
549 }
550 else if( a->size ) {
551 printf("block_filter: pending bytes!\n");
552 }
553 safe_free(a); /* we can free our context now */
554 }
555
556 return rc;
557 }
558
559 /****************
560 * Allocate a new io buffer, with no function assigned.
561 * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer
562 * BUFSIZE is a suggested buffer size.
563 */
564 gpg_iobuf_t
565 gpg_iobuf_alloc(int use, size_t bufsize)
566 {
567 gpg_iobuf_t a;
568 static int number=0;
569
570 a = calloc(1, sizeof *a);
571 a->use = use;
572 a->d.buf = malloc( bufsize );
573 a->d.size = bufsize;
574 a->no = ++number;
575 a->subno = 0;
576 a->opaque = NULL;
577 a->real_fname = NULL;
578 return a;
579 }
580
581 int
582 gpg_iobuf_close( gpg_iobuf_t a )
583 {
584 gpg_iobuf_t a2;
585 size_t dummy_len=0;
586 int rc=0;
587
588 if( a && a->directfp ) {
589 fclose( a->directfp );
590 safe_free( a->real_fname );
591 return 0;
592 }
593
594 for( ; a && !rc ; a = a2 ) {
595 a2 = a->chain;
596 if( a->use == 2 && (rc=gpg_iobuf_flush(a)) )
597 printf("iobuf_flush failed on close\n");
598 if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE,
599 a->chain, NULL, &dummy_len)) )
600 printf("IOBUFCTRL_FREE failed on close\n");
601 safe_free(a->real_fname);
602 if (a->d.buf) {
603 memset (a->d.buf, 0, a->d.size); /* erase the buffer */
604 safe_free(a->d.buf);
605 }
606 safe_free(a);
607 }
608
609 return rc;
610 }
611
612 int
613 gpg_iobuf_cancel( gpg_iobuf_t a )
614 {
615 const char *s;
616 gpg_iobuf_t a2;
617 int rc;
618 char *remove_name = NULL;
619
620 if( a && a->use == 2 ) {
621 s = gpg_iobuf_get_real_fname(a);
622 if( s && *s ) {
623 remove_name = strdup ( s );
624 }
625 }
626
627 /* send a cancel message to all filters */
628 for( a2 = a; a2 ; a2 = a2->chain ) {
629 size_t dummy;
630 if( a2->filter )
631 a2->filter( a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain,
632 NULL, &dummy );
633 }
634
635 rc = gpg_iobuf_close(a);
636 if ( remove_name ) {
637 /* Argg, MSDOS does not allow to remove open files. So
638 * we have to do it here */
639 remove ( remove_name );
640 safe_free ( remove_name );
641 }
642 return rc;
643 }
644
645
646 /****************
647 * create a temporary iobuf, which can be used to collect stuff
648 * in an iobuf and later be written by iobuf_write_temp() to another
649 * iobuf.
650 */
651 gpg_iobuf_t
652 gpg_iobuf_temp( void )
653 {
654 gpg_iobuf_t a;
655
656 a = gpg_iobuf_alloc(3, 8192 );
657
658 return a;
659 }
660
661 gpg_iobuf_t
662 gpg_iobuf_temp_with_content( const char *buffer, size_t length )
663 {
664 gpg_iobuf_t a;
665
666 a = gpg_iobuf_alloc(3, length );
667 memcpy( a->d.buf, buffer, length );
668 a->d.len = length;
669
670 return a;
671 }
672
673 void
674 gpg_iobuf_enable_special_filenames ( int yes )
675 {
676 special_names_enabled = yes;
677 }
678
679 /*
680 * see whether the filename has the for "-&nnnn", where n is a
681 * non-zero number.
682 * Returns this number or -1 if it is not the case.
683 */
684 static int
685 check_special_filename ( const char *fname )
686 {
687 if ( special_names_enabled
688 && fname && *fname == '-' && fname[1] == '&' ) {
689 int i;
690
691 fname += 2;
692 for (i=0; isdigit (fname[i]); i++ )
693 ;
694 if ( !fname[i] )
695 return atoi (fname);
696 }
697 return -1;
698 }
699
700 /****************
701 * Create a head iobuf for reading from a file
702 * returns: NULL if an error occures and sets errno
703 */
704 gpg_iobuf_t
705 gpg_iobuf_open( const char *fname )
706 {
707 gpg_iobuf_t a;
708 FILEP_OR_FD fp;
709 file_filter_ctx_t *fcx;
710 size_t len;
711 int print_only = 0;
712 int fd;
713
714 if( !fname || (*fname=='-' && !fname[1]) ) {
715 fp = FILEP_OR_FD_FOR_STDIN;
716 //setmode ( my_fileno(fp) , O_BINARY );
717 fname = "[stdin]";
718 print_only = 1;
719 }
720 else if ( (fd = check_special_filename ( fname )) != -1 )
721 return gpg_iobuf_fdopen ( translate_file_handle (fd,0), "rb" );
722 else if( (fp = my_fopen_ro(fname, "rb")) == INVALID_FP )
723 return NULL;
724 a = gpg_iobuf_alloc(1, 8192 );
725 fcx = malloc( sizeof *fcx + strlen(fname) );
726 fcx->fp = fp;
727 fcx->print_only_name = print_only;
728 strcpy(fcx->fname, fname );
729 if( !print_only )
730 a->real_fname = strdup( fname );
731 a->filter = file_filter;
732 a->filter_ov = fcx;
733 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
734 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
735
736 return a;
737 }
738
739 /****************
740 * Create a head iobuf for reading from a file
741 * returns: NULL if an error occures and sets errno
742 */
743 gpg_iobuf_t
744 gpg_iobuf_fdopen( int fd, const char *mode )
745 {
746 gpg_iobuf_t a;
747 FILEP_OR_FD fp;
748 file_filter_ctx_t *fcx;
749 size_t len;
750
751 fp = (FILEP_OR_FD)fd;
752 a = gpg_iobuf_alloc( strchr( mode, 'w')? 2:1, 8192 );
753 fcx = malloc( sizeof *fcx + 20 );
754 fcx->fp = fp;
755 fcx->print_only_name = 1;
756 sprintf(fcx->fname, "[fd %d]", fd );
757 a->filter = file_filter;
758 a->filter_ov = fcx;
759 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
760 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
761 gpg_iobuf_ioctl (a,3,1,NULL); /* disable fd caching */
762 return a;
763 }
764
765 /****************
766 * create an iobuf for writing to a file; the file will be created.
767 */
768 gpg_iobuf_t
769 gpg_iobuf_create( const char *fname )
770 {
771 gpg_iobuf_t a;
772 FILEP_OR_FD fp;
773 file_filter_ctx_t *fcx;
774 size_t len;
775 int print_only = 0;
776 int fd;
777
778 if( !fname || (*fname=='-' && !fname[1]) ) {
779 fp = FILEP_OR_FD_FOR_STDOUT;
780 fname = "[stdout]";
781 print_only = 1;
782 }
783 else if ( (fd = check_special_filename ( fname )) != -1 )
784 return gpg_iobuf_fdopen ( translate_file_handle (fd, 1), "wb" );
785 else if( (fp = my_fopen(fname, "wb")) == INVALID_FP )
786 return NULL;
787 a = gpg_iobuf_alloc(2, 8192 );
788 fcx = malloc( sizeof *fcx + strlen(fname) );
789 fcx->fp = fp;
790 fcx->print_only_name = print_only;
791 strcpy(fcx->fname, fname );
792 if( !print_only )
793 a->real_fname = strdup( fname );
794 a->filter = file_filter;
795 a->filter_ov = fcx;
796 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
797 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
798
799 return a;
800 }
801
802 gpg_iobuf_t
803 gpg_iobuf_openrw( const char *fname )
804 {
805 gpg_iobuf_t a;
806 FILEP_OR_FD fp;
807 file_filter_ctx_t *fcx;
808 size_t len;
809
810 if( !fname )
811 return NULL;
812 else if( (fp = my_fopen(fname, "r+b")) == INVALID_FP )
813 return NULL;
814 a = gpg_iobuf_alloc(2, 8192 );
815 fcx = malloc( sizeof *fcx + strlen(fname) );
816 fcx->fp = fp;
817 strcpy(fcx->fname, fname );
818 a->real_fname = strdup( fname );
819 a->filter = file_filter;
820 a->filter_ov = fcx;
821 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
822 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
823
824 return a;
825 }
826
827
828 int
829 gpg_iobuf_ioctl ( gpg_iobuf_t a, int cmd, int intval, void *ptrval )
830 {
831 if ( cmd == 1 ) { /* keep system filepointer/descriptor open */
832 for( ; a; a = a->chain )
833 if( !a->chain && a->filter == file_filter ) {
834 file_filter_ctx_t *b = a->filter_ov;
835 b->keep_open = intval;
836 return 0;
837 }
838 }
839 else if ( cmd == 2 ) { /* invalidate cache */
840 if ( !a && !intval && ptrval ) {
841 fd_cache_invalidate (ptrval);
842 return 0;
843 }
844 }
845 else if ( cmd == 3 ) { /* disallow/allow caching */
846 for( ; a; a = a->chain )
847 if( !a->chain && a->filter == file_filter ) {
848 file_filter_ctx_t *b = a->filter_ov;
849 b->no_cache = intval;
850 return 0;
851 }
852 }
853
854 return -1;
855 }
856
857
858 /****************
859 * Register an i/o filter.
860 */
861 int
862 gpg_iobuf_push_filter( gpg_iobuf_t a,
863 int (*f)(void *opaque, int control,
864 gpg_iobuf_t chain, byte *buf, size_t *len), void *ov )
865 {
866 return gpg_iobuf_push_filter2( a, f, ov, 0 );
867 }
868
869 int
870 gpg_iobuf_push_filter2( gpg_iobuf_t a,
871 int (*f)(void *opaque, int control,
872 gpg_iobuf_t chain, byte *buf, size_t *len),
873 void *ov, int rel_ov )
874 {
875 gpg_iobuf_t b;
876 size_t dummy_len=0;
877 int rc=0;
878
879 if( a->directfp ) {
880 printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
881 exit( -1 );
882 }
883
884 if( a->use == 2 && (rc=gpg_iobuf_flush(a)) )
885 return rc;
886 /* make a copy of the current stream, so that
887 * A is the new stream and B the original one.
888 * The contents of the buffers are transferred to the
889 * new stream.
890 */
891 b = malloc(sizeof *b);
892 memcpy(b, a, sizeof *b );
893 /* fixme: it is stupid to keep a copy of the name at every level
894 * but we need the name somewhere because the name known by file_filter
895 * may have been released when we need the name of the file */
896 b->real_fname = a->real_fname? strdup(a->real_fname):NULL;
897 /* remove the filter stuff from the new stream */
898 a->filter = NULL;
899 a->filter_ov = NULL;
900 a->filter_ov_owner = 0;
901 a->filter_eof = 0;
902 if( a->use == 3 )
903 a->use = 2; /* make a write stream from a temp stream */
904
905 if( a->use == 2 ) { /* allocate a fresh buffer for the original stream */
906 b->d.buf = malloc( a->d.size );
907 b->d.len = 0;
908 b->d.start = 0;
909 }
910 else { /* allocate a fresh buffer for the new stream */
911 a->d.buf = malloc( a->d.size );
912 a->d.len = 0;
913 a->d.start = 0;
914 }
915 /* disable nlimit for the new stream */
916 a->ntotal = b->ntotal + b->nbytes;
917 a->nlimit = a->nbytes = 0;
918 a->nofast &= ~1;
919 /* make a link from the new stream to the original stream */
920 a->chain = b;
921 a->opaque = b->opaque;
922
923 /* setup the function on the new stream */
924 a->filter = f;
925 a->filter_ov = ov;
926 a->filter_ov_owner = rel_ov;
927
928 a->subno = b->subno + 1;
929 f( ov, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &dummy_len );
930
931 /* now we can initialize the new function if we have one */
932 if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_INIT, a->chain,
933 NULL, &dummy_len)) )
934 printf("IOBUFCTRL_INIT failed\n");
935 return rc;
936 }
937
938 /****************
939 * Remove an i/o filter.
940 */
941 int
942 pop_filter( gpg_iobuf_t a, int (*f)(void *opaque, int control,
943 gpg_iobuf_t chain, byte *buf, size_t *len), void *ov )
944 {
945 gpg_iobuf_t b;
946 size_t dummy_len=0;
947 int rc=0;
948
949 if( a->directfp ) {
950 printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
951 exit( -1 );
952 }
953
954 if( !a->filter ) { /* this is simple */
955 b = a->chain;
956 assert(b);
957 safe_free(a->d.buf);
958 safe_free(a->real_fname);
959 memcpy(a,b, sizeof *a);
960 safe_free(b);
961 return 0;
962 }
963 for(b=a ; b; b = b->chain )
964 if( b->filter == f && (!ov || b->filter_ov == ov) )
965 break;
966 if( !b )
967 printf("pop_filter(): filter function not found\n");
968
969 /* flush this stream if it is an output stream */
970 if( a->use == 2 && (rc=gpg_iobuf_flush(b)) ) {
971 printf("iobuf_flush failed in pop_filter\n");
972 return rc;
973 }
974 /* and tell the filter to free it self */
975 if( b->filter && (rc = b->filter(b->filter_ov, IOBUFCTRL_FREE, b->chain,
976 NULL, &dummy_len)) ) {
977 printf("IOBUFCTRL_FREE failed\n");
978 return rc;
979 }
980 if( b->filter_ov && b->filter_ov_owner ) {
981 safe_free( b->filter_ov );
982 b->filter_ov = NULL;
983 }
984
985
986 /* and see how to remove it */
987 if( a == b && !b->chain )
988 printf("can't remove the last filter from the chain\n");
989 else if( a == b ) { /* remove the first iobuf from the chain */
990 /* everything from b is copied to a. This is save because
991 * a flush has been done on the to be removed entry
992 */
993 b = a->chain;
994 safe_free(a->d.buf);
995 safe_free(a->real_fname);
996 memcpy(a,b, sizeof *a);
997 safe_free(b);
998 }
999 else if( !b->chain ) { /* remove the last iobuf from the chain */
1000 printf("Ohh jeee, trying to remove a head filter\n");
1001 }
1002 else { /* remove an intermediate iobuf from the chain */
1003 printf("Ohh jeee, trying to remove an intermediate filter\n");
1004 }
1005
1006 return rc;
1007 }
1008
1009
1010 /****************
1011 * read underflow: read more bytes into the buffer and return
1012 * the first byte or -1 on EOF.
1013 */
1014 static int
1015 underflow(gpg_iobuf_t a)
1016 {
1017 size_t len;
1018 int rc;
1019
1020 assert( a->d.start == a->d.len );
1021 if( a->use == 3 )
1022 return -1; /* EOF because a temp buffer can't do an underflow */
1023
1024 if( a->filter_eof ) {
1025 if( a->chain ) {
1026 gpg_iobuf_t b = a->chain;
1027 safe_free(a->d.buf);
1028 safe_free(a->real_fname);
1029 memcpy(a, b, sizeof *a);
1030 safe_free(b);
1031 }
1032 else
1033 a->filter_eof = 0; /* for the top level filter */
1034 return -1; /* return one(!) EOF */
1035 }
1036 if( a->error ) {
1037 return -1;
1038 }
1039
1040 if( a->directfp ) {
1041 FILE *fp = a->directfp;
1042
1043 len = fread( a->d.buf, 1, a->d.size, fp);
1044 if( len < a->d.size ) {
1045 if( ferror(fp) )
1046 a->error = 1;
1047 }
1048 a->d.len = len;
1049 a->d.start = 0;
1050 return len? a->d.buf[a->d.start++] : -1;
1051 }
1052
1053
1054 if( a->filter ) {
1055 len = a->d.size;
1056 rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1057 a->d.buf, &len );
1058 if( a->use == 1 && rc == -1 ) { /* EOF: we can remove the filter */
1059 size_t dummy_len=0;
1060
1061 /* and tell the filter to free itself */
1062 if( (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain,
1063 NULL, &dummy_len)) )
1064 printf("IOBUFCTRL_FREE failed\n");
1065 if( a->filter_ov && a->filter_ov_owner ) {
1066 safe_free( a->filter_ov );
1067 a->filter_ov = NULL;
1068 }
1069 a->filter = NULL;
1070 a->desc = NULL;
1071 a->filter_ov = NULL;
1072 a->filter_eof = 1;
1073 if( !len && a->chain ) {
1074 gpg_iobuf_t b = a->chain;
1075 safe_free(a->d.buf);
1076 safe_free(a->real_fname);
1077 memcpy(a,b, sizeof *a);
1078 safe_free(b);
1079 }
1080 }
1081 else if( rc )
1082 a->error = 1;
1083
1084 if( !len ) {
1085 return -1;
1086 }
1087 a->d.len = len;
1088 a->d.start = 0;
1089 return a->d.buf[a->d.start++];
1090 }
1091 else {
1092 return -1; /* no filter; return EOF */
1093 }
1094 }
1095
1096
1097 int
1098 gpg_iobuf_flush(gpg_iobuf_t a)
1099 {
1100 size_t len;
1101 int rc;
1102
1103 if( a->directfp )
1104 return 0;
1105
1106 if( a->use == 3 ) { /* increase the temp buffer */
1107 char *newbuf;
1108 size_t newsize = a->d.size + 8192;
1109
1110 printf("increasing temp iobuf from %lu to %lu\n",
1111 (ulong)a->d.size, (ulong)newsize );
1112 newbuf = malloc( newsize );
1113 memcpy( newbuf, a->d.buf, a->d.len );
1114 safe_free(a->d.buf);
1115 a->d.buf = newbuf;
1116 a->d.size = newsize;
1117 return 0;
1118 }
1119 else if( a->use != 2 )
1120 printf("flush on non-output iobuf\n");
1121 else if( !a->filter )
1122 printf("iobuf_flush: no filter\n");
1123 len = a->d.len;
1124 rc = a->filter( a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len );
1125 if( !rc && len != a->d.len ) {
1126 printf("iobuf_flush did not write all!\n");
1127 rc = G10ERR_WRITE_FILE;
1128 }
1129 else if( rc )
1130 a->error = 1;
1131 a->d.len = 0;
1132
1133 return rc;
1134 }
1135
1136
1137 /****************
1138 * Read a byte from the iobuf; returns -1 on EOF
1139 */
1140 int
1141 gpg_iobuf_readbyte(gpg_iobuf_t a)
1142 {
1143 int c;
1144
1145 /* nlimit does not work together with unget */
1146 /* nbytes is also not valid! */
1147 if( a->unget.buf ) {
1148 if( a->unget.start < a->unget.len )
1149 return a->unget.buf[a->unget.start++];
1150 safe_free(a->unget.buf);
1151 a->unget.buf = NULL;
1152 a->nofast &= ~2;
1153 }
1154
1155 if( a->nlimit && a->nbytes >= a->nlimit )
1156 return -1; /* forced EOF */
1157
1158 if( a->d.start < a->d.len ) {
1159 c = a->d.buf[a->d.start++];
1160 }
1161 else if( (c=underflow(a)) == -1 )
1162 return -1; /* EOF */
1163
1164 a->nbytes++;
1165 return c;
1166 }
1167
1168
1169 int
1170 gpg_iobuf_read(gpg_iobuf_t a, byte *buf, unsigned buflen )
1171 {
1172 int c, n;
1173
1174 if( a->unget.buf || a->nlimit ) {
1175 /* handle special cases */
1176 for(n=0 ; n < buflen; n++ ) {
1177 if( (c = gpg_iobuf_readbyte(a)) == -1 ) {
1178 if( !n )
1179 return -1; /* eof */
1180 break;
1181 }
1182 else
1183 if( buf ) *buf = c;
1184 if( buf ) buf++;
1185 }
1186 return n;
1187 }
1188
1189 n = 0;
1190 do {
1191 if( n < buflen && a->d.start < a->d.len ) {
1192 unsigned size = a->d.len - a->d.start;
1193 if( size > buflen - n )
1194 size = buflen - n;
1195 if( buf )
1196 memcpy( buf, a->d.buf + a->d.start, size );
1197 n += size;
1198 a->d.start += size;
1199 if( buf )
1200 buf += size;
1201 }
1202 if( n < buflen ) {
1203 if( (c=underflow(a)) == -1 ) {
1204 a->nbytes += n;
1205 return n? n : -1/*EOF*/;
1206 }
1207 if( buf )
1208 *buf++ = c;
1209 n++;
1210 }
1211 } while( n < buflen );
1212 a->nbytes += n;
1213 return n;
1214 }
1215
1216
1217 /****************
1218 * Have a look at the iobuf.
1219 * NOTE: This only works in special cases.
1220 */
1221 int
1222 gpg_iobuf_peek(gpg_iobuf_t a, byte *buf, unsigned buflen )
1223 {
1224 int n=0;
1225
1226 if( a->filter_eof )
1227 return -1;
1228
1229 if( !(a->d.start < a->d.len) ) {
1230 if( underflow(a) == -1 )
1231 return -1;
1232 /* and unget this character */
1233 assert(a->d.start == 1);
1234 a->d.start = 0;
1235 }
1236
1237 for(n=0 ; n < buflen && (a->d.start+n) < a->d.len ; n++, buf++ )
1238 *buf = a->d.buf[n];
1239 return n;
1240 }
1241
1242
1243
1244
1245 int
1246 gpg_iobuf_writebyte(gpg_iobuf_t a, unsigned c)
1247 {
1248
1249 if( a->directfp ) {
1250 printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
1251 exit( -1 );
1252 }
1253
1254 if( a->d.len == a->d.size )
1255 if( gpg_iobuf_flush(a) )
1256 return -1;
1257
1258 assert( a->d.len < a->d.size );
1259 a->d.buf[a->d.len++] = c;
1260 return 0;
1261 }
1262
1263
1264 int
1265 gpg_iobuf_write(gpg_iobuf_t a, byte *buf, unsigned buflen )
1266 {
1267
1268 if( a->directfp ) {
1269 printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
1270 exit( -1 );
1271 }
1272
1273 do {
1274 if( buflen && a->d.len < a->d.size ) {
1275 unsigned size = a->d.size - a->d.len;
1276 if( size > buflen ) size = buflen;
1277 memcpy( a->d.buf + a->d.len, buf, size );
1278 buflen -= size;
1279 buf += size;
1280 a->d.len += size;
1281 }
1282 if( buflen ) {
1283 if( gpg_iobuf_flush(a) )
1284 return -1;
1285 }
1286 } while( buflen );
1287 return 0;
1288 }
1289
1290
1291 int
1292 gpg_iobuf_writestr(gpg_iobuf_t a, const char *buf )
1293 {
1294 for( ; *buf; buf++ )
1295 if( gpg_iobuf_writebyte(a, *buf) )
1296 return -1;
1297 return 0;
1298 }
1299
1300
1301
1302 /****************
1303 * copy the contents of TEMP to A.
1304 */
1305 int
1306 gpg_iobuf_write_temp( gpg_iobuf_t a, gpg_iobuf_t temp )
1307 {
1308 while( temp->chain )
1309 pop_filter( temp, temp->filter, NULL );
1310 return gpg_iobuf_write(a, temp->d.buf, temp->d.len );
1311 }
1312
1313 /****************
1314 * copy the contents of the temp io stream to BUFFER.
1315 */
1316 size_t
1317 gpg_iobuf_temp_to_buffer( gpg_iobuf_t a, byte *buffer, size_t buflen )
1318 {
1319 size_t n = a->d.len;
1320
1321 if( n > buflen )
1322 n = buflen;
1323 memcpy( buffer, a->d.buf, n );
1324 return n;
1325 }
1326
1327
1328 /****************
1329 * Call this function to terminate processing of the temp stream
1330 * without closing it. This removes all filters from the stream
1331 * makes sure that iobuf_get_temp_{buffer,length}() returns correct
1332 * values.
1333 */
1334 void
1335 gpg_iobuf_flush_temp( gpg_iobuf_t temp )
1336 {
1337 while( temp->chain )
1338 pop_filter( temp, temp->filter, NULL );
1339 }
1340
1341
1342 /****************
1343 * Set a limit on how many bytes may be read from the input stream A.
1344 * Setting the limit to 0 disables this feature.
1345 */
1346 void
1347 gpg_iobuf_set_limit( gpg_iobuf_t a, _off_t nlimit )
1348 {
1349 if( nlimit )
1350 a->nofast |= 1;
1351 else
1352 a->nofast &= ~1;
1353 a->nlimit = nlimit;
1354 a->ntotal += a->nbytes;
1355 a->nbytes = 0;
1356 }
1357
1358
1359
1360 /****************
1361 * Return the length of an open file
1362 */
1363 _off_t
1364 gpg_iobuf_get_filelength( gpg_iobuf_t a )
1365 {
1366 struct stat st;
1367
1368 if( a->directfp ) {
1369 FILE *fp = a->directfp;
1370
1371 if( !fstat(fileno(fp), &st) )
1372 return st.st_size;
1373 printf("fstat() failed: %s\n", strerror(errno) );
1374 return 0;
1375 }
1376
1377 /* Hmmm: file_filter may have already been removed */
1378 for( ; a; a = a->chain )
1379 if( !a->chain && a->filter == file_filter ) {
1380 file_filter_ctx_t *b = a->filter_ov;
1381 FILEP_OR_FD fp = b->fp;
1382
1383 ulong size;
1384
1385 if ( (size=GetFileSize (fp, NULL)) != 0xffffffff )
1386 return size;
1387 printf ("GetFileSize for handle %p failed: ec=%d\n",
1388 fp, (int)GetLastError () );
1389 break;
1390 }
1391
1392 return 0;
1393 }
1394
1395 /****************
1396 * Tell the file position, where the next read will take place
1397 */
1398 _off_t
1399 gpg_iobuf_tell( gpg_iobuf_t a )
1400 {
1401 return a->ntotal + a->nbytes;
1402 }
1403
1404
1405 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
1406
1407 #ifdef HAVE_LIMITS_H
1408 # include <limits.h>
1409 #endif
1410 #ifndef LONG_MAX
1411 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
1412 #endif
1413 #ifndef LONG_MIN
1414 # define LONG_MIN (-1 - LONG_MAX)
1415 #endif
1416
1417 /****************
1418 * A substitute for fseeko, for hosts that don't have it.
1419 */
1420 static int
1421 fseeko( FILE *stream, _off_t newpos, int whence )
1422 {
1423 while( newpos != (long) newpos ) {
1424 long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
1425 if( fseek( stream, pos, whence ) != 0 )
1426 return -1;
1427 newpos -= pos;
1428 whence = SEEK_CUR;
1429 }
1430 return fseek( stream, (long)newpos, whence );
1431 }
1432 #endif
1433
1434 /****************
1435 * This is a very limited implementation. It simply discards all internal
1436 * buffering and removes all filters but the first one.
1437 */
1438 int
1439 gpg_iobuf_seek( gpg_iobuf_t a, _off_t newpos )
1440 {
1441 file_filter_ctx_t *b = NULL;
1442
1443 if( a->directfp ) {
1444 FILE *fp = a->directfp;
1445 if( fseeko( fp, newpos, SEEK_SET ) ) {
1446 printf("can't seek: %s\n", strerror(errno) );
1447 return -1;
1448 }
1449 clearerr(fp);
1450 }
1451 else {
1452 for( ; a; a = a->chain ) {
1453 if( !a->chain && a->filter == file_filter ) {
1454 b = a->filter_ov;
1455 break;
1456 }
1457 }
1458 if( !a )
1459 return -1;
1460 if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff ) {
1461 printf ("SetFilePointer failed on handle %p: ec=%d\n",
1462 b->fp, (int)GetLastError () );
1463 return -1;
1464 }
1465 }
1466 a->d.len = 0; /* discard buffer */
1467 a->d.start = 0;
1468 a->nbytes = 0;
1469 a->nlimit = 0;
1470 a->nofast &= ~1;
1471 a->ntotal = newpos;
1472 a->error = 0;
1473 /* remove filters, but the last */
1474 if( a->chain )
1475 printf("pop_filter called in iobuf_seek - please report\n");
1476 while( a->chain )
1477 pop_filter( a, a->filter, NULL );
1478
1479 return 0;
1480 }
1481
1482
1483
1484
1485
1486
1487 /****************
1488 * Retrieve the real filename
1489 */
1490 const char *
1491 gpg_iobuf_get_real_fname( gpg_iobuf_t a )
1492 {
1493 if( a->real_fname )
1494 return a->real_fname;
1495
1496 /* the old solution */
1497 for( ; a; a = a->chain )
1498 if( !a->chain && a->filter == file_filter ) {
1499 file_filter_ctx_t *b = a->filter_ov;
1500 return b->print_only_name? NULL : b->fname;
1501 }
1502
1503 return NULL;
1504 }
1505
1506
1507 /****************
1508 * Retrieve the filename
1509 */
1510 const char *
1511 gpg_iobuf_get_fname( gpg_iobuf_t a )
1512 {
1513 for( ; a; a = a->chain )
1514 if( !a->chain && a->filter == file_filter ) {
1515 file_filter_ctx_t *b = a->filter_ov;
1516 return b->fname;
1517 }
1518
1519 return NULL;
1520 }
1521
1522 /****************
1523 * Start the block write mode, see rfc1991.new for details.
1524 * A value of 0 for N stops this mode (flushes and writes
1525 * the end marker)
1526 */
1527 void
1528 gpg_iobuf_set_block_mode( gpg_iobuf_t a, size_t n )
1529 {
1530 block_filter_ctx_t *ctx = calloc( 1, sizeof *ctx );
1531
1532 assert( a->use == 1 || a->use == 2 );
1533 ctx->use = a->use;
1534 if( !n ) {
1535 if( a->use == 1 )
1536 printf("pop_filter called in set_block_mode - please report\n");
1537 pop_filter(a, block_filter, NULL );
1538 }
1539 else {
1540 ctx->size = n; /* only needed for use 2 */
1541 gpg_iobuf_push_filter(a, block_filter, ctx );
1542 }
1543 }
1544
1545 /****************
1546 * enable partial block mode as described in the OpenPGP draft.
1547 * LEN is the first length byte on read, but ignored on writes.
1548 */
1549 void
1550 gpg_iobuf_set_partial_block_mode( gpg_iobuf_t a, size_t len )
1551 {
1552 block_filter_ctx_t *ctx = calloc( 1, sizeof *ctx );
1553
1554 assert( a->use == 1 || a->use == 2 );
1555 ctx->use = a->use;
1556 if( !len ) {
1557 if( a->use == 1 )
1558 printf("pop_filter called in set_partial_block_mode"
1559 " - please report\n");
1560 pop_filter(a, block_filter, NULL );
1561 }
1562 else {
1563 ctx->partial = 1;
1564 ctx->size = 0;
1565 ctx->first_c = len;
1566 gpg_iobuf_push_filter(a, block_filter, ctx );
1567 }
1568 }
1569
1570
1571 /****************
1572 * Checks whether the stream is in block mode
1573 * Note: This does not work if other filters are pushed on the stream.
1574 */
1575 int
1576 gpg_iobuf_in_block_mode( gpg_iobuf_t a )
1577 {
1578 if( a && a->filter == block_filter )
1579 return 1; /* yes */
1580 return 0; /* no */
1581 }
1582
1583
1584 /****************
1585 * Same as fgets() but if the buffer is too short a larger one will
1586 * be allocated up to some limit *max_length.
1587 * A line is considered a byte stream ending in a LF.
1588 * Returns the length of the line. EOF is indicated by a line of
1589 * length zero. The last LF may be missing due to an EOF.
1590 * is max_length is zero on return, the line has been truncated.
1591 *
1592 * Note: The buffer is allocated with enough space to append a CR,LF,EOL
1593 */
1594 unsigned
1595 gpg_iobuf_read_line( gpg_iobuf_t a, byte **addr_of_buffer,
1596 unsigned *length_of_buffer, unsigned *max_length )
1597 {
1598 int c;
1599 char *buffer = *addr_of_buffer;
1600 unsigned length = *length_of_buffer;
1601 unsigned nbytes = 0;
1602 unsigned maxlen = *max_length;
1603 char *p;
1604
1605 if( !buffer ) { /* must allocate a new buffer */
1606 length = 256;
1607 buffer = (char *)malloc( length );
1608 *addr_of_buffer = buffer;
1609 *length_of_buffer = length;
1610 }
1611
1612 length -= 3; /* reserve 3 bytes (cr,lf,eol) */
1613 p = buffer;
1614 while( (c=gpg_iobuf_get(a)) != -1 ) {
1615 if( nbytes == length ) { /* increase the buffer */
1616 if( length > maxlen ) { /* this is out limit */
1617 /* skip the rest of the line */
1618 while( c != '\n' && (c=gpg_iobuf_get(a)) != -1 )
1619 ;
1620 *p++ = '\n'; /* always append a LF (we have reserved space) */
1621 nbytes++;
1622 *max_length = 0; /* indicate truncation */
1623 break;
1624 }
1625 length += 3; /* correct for the reserved byte */
1626 length += length < 1024? 256 : 1024;
1627 buffer = realloc( buffer, length );
1628 *addr_of_buffer = buffer;
1629 *length_of_buffer = length;
1630 length -= 3; /* and reserve again */
1631 p = buffer + nbytes;
1632 }
1633 *p++ = c;
1634 nbytes++;
1635 if( c == '\n' )
1636 break;
1637 }
1638 *p = 0; /* make sure the line is a string */
1639
1640 return nbytes;
1641 }
1642
1643 /* This is the non iobuf specific function */
1644 int
1645 gpg_iobuf_translate_file_handle ( int fd, int for_write )
1646 {
1647 {
1648 int x;
1649
1650 if ( fd <= 2 )
1651 return fd; /* do not do this for error, stdin, stdout, stderr */
1652
1653 x = _open_osfhandle ( fd, for_write? 1:0 );
1654 if (x==-1 )
1655 printf ("failed to translate osfhandle %p\n", (void*)fd );
1656 else {
1657 /*log_info ("_open_osfhandle %p yields %d%s\n",
1658 (void*)fd, x, for_write? " for writing":"" );*/
1659 fd = x;
1660 }
1661 }
1662 return fd;
1663 }
1664
1665 static int
1666 translate_file_handle ( int fd, int for_write )
1667 {
1668 {
1669 int x;
1670
1671 if ( fd == 0 )
1672 x = (int)GetStdHandle (STD_INPUT_HANDLE);
1673 else if (fd == 1)
1674 x = (int)GetStdHandle (STD_OUTPUT_HANDLE);
1675 else if (fd == 2)
1676 x = (int)GetStdHandle (STD_ERROR_HANDLE);
1677 else
1678 x = fd;
1679
1680 if (x == -1)
1681 printf ("GetStdHandle(%d) failed: ec=%d\n",
1682 fd, (int)GetLastError () );
1683
1684 fd = x;
1685 }
1686 return fd;
1687 }
1688
1689

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26