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