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