9fba1fc0b1b6fa3bffada7d4b54ac0cd509f1994
[gnupg.git] / util / iobuf.c
1 /* iobuf.c  -  file handling
2  *      Copyright (C) 1998, 1999 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 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30
31 #include "memory.h"
32 #include "util.h"
33 #include "iobuf.h"
34
35 typedef struct {
36     FILE *fp;      /* open file handle */
37     int  print_only_name; /* flags indicating that fname is not a real file*/
38     char fname[1]; /* name of the file */
39 } file_filter_ctx_t ;
40
41
42 /* The first partial length header block must be of size 512
43  * to make it easier (and efficienter) we use a min. block size of 512
44  * for all chznks (but the last one) */
45 #define OP_MIN_PARTIAL_CHUNK      512
46 #define OP_MIN_PARTIAL_CHUNK_2POW 9
47
48 typedef struct {
49     int usage;
50     size_t size;
51     size_t count;
52     int partial;  /* 1 = partial header, 2 in last partial packet */
53     char *buffer;    /* used for partial header */
54     size_t buflen;   /* used size of buffer */
55     int first_c;     /* of partial header (which is > 0)*/
56     int eof;
57 } block_filter_ctx_t;
58
59
60 static int underflow(IOBUF a);
61 static const char *get_real_fname( IOBUF a );
62
63 /****************
64  * Read data from a file into buf which has an allocated length of *LEN.
65  * return the number of read bytes in *LEN. OPAQUE is the FILE * of
66  * the stream. A is not used.
67  * control may be:
68  * IOBUFCTRL_INIT: called just before the function is linked into the
69  *                 list of function. This can be used to prepare internal
70  *                 data structures of the function.
71  * IOBUFCTRL_FREE: called just before the function is removed from the
72  *                  list of functions and can be used to release internal
73  *                  data structures or close a file etc.
74  * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer
75  *                  with new stuff. *RET_LEN is the available size of the
76  *                  buffer, and should be set to the number of bytes
77  *                  which were put into the buffer. The function
78  *                  returns 0 to indicate success, -1 on EOF and
79  *                  G10ERR_xxxxx for other errors.
80  *
81  * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
82  *                  *RET_LAN is the number of bytes in BUF.
83  *
84  */
85 static int
86 file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
87 {
88     file_filter_ctx_t *a = opaque;
89     FILE *fp = a->fp;
90     size_t size = *ret_len;
91     size_t nbytes = 0;
92     int c, rc = 0;
93     char *p;
94
95     if( control == IOBUFCTRL_UNDERFLOW ) {
96         assert( size ); /* need a buffer */
97         for(; size; size-- ) {
98             if( (c=getc(fp)) == EOF ) {
99                 if( ferror(fp) && errno != EPIPE  ) {
100                     log_error("%s: read error: %s\n",
101                                         a->fname, strerror(errno));
102                     rc = G10ERR_READ_FILE;
103                 }
104                 else if( !nbytes )
105                     rc = -1; /* okay: we can return EOF now. */
106                 break;
107             }
108             buf[nbytes++] = c & 0xff;
109         }
110         *ret_len = nbytes;
111     }
112     else if( control == IOBUFCTRL_FLUSH ) {
113         for(p=buf; nbytes < size; nbytes++, p++ ) {
114             if( putc(*p, fp) == EOF ) {
115                 log_error("%s: write error: %s\n",
116                                     a->fname, strerror(errno));
117                 rc = G10ERR_WRITE_FILE;
118                 break;
119             }
120         }
121         *ret_len = nbytes;
122     }
123     else if( control == IOBUFCTRL_INIT ) {
124     }
125     else if( control == IOBUFCTRL_DESC ) {
126         *(char**)buf = "file_filter";
127     }
128     else if( control == IOBUFCTRL_FREE ) {
129         if( fp != stdin && fp != stdout )
130             fclose(fp);
131         fp = NULL;
132         m_free(a); /* we can free our context now */
133     }
134
135     return rc;
136 }
137
138
139 /****************
140  * This is used to implement the block write mode.
141  * Block reading is done on a byte by byte basis in readbyte(),
142  * without a filter
143  */
144 static int
145 block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
146 {
147     block_filter_ctx_t *a = opaque;
148     size_t size = *ret_len;
149     int c, rc = 0;
150     char *p;
151
152     if( control == IOBUFCTRL_UNDERFLOW ) {
153         size_t n=0;
154
155         p = buf;
156         assert( size ); /* need a buffer */
157         if( a->eof ) /* don't read any further */
158             rc = -1;
159         while( !rc && size ) {
160             if( !a->size ) { /* get the length bytes */
161                 if( a->partial == 2 ) {
162                     a->eof = 1;
163                     if( !n )
164                         rc = -1;
165                     break;
166                 }
167                 else if( a->partial ) {
168                     /* These OpenPGP introduced huffman encoded length
169                      * bytes are really a mess :-( */
170                     if( a->first_c ) {
171                         c = a->first_c;
172                         a->first_c = 0;
173                         assert( c >= 224 && c < 255 );
174                     }
175                     else if( (c = iobuf_get(chain)) == -1 ) {
176                         log_error("block_filter: 1st length byte missing\n");
177                         rc = G10ERR_READ_FILE;
178                         break;
179                     }
180                     if( c < 192 ) {
181                         a->size = c;
182                         a->partial = 2;
183                         if( !a->size ) {
184                             a->eof = 1;
185                             if( !n )
186                                 rc = -1;
187                             break;
188                         }
189                     }
190                     else if( c < 224 ) {
191                         a->size = (c - 192) * 256;
192                         if( (c = iobuf_get(chain)) == -1 ) {
193                             log_error("block_filter: 2nd length byte missing\n");
194                             rc = G10ERR_READ_FILE;
195                             break;
196                         }
197                         a->size += c + 192;
198                         a->partial = 2;
199                         if( !a->size ) {
200                             a->eof = 1;
201                             if( !n )
202                                 rc = -1;
203                             break;
204                         }
205                     }
206                     else if( c == 255 ) {
207                         a->size  = iobuf_get(chain) << 24;
208                         a->size |= iobuf_get(chain) << 16;
209                         a->size |= iobuf_get(chain) << 8;
210                         if( (c = iobuf_get(chain)) == -1 ) {
211                             log_error("block_filter: invalid 4 byte length\n");
212                             rc = G10ERR_READ_FILE;
213                             break;
214                         }
215                         a->size |= c;
216                     }
217                     else { /* next partial body length */
218                         a->size = 1 << (c & 0x1f);
219                     }
220                 }
221                 else { /* the gnupg partial length scheme - much better :-) */
222                     c = iobuf_get(chain);
223                     a->size = c << 8;
224                     c = iobuf_get(chain);
225                     a->size |= c;
226                     if( c == -1 ) {
227                         log_error("block_filter: error reading length info\n");
228                         rc = G10ERR_READ_FILE;
229                     }
230                     if( !a->size ) {
231                         a->eof = 1;
232                         if( !n )
233                             rc = -1;
234                         break;
235                     }
236                 }
237             }
238
239             for(; !rc && size && a->size; size--, a->size-- ) {
240                 if( (c=iobuf_get(chain)) == -1 ) {
241                     log_error("block_filter %p: read error (size=%lu,a->size=%lu)\n",
242                                 a,  (ulong)size, (ulong)a->size);
243                     rc = G10ERR_READ_FILE;
244                 }
245                 else {
246                     *p++ = c;
247                     n++;
248                 }
249             }
250         }
251         *ret_len = n;
252     }
253     else if( control == IOBUFCTRL_FLUSH ) {
254         if( a->partial ) { /* the complicated openpgp scheme */
255             size_t blen, n, nbytes = size + a->buflen;
256
257             assert( a->buflen <= OP_MIN_PARTIAL_CHUNK );
258             if( nbytes < OP_MIN_PARTIAL_CHUNK ) {
259                 /* not enough to write a partial block out , so we store it*/
260                 if( !a->buffer )
261                     a->buffer = m_alloc( OP_MIN_PARTIAL_CHUNK );
262                 memcpy( a->buffer + a->buflen, buf, size );
263                 a->buflen += size;
264             }
265             else { /* okay, we can write out something */
266                 /* do this in a loop to use the most efficient block lengths */
267                 p = buf;
268                 do {
269                     /* find the best matching block length - this is limited
270                      * by the size of the internal buffering */
271                     for( blen=OP_MIN_PARTIAL_CHUNK*2,
272                             c=OP_MIN_PARTIAL_CHUNK_2POW+1; blen < nbytes;
273                                                             blen *=2, c++ )
274                         ;
275                     blen /= 2; c--;
276                     /* write the partial length header */
277                     assert( c <= 0x1f ); /*;-)*/
278                     c |= 0xe0;
279                     iobuf_put( chain, c );
280                     if( (n=a->buflen) ) { /* write stuff from the buffer */
281                         assert( n == OP_MIN_PARTIAL_CHUNK);
282                         if( iobuf_write(chain, a->buffer, n ) )
283                             rc = G10ERR_WRITE_FILE;
284                         a->buflen = 0;
285                         nbytes -= n;
286                     }
287                     if( (n = nbytes) > blen )
288                         n = blen;
289                     if( n && iobuf_write(chain, p, n ) )
290                         rc = G10ERR_WRITE_FILE;
291                     p += n;
292                     nbytes -= n;
293                 } while( !rc && nbytes >= OP_MIN_PARTIAL_CHUNK );
294                 /* store the rest in the buffer */
295                 if( !rc && nbytes ) {
296                     assert( !a->buflen );
297                     assert( nbytes < OP_MIN_PARTIAL_CHUNK );
298                     if( !a->buffer )
299                         a->buffer = m_alloc( OP_MIN_PARTIAL_CHUNK );
300                     memcpy( a->buffer, p, nbytes );
301                     a->buflen = nbytes;
302                 }
303             }
304         }
305         else { /* the gnupg scheme */
306             size_t avail, n;
307
308             for(p=buf; !rc && size; ) {
309                 n = size;
310                 avail = a->size - a->count;
311                 if( !avail ) {
312                     if( n > a->size ) {
313                         iobuf_put( chain, (a->size >> 8) & 0xff );
314                         iobuf_put( chain, a->size & 0xff );
315                         avail = a->size;
316                         a->count = 0;
317                     }
318                     else {
319                         iobuf_put( chain, (n >> 8) & 0xff );
320                         iobuf_put( chain, n & 0xff );
321                         avail = n;
322                         a->count = a->size - n;
323                     }
324                 }
325                 if( n > avail )
326                     n = avail;
327                 if( iobuf_write(chain, p, n ) )
328                     rc = G10ERR_WRITE_FILE;
329                 a->count += n;
330                 p += n;
331                 size -= n;
332             }
333         }
334     }
335     else if( control == IOBUFCTRL_INIT ) {
336         if( DBG_IOBUF )
337             log_debug("init block_filter %p\n", a );
338         if( a->partial )
339             a->count = 0;
340         else if( a->usage == 1 )
341             a->count = a->size = 0;
342         else
343             a->count = a->size; /* force first length bytes */
344         a->eof = 0;
345         a->buffer = NULL;
346         a->buflen = 0;
347     }
348     else if( control == IOBUFCTRL_DESC ) {
349         *(char**)buf = "block_filter";
350     }
351     else if( control == IOBUFCTRL_FREE ) {
352         if( a->usage == 2 ) { /* write the end markers */
353             if( a->partial ) {
354                 u32 len;
355                 /* write out the remaining bytes without a partial header
356                  * the length of this header may be 0 - but if it is
357                  * the first block we are not allowed to use a partial header
358                  * and frankly we can't do so, because this length must be
359                  * a power of 2. This is _really_ complicated because we
360                  * have to check the possible length of a packet prior
361                  * to it's creation: a chein of filters becomes complicated
362                  * and we need a lot of code to handle compressed packets etc.
363                  *   :-(((((((
364                  */
365                 /* construct header */
366                 len = a->buflen;
367                 if( len < 192 )
368                     rc = iobuf_put(chain, len );
369                 else if( len < 8384 ) {
370                     if( !(rc=iobuf_put( chain, ((len-192) / 256) + 192)) )
371                         rc = iobuf_put( chain, ((len-192) % 256));
372                 }
373                 else { /* use a 4 byte header */
374                     if( !(rc=iobuf_put( chain, 0xff )) )
375                         if( !(rc=iobuf_put( chain, (len >> 24)&0xff )) )
376                             if( !(rc=iobuf_put( chain, (len >> 16)&0xff )) )
377                                 if( !(rc=iobuf_put( chain, (len >> 8)&0xff )))
378                                     rc=iobuf_put( chain, len & 0xff );
379                 }
380                 if( !rc && len )
381                     rc = iobuf_write(chain, a->buffer, len );
382                 if( rc ) {
383                     log_error("block_filter: write error: %s\n",strerror(errno));
384                     rc = G10ERR_WRITE_FILE;
385                 }
386                 m_free( a->buffer ); a->buffer = NULL; a->buflen = 0;
387             }
388             else {
389                 iobuf_writebyte(chain, 0);
390                 iobuf_writebyte(chain, 0);
391             }
392         }
393         else if( a->size ) {
394             log_error("block_filter: pending bytes!\n");
395         }
396         if( DBG_IOBUF )
397             log_debug("free block_filter %p\n", a );
398         m_free(a); /* we can free our context now */
399     }
400
401     return rc;
402 }
403
404
405 static void
406 print_chain( IOBUF a )
407 {
408     if( !DBG_IOBUF )
409         return;
410     for(; a; a = a->chain ) {
411         size_t dummy_len = 0;
412         const char *desc = "[none]";
413
414         if( a->filter )
415             a->filter( a->filter_ov, IOBUFCTRL_DESC, NULL,
416                                                 (byte*)&desc, &dummy_len );
417
418         log_debug("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n",
419                    a->no, a->subno, desc, a->filter_eof,
420                    a->d.start, a->d.len );
421     }
422 }
423
424 /****************
425  * Allocate a new io buffer, with no function assigned.
426  * Usage is the desired usage: 1 for input, 2 for output, 3 for temp buffer
427  * BUFSIZE is a suggested buffer size.
428  */
429 IOBUF
430 iobuf_alloc(int usage, size_t bufsize)
431 {
432     IOBUF a;
433     static int number=0;
434
435     a = m_alloc_clear(sizeof *a);
436     a->usage = usage;
437     a->d.buf = m_alloc( bufsize );
438     a->d.size = bufsize;
439     a->no = ++number;
440     a->subno = 0;
441     a->opaque = NULL;
442     return a;
443 }
444
445
446 int
447 iobuf_close( IOBUF a )
448 {
449     IOBUF a2;
450     size_t dummy_len;
451     int rc=0;
452
453     if( a && a->directfp ) {
454         fclose( a->directfp );
455         if( DBG_IOBUF )
456             log_debug("iobuf_close -> %p\n", a->directfp );
457         return 0;
458     }
459
460     for( ; a && !rc ; a = a2 ) {
461         a2 = a->chain;
462         if( a->usage == 2 && (rc=iobuf_flush(a)) )
463             log_error("iobuf_flush failed on close: %s\n", g10_errstr(rc));
464
465         if( DBG_IOBUF )
466             log_debug("iobuf-%d.%d: close `%s'\n", a->no, a->subno, a->desc );
467         if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE,
468                                          a->chain, NULL, &dummy_len)) )
469             log_error("IOBUFCTRL_FREE failed on close: %s\n", g10_errstr(rc) );
470         m_free(a->d.buf);
471         m_free(a);
472     }
473     return rc;
474 }
475
476 int
477 iobuf_cancel( IOBUF a )
478 {
479     const char *s;
480
481     if( a && a->usage == 2 ) {
482         s = get_real_fname(a);
483         if( s && *s )
484             remove(s);  /* remove the file. Fixme: this will fail for MSDOZE*/
485     }                   /* because the file is still open */
486     return iobuf_close(a);
487 }
488
489
490 /****************
491  * create a temporary iobuf, which can be used to collect stuff
492  * in an iobuf and later be written by iobuf_write_temp() to another
493  * iobuf.
494  */
495 IOBUF
496 iobuf_temp()
497 {
498     IOBUF a;
499
500     a = iobuf_alloc(3, 8192 );
501
502     return a;
503 }
504
505 IOBUF
506 iobuf_temp_with_content( const char *buffer, size_t length )
507 {
508     IOBUF a;
509
510     a = iobuf_alloc(3, length );
511     memcpy( a->d.buf, buffer, length );
512     a->d.len = length;
513
514     return a;
515 }
516
517
518 /****************
519  * Create a head iobuf for reading from a file
520  * returns: NULL if an error occures and sets errno
521  */
522 IOBUF
523 iobuf_open( const char *fname )
524 {
525     IOBUF a;
526     FILE *fp;
527     file_filter_ctx_t *fcx;
528     size_t len;
529     int print_only = 0;
530
531     if( !fname || (*fname=='-' && !fname[1])  ) {
532         fp = stdin; /* fixme: set binary mode for msdoze */
533         fname = "[stdin]";
534         print_only = 1;
535     }
536     else if( !(fp = fopen(fname, "rb")) )
537         return NULL;
538     a = iobuf_alloc(1, 8192 );
539     fcx = m_alloc( sizeof *fcx + strlen(fname) );
540     fcx->fp = fp;
541     fcx->print_only_name = print_only;
542     strcpy(fcx->fname, fname );
543     a->filter = file_filter;
544     a->filter_ov = fcx;
545     file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
546     file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
547     if( DBG_IOBUF )
548         log_debug("iobuf-%d.%d: open `%s'\n", a->no, a->subno, fname );
549
550     return a;
551 }
552
553 /****************
554  * Create a head iobuf for reading from a file
555  * returns: NULL if an error occures and sets errno
556  */
557 IOBUF
558 iobuf_fdopen( int fd, const char *mode )
559 {
560     IOBUF a;
561     FILE *fp;
562     file_filter_ctx_t *fcx;
563     size_t len;
564
565     if( !(fp = fdopen(fd, mode)) )
566         return NULL;
567     a = iobuf_alloc( strchr( mode, 'w')? 2:1, 8192 );
568     fcx = m_alloc( sizeof *fcx + 20 );
569     fcx->fp = fp;
570     fcx->print_only_name = 1;
571     sprintf(fcx->fname, "[fd %d]", fd );
572     a->filter = file_filter;
573     a->filter_ov = fcx;
574     file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
575     file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
576     if( DBG_IOBUF )
577         log_debug("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname );
578
579     return a;
580 }
581
582 /****************
583  * create an iobuf for writing to a file; the file will be created.
584  */
585 IOBUF
586 iobuf_create( const char *fname )
587 {
588     IOBUF a;
589     FILE *fp;
590     file_filter_ctx_t *fcx;
591     size_t len;
592     int print_only = 0;
593
594     if( !fname || (*fname=='-' && !fname[1]) ) {
595         fp = stdout;
596         fname = "[stdout]";
597         print_only = 1;
598     }
599     else if( !(fp = fopen(fname, "wb")) )
600         return NULL;
601     a = iobuf_alloc(2, 8192 );
602     fcx = m_alloc( sizeof *fcx + strlen(fname) );
603     fcx->fp = fp;
604     fcx->print_only_name = print_only;
605     strcpy(fcx->fname, fname );
606     a->filter = file_filter;
607     a->filter_ov = fcx;
608     file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
609     file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
610     if( DBG_IOBUF )
611         log_debug("iobuf-%d.%d: create `%s'\n", a->no, a->subno, a->desc );
612
613     return a;
614 }
615
616 /****************
617  * append to an iobuf; if the file does not exist, create it.
618  * cannot be used for stdout.
619  */
620 IOBUF
621 iobuf_append( const char *fname )
622 {
623     IOBUF a;
624     FILE *fp;
625     file_filter_ctx_t *fcx;
626     size_t len;
627
628     if( !fname )
629         return NULL;
630     else if( !(fp = fopen(fname, "ab")) )
631         return NULL;
632     a = iobuf_alloc(2, 8192 );
633     fcx = m_alloc( sizeof *fcx + strlen(fname) );
634     fcx->fp = fp;
635     strcpy(fcx->fname, fname );
636     a->filter = file_filter;
637     a->filter_ov = fcx;
638     file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
639     file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
640     if( DBG_IOBUF )
641         log_debug("iobuf-%d.%d: append `%s'\n", a->no, a->subno, a->desc );
642
643     return a;
644 }
645
646 IOBUF
647 iobuf_openrw( const char *fname )
648 {
649     IOBUF a;
650     FILE *fp;
651     file_filter_ctx_t *fcx;
652     size_t len;
653
654     if( !fname )
655         return NULL;
656     else if( !(fp = fopen(fname, "r+b")) )
657         return NULL;
658     a = iobuf_alloc(2, 8192 );
659     fcx = m_alloc( sizeof *fcx + strlen(fname) );
660     fcx->fp = fp;
661     strcpy(fcx->fname, fname );
662     a->filter = file_filter;
663     a->filter_ov = fcx;
664     file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
665     file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
666     if( DBG_IOBUF )
667         log_debug("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno, a->desc );
668
669     return a;
670 }
671
672
673
674 /****************
675  * You can overwrite the normal iobuf behaviour by using this function.
676  * If used the iobuf is a simple wrapper around stdio.
677  * NULL if an error occures and sets errno
678  */
679 IOBUF
680 iobuf_fopen( const char *fname, const char *mode )
681 {
682     IOBUF a;
683     FILE *fp;
684     int print_only = 0;
685
686     if( !fname || (*fname=='-' && !fname[1])  ) {
687         fp = stdin; /* fixme: set binary mode for msdoze */
688         fname = "[stdin]";
689         print_only = 1;
690     }
691     else if( !(fp = fopen(fname, mode) ) )
692         return NULL;
693     a = iobuf_alloc(1, 8192 );
694     a->directfp = fp;
695
696     if( DBG_IOBUF )
697         log_debug("iobuf_fopen -> %p\n", a->directfp );
698
699     return a;
700 }
701
702
703
704 /****************
705  * Register an i/o filter.
706  */
707 int
708 iobuf_push_filter( IOBUF a,
709                    int (*f)(void *opaque, int control,
710                    IOBUF chain, byte *buf, size_t *len), void *ov )
711 {
712     IOBUF b;
713     size_t dummy_len=0;
714     int rc=0;
715
716     if( a->directfp )
717         BUG();
718
719     if( a->usage == 2 && (rc=iobuf_flush(a)) )
720         return rc;
721     /* make a copy of the current stream, so that
722      * A is the new stream and B the original one.
723      * The contents of the buffers are transferred to the
724      * new stream.
725      */
726     b = m_alloc(sizeof *b);
727     memcpy(b, a, sizeof *b );
728     /* remove the filter stuff from the new stream */
729     a->filter = NULL;
730     a->filter_ov = NULL;
731     a->filter_eof = 0;
732     if( a->usage == 3 )
733         a->usage = 2;  /* make a write stream from a temp stream */
734
735     if( a->usage == 2 ) { /* allocate a fresh buffer for the original stream */
736         b->d.buf = m_alloc( a->d.size );
737         b->d.len = 0;
738         b->d.start = 0;
739     }
740     else { /* allocate a fresh buffer for the new stream */
741         a->d.buf = m_alloc( a->d.size );
742         a->d.len = 0;
743         a->d.start = 0;
744     }
745     /* disable nlimit for the new stream */
746     a->ntotal = b->ntotal + b->nbytes;
747     a->nlimit = a->nbytes = 0;
748     a->nofast &= ~1;
749     /* make a link from the new stream to the original stream */
750     a->chain = b;
751     a->opaque = b->opaque;
752
753     /* setup the function on the new stream */
754     a->filter = f;
755     a->filter_ov = ov;
756
757     a->subno = b->subno + 1;
758     f( ov, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &dummy_len );
759
760     if( DBG_IOBUF ) {
761         log_debug("iobuf-%d.%d: push `%s'\n", a->no, a->subno, a->desc );
762         print_chain( a );
763     }
764
765     /* now we can initialize the new function if we have one */
766     if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_INIT, a->chain,
767                        NULL, &dummy_len)) )
768         log_error("IOBUFCTRL_INIT failed: %s\n", g10_errstr(rc) );
769     return rc;
770 }
771
772 /****************
773  * Remove an i/o filter.
774  * Only needed for iobuf_seek?
775  */
776 static int
777 pop_filter( IOBUF a, int (*f)(void *opaque, int control,
778                       IOBUF chain, byte *buf, size_t *len), void *ov )
779 {
780     IOBUF b;
781     size_t dummy_len=0;
782     int rc=0;
783
784     if( a->directfp )
785         BUG();
786
787     if( DBG_IOBUF )
788         log_debug("iobuf-%d.%d: pop `%s'\n", a->no, a->subno, a->desc );
789     if( !a->filter ) { /* this is simple */
790         b = a->chain;
791         assert(b);
792         m_free(a->d.buf);
793         memcpy(a,b, sizeof *a);
794         m_free(b);
795         return 0;
796     }
797     for(b=a ; b; b = b->chain )
798         if( b->filter == f && (!ov || b->filter_ov == ov) )
799             break;
800     if( !b )
801         log_bug("iobuf_pop_filter(): filter function not found\n");
802
803     /* flush this stream if it is an output stream */
804     if( a->usage == 2 && (rc=iobuf_flush(b)) ) {
805         log_error("iobuf_flush failed in pop_filter: %s\n", g10_errstr(rc));
806         return rc;
807     }
808     /* and tell the filter to free it self */
809     if( b->filter && (rc = b->filter(b->filter_ov, IOBUFCTRL_FREE, b->chain,
810                        NULL, &dummy_len)) ) {
811         log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
812         return rc;
813     }
814
815     /* and see how to remove it */
816     if( a == b && !b->chain )
817         log_bug("can't remove the last filter from the chain\n");
818     else if( a == b ) { /* remove the first iobuf from the chain */
819         /* everything from b is copied to a. This is save because
820          * a flush has been done on the to be removed entry
821          */
822         b = a->chain;
823         m_free(a->d.buf);
824         memcpy(a,b, sizeof *a);
825         m_free(b);
826         if( DBG_IOBUF )
827            log_debug("iobuf-%d.%d: popped filter\n", a->no, a->subno );
828     }
829     else if( !b->chain ) { /* remove the last iobuf from the chain */
830         log_bug("Ohh jeee, trying to remove a head filter\n");
831     }
832     else {  /* remove an intermediate iobuf from the chain */
833         log_bug("Ohh jeee, trying to remove an intermediate filter\n");
834     }
835
836     return rc;
837 }
838
839
840
841 /****************
842  * read underflow: read more bytes into the buffer and return
843  * the first byte or -1 on EOF.
844  */
845 static int
846 underflow(IOBUF a)
847 {
848     size_t len;
849     int rc;
850
851     assert( a->d.start == a->d.len );
852     if( a->usage == 3 )
853         return -1; /* EOF because a temp buffer can't do an underflow */
854
855     if( a->filter_eof ) {
856         if( a->chain && a->filter_eof == 1 ) {
857             IOBUF b = a->chain;
858             if( DBG_IOBUF )
859                 log_debug("iobuf-%d.%d: pop `%s' in underflow\n",
860                                         a->no, a->subno, a->desc );
861             m_free(a->d.buf);
862             memcpy(a, b, sizeof *a);
863             m_free(b);
864             print_chain(a);
865         }
866         else
867             a->filter_eof = 0;
868         if( DBG_IOBUF )
869             log_debug("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
870                                                     a->no, a->subno );
871         return -1; /* return one(!) EOF */
872     }
873     if( a->error ) {
874         if( DBG_IOBUF )
875             log_debug("iobuf-%d.%d: error\n", a->no, a->subno );
876         return -1;
877     }
878
879     if( a->directfp ) {
880         FILE *fp = a->directfp;
881
882         len = fread( a->d.buf, 1, a->d.size, fp);
883         if( len < a->d.size ) {
884             if( ferror(fp) )
885                 a->error = 1;
886         }
887         a->d.len = len;
888         a->d.start = 0;
889         return len? a->d.buf[a->d.start++] : -1;
890     }
891
892
893     if( a->filter ) {
894         len = a->d.size;
895         rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
896                         a->d.buf, &len );
897         if( DBG_IOBUF ) {
898             log_debug("iobuf-%d.%d: underflow: req=%lu got=%lu rc=%d\n",
899                     a->no, a->subno, (ulong)a->d.size, (ulong)len, rc );
900           #if 0
901             if( a->no == 7 ) {
902                 print_string(stderr, a->d.buf, len, 0 );
903                 putc('\n', stderr );
904             }
905           #endif
906
907         }
908         if( a->usage == 1 && rc == -1 ) { /* EOF: we can remove the filter */
909             size_t dummy_len;
910
911             /* and tell the filter to free itself */
912             if( (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain,
913                                NULL, &dummy_len)) )
914                 log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
915             a->filter = NULL;
916             a->desc = NULL;
917             a->filter_ov = NULL;
918             a->filter_eof = 1;
919             if( !len && a->chain ) {
920                 IOBUF b = a->chain;
921                 if( DBG_IOBUF )
922                     log_debug("iobuf-%d.%d: pop `%s' in underflow (!len)\n",
923                                                a->no, a->subno, a->desc );
924                 print_chain(a);
925                 m_free(a->d.buf);
926                 memcpy(a,b, sizeof *a);
927                 m_free(b);
928                 print_chain(a);
929
930
931             }
932         }
933         else if( rc )
934             a->error = 1;
935
936         if( !len ) {
937             if( DBG_IOBUF )
938                 log_debug("iobuf-%d.%d: underflow: eof\n", a->no, a->subno );
939             return -1;
940         }
941         a->d.len = len;
942         a->d.start = 0;
943         return a->d.buf[a->d.start++];
944     }
945     else {
946         if( DBG_IOBUF )
947             log_debug("iobuf-%d.%d: underflow: eof (no filter)\n",
948                                                     a->no, a->subno );
949         return -1;  /* no filter; return EOF */
950     }
951 }
952
953
954 int
955 iobuf_flush(IOBUF a)
956 {
957     size_t len;
958     int rc;
959
960     if( a->directfp )
961         return 0;
962
963     /*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/
964     if( a->usage == 3 ) { /* increase the temp buffer */
965         char *newbuf;
966         size_t newsize = a->d.size + 8192;
967
968         log_debug("increasing temp iobuf from %lu to %lu\n",
969                     (ulong)a->d.size, (ulong)newsize );
970         newbuf = m_alloc( newsize );
971         memcpy( newbuf, a->d.buf, a->d.len );
972         m_free(a->d.buf);
973         a->d.buf = newbuf;
974         a->d.size = newsize;
975         return 0;
976     }
977     else if( a->usage != 2 )
978         log_bug("flush on non-output iobuf\n");
979     else if( !a->filter )
980         log_bug("iobuf_flush: no filter\n");
981     len = a->d.len;
982     rc = a->filter( a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len );
983     if( !rc && len != a->d.len ) {
984         log_info("iobuf_flush did not write all!\n");
985         rc = G10ERR_WRITE_FILE;
986     }
987     else if( rc )
988         a->error = 1;
989     a->d.len = 0;
990
991     return rc;
992 }
993
994
995 /****************
996  * Read a byte from the iobuf; returns -1 on EOF
997  */
998 int
999 iobuf_readbyte(IOBUF a)
1000 {
1001     int c;
1002
1003     /* nlimit does not work together with unget */
1004     /* nbytes is also not valid! */
1005     if( a->unget.buf ) {
1006         if( a->unget.start < a->unget.len )
1007             return a->unget.buf[a->unget.start++];
1008         m_free(a->unget.buf);
1009         a->unget.buf = NULL;
1010         a->nofast &= ~2;
1011     }
1012
1013     if( a->nlimit && a->nbytes >= a->nlimit )
1014         return -1; /* forced EOF */
1015
1016     if( a->d.start < a->d.len ) {
1017         c = a->d.buf[a->d.start++];
1018     }
1019     else if( (c=underflow(a)) == -1 )
1020         return -1; /* EOF */
1021
1022     a->nbytes++;
1023     return c;
1024 }
1025
1026
1027 int
1028 iobuf_read(IOBUF a, byte *buf, unsigned buflen )
1029 {
1030     int c, n;
1031
1032     if( a->unget.buf || a->nlimit ) {
1033         /* handle special cases */
1034         for(n=0 ; n < buflen; n++, buf++ ) {
1035             if( (c = iobuf_readbyte(a)) == -1 ) {
1036                 if( !n )
1037                     return -1; /* eof */
1038                 break;
1039             }
1040             else
1041                 *buf = c;
1042         }
1043         return n;
1044     }
1045
1046     n = 0;
1047     do {
1048         for( ; n < buflen && a->d.start < a->d.len; n++ )
1049             *buf++ = a->d.buf[a->d.start++];
1050         if( n < buflen ) {
1051             if( (c=underflow(a)) == -1 ) {
1052                 a->nbytes += n;
1053                 return n? n : -1/*EOF*/;
1054             }
1055             *buf++ = c; n++;
1056         }
1057     } while( n < buflen );
1058     a->nbytes += n;
1059     return n;
1060 }
1061
1062
1063 /****************
1064  * Have a look at the iobuf.
1065  * NOTE: This only works in special cases.
1066  */
1067 int
1068 iobuf_peek(IOBUF a, byte *buf, unsigned buflen )
1069 {
1070     int n=0;
1071
1072     if( a->filter_eof )
1073         return -1;
1074
1075     if( !(a->d.start < a->d.len) ) {
1076         if( underflow(a) == -1 )
1077             return -1;
1078         /* and unget this character */
1079         assert(a->d.start == 1);
1080         a->d.start = 0;
1081     }
1082
1083     for(n=0 ; n < buflen && (a->d.start+n) < a->d.len ; n++, buf++ )
1084         *buf = a->d.buf[n];
1085     return n;
1086 }
1087
1088
1089
1090
1091 int
1092 iobuf_writebyte(IOBUF a, unsigned c)
1093 {
1094
1095     if( a->directfp )
1096         BUG();
1097
1098     if( a->d.len == a->d.size )
1099         if( iobuf_flush(a) )
1100             return -1;
1101
1102     assert( a->d.len < a->d.size );
1103     a->d.buf[a->d.len++] = c;
1104     return 0;
1105 }
1106
1107
1108 int
1109 iobuf_write(IOBUF a, byte *buf, unsigned buflen )
1110 {
1111
1112     if( a->directfp )
1113         BUG();
1114
1115     do {
1116         for( ; buflen && a->d.len < a->d.size; buflen--, buf++ )
1117             a->d.buf[a->d.len++] = *buf;
1118         if( buflen ) {
1119             if( iobuf_flush(a) )
1120                 return -1;
1121         }
1122     } while( buflen );
1123     return 0;
1124 }
1125
1126
1127 int
1128 iobuf_writestr(IOBUF a, const char *buf )
1129 {
1130     for( ; *buf; buf++ )
1131         if( iobuf_writebyte(a, *buf) )
1132             return -1;
1133     return 0;
1134 }
1135
1136
1137
1138 /****************
1139  * copy the contents of TEMP to A.
1140  */
1141 int
1142 iobuf_write_temp( IOBUF a, IOBUF temp )
1143 {
1144     while( temp->chain )
1145         pop_filter( temp, temp->filter, NULL );
1146     return iobuf_write(a, temp->d.buf, temp->d.len );
1147 }
1148
1149 /****************
1150  * copy the contents of the temp io stream to BUFFER.
1151  */
1152 size_t
1153 iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen )
1154 {
1155     size_t n = a->d.len;
1156
1157     if( n > buflen )
1158         n = buflen;
1159     memcpy( buffer, a->d.buf, n );
1160     return n;
1161 }
1162
1163
1164 /****************
1165  * Call this function to terminate processing of the temp stream
1166  * without closing it.  This removes all filters from the stream
1167  * makes sure that iobuf_get_temp_{buffer,length}() returns correct
1168  * values.
1169  */
1170 void
1171 iobuf_flush_temp( IOBUF temp )
1172 {
1173     while( temp->chain )
1174         pop_filter( temp, temp->filter, NULL );
1175 }
1176
1177
1178 /****************
1179  * Set a limit on how many bytes may be read from the input stream A.
1180  * Setting the limit to 0 disables this feature.
1181  */
1182 void
1183 iobuf_set_limit( IOBUF a, unsigned long nlimit )
1184 {
1185     if( nlimit )
1186         a->nofast |= 1;
1187     else
1188         a->nofast &= ~1;
1189     a->nlimit = nlimit;
1190     a->ntotal += a->nbytes;
1191     a->nbytes = 0;
1192 }
1193
1194
1195
1196 /****************
1197  * Return the length of an open file
1198  */
1199 u32
1200 iobuf_get_filelength( IOBUF a )
1201 {
1202     struct stat st;
1203
1204     if( a->directfp )  {
1205         FILE *fp = a->directfp;
1206
1207         if( !fstat(fileno(fp), &st) )
1208             return st.st_size;
1209         log_error("fstat() failed: %s\n", strerror(errno) );
1210         return 0;
1211     }
1212
1213     for( ; a; a = a->chain )
1214         if( !a->chain && a->filter == file_filter ) {
1215             file_filter_ctx_t *b = a->filter_ov;
1216             FILE *fp = b->fp;
1217
1218             if( !fstat(fileno(fp), &st) )
1219                 return st.st_size;
1220             log_error("fstat() failed: %s\n", strerror(errno) );
1221             break;
1222         }
1223
1224     return 0;
1225 }
1226
1227 /****************
1228  * Tell the file position, where the next read will take place
1229  */
1230 ulong
1231 iobuf_tell( IOBUF a )
1232 {
1233     return a->ntotal + a->nbytes;
1234 }
1235
1236
1237
1238 /****************
1239  * This is a very limited implementation. It simply discards all internal
1240  * buffering and removes all filters but the first one.
1241  */
1242 int
1243 iobuf_seek( IOBUF a, ulong newpos )
1244 {
1245     file_filter_ctx_t *b = NULL;
1246
1247     if( a->directfp ) {
1248         FILE *fp = a->directfp;
1249         if( fseek( fp, newpos, SEEK_SET ) ) {
1250             log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
1251             return -1;
1252         }
1253         clearerr(fp);
1254     }
1255     else {
1256         for( ; a; a = a->chain ) {
1257             if( !a->chain && a->filter == file_filter ) {
1258                 b = a->filter_ov;
1259                 break;
1260             }
1261         }
1262         if( !a )
1263             return -1;
1264         if( fseek( b->fp, newpos, SEEK_SET ) ) {
1265             log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
1266             return -1;
1267         }
1268     }
1269     a->d.len = 0;   /* discard buffer */
1270     a->d.start = 0;
1271     a->nbytes = 0;
1272     a->nlimit = 0;
1273     a->nofast &= ~1;
1274     a->ntotal = newpos;
1275     a->error = 0;
1276     /* remove filters, but the last */
1277     if( a->chain )
1278         log_debug("pop_filter called in iobuf_seek - please report\n");
1279     while( a->chain )
1280        pop_filter( a, a->filter, NULL );
1281
1282     return 0;
1283 }
1284
1285
1286
1287
1288
1289
1290 /****************
1291  * Retrieve the real filename
1292  */
1293 static const char *
1294 get_real_fname( IOBUF a )
1295 {
1296     for( ; a; a = a->chain )
1297         if( !a->chain && a->filter == file_filter ) {
1298             file_filter_ctx_t *b = a->filter_ov;
1299             return b->print_only_name? NULL : b->fname;
1300         }
1301
1302     return NULL;
1303 }
1304
1305
1306 /****************
1307  * Retrieve the filename
1308  */
1309 const char *
1310 iobuf_get_fname( IOBUF a )
1311 {
1312     for( ; a; a = a->chain )
1313         if( !a->chain && a->filter == file_filter ) {
1314             file_filter_ctx_t *b = a->filter_ov;
1315             return b->fname;
1316         }
1317
1318     return NULL;
1319 }
1320
1321 /****************
1322  * Start the block write mode, see rfc1991.new for details.
1323  * A value of 0 for N stops this mode (flushes and writes
1324  * the end marker)
1325  */
1326 void
1327 iobuf_set_block_mode( IOBUF a, size_t n )
1328 {
1329     block_filter_ctx_t *ctx = m_alloc_clear( sizeof *ctx );
1330
1331     assert( a->usage == 1 || a->usage == 2 );
1332     ctx->usage = a->usage;
1333     if( !n ) {
1334         if( a->usage == 1 )
1335             log_debug("pop_filter called in set_block_mode - please report\n");
1336         pop_filter(a, block_filter, NULL );
1337     }
1338     else {
1339         ctx->size = n; /* only needed for usage 2 */
1340         iobuf_push_filter(a, block_filter, ctx );
1341     }
1342 }
1343
1344 /****************
1345  * enable partial block mode as described in the OpenPGP draft.
1346  * LEN is the first length byte on read, but ignored on writes.
1347  */
1348 void
1349 iobuf_set_partial_block_mode( IOBUF a, size_t len )
1350 {
1351     block_filter_ctx_t *ctx = m_alloc_clear( sizeof *ctx );
1352
1353     assert( a->usage == 1 || a->usage == 2 );
1354     ctx->usage = a->usage;
1355     if( !len ) {
1356         if( a->usage == 1 )
1357             log_debug("pop_filter called in set_partial_block_mode"
1358                                                     " - please report\n");
1359         pop_filter(a, block_filter, NULL );
1360     }
1361     else {
1362         ctx->partial = 1;
1363         ctx->size = 0;
1364         ctx->first_c = len;
1365         iobuf_push_filter(a, block_filter, ctx );
1366     }
1367 }
1368
1369
1370 /****************
1371  * Checks whether the stream is in block mode
1372  * Note: This does not work if other filters are pushed on the stream.
1373  */
1374 int
1375 iobuf_in_block_mode( IOBUF a )
1376 {
1377     if( a && a->filter == block_filter )
1378         return 1; /* yes */
1379     return 0; /* no */
1380 }
1381
1382
1383 /****************
1384  * Same as fgets() but if the buffer is too short a larger one will
1385  * be allocated up to some limit *max_length.
1386  * A line is considered a byte stream ending in a LF.
1387  * Returns the length of the line. EOF is indicated by a line of
1388  * length zero. The last LF may be missing due to an EOF.
1389  * is max_length is zero on return, the line has been truncated.
1390  *
1391  * Note: The buffer is allocated with enough space to append a CR,LF,EOL
1392  */
1393 unsigned
1394 iobuf_read_line( IOBUF a, byte **addr_of_buffer,
1395                           unsigned *length_of_buffer, unsigned *max_length )
1396 {
1397     int c;
1398     char *buffer = *addr_of_buffer;
1399     unsigned length = *length_of_buffer;
1400     unsigned nbytes = 0;
1401     unsigned maxlen = *max_length;
1402     char *p;
1403
1404     if( !buffer ) { /* must allocate a new buffer */
1405         length = 256;
1406         buffer = m_alloc( length );
1407         *addr_of_buffer = buffer;
1408         *length_of_buffer = length;
1409     }
1410
1411     length -= 3; /* reserve 3 bytes (cr,lf,eol) */
1412     p = buffer;
1413     while( (c=iobuf_get(a)) != -1 ) {
1414         if( nbytes == length ) { /* increase the buffer */
1415             if( length > maxlen  ) { /* this is out limit */
1416                 /* skip the rest of the line */
1417                 while( c != '\n' && (c=iobuf_get(a)) != -1 )
1418                     ;
1419                 *p++ = '\n'; /* always append a LF (we have reserved space) */
1420                 nbytes++;
1421                 *max_length = 0; /* indicate truncation */
1422                 break;
1423             }
1424             length += 3; /* correct for the reserved byte */
1425             length += length < 1024? 256 : 1024;
1426             buffer = m_realloc( buffer, length );
1427             *addr_of_buffer = buffer;
1428             *length_of_buffer = length;
1429             length -= 3; /* and reserve again */
1430             p = buffer + nbytes;
1431         }
1432         *p++ = c;
1433         nbytes++;
1434         if( c == '\n' )
1435             break;
1436     }
1437     *p = 0; /* make sure the line is a string */
1438
1439     return nbytes;
1440 }
1441