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