/* @(#) $Id: ovfl.c,v 1.1 2002/01/27 17:00:05 qed Exp $ */
#include <stdio.h>
#include <string.h>
#include <malloc.h>

/* Grabs stdin, allocating as much memory as necessary to hold the result
   buffer.  It is up to the calling program to free the memory once it is
   done with it */

char * nboGrabLine (void) {
char * strout;
char * tmpstr;
char buff[64];
unsigned int memlen, sofar, len, crlfflag;

    memlen = 64;
    strout = (char *)malloc (memlen);
    if (strout == NULL) return NULL;

    strout[0] = '\0';
    sofar = 1;

    crlfflag = 0;
    while ((crlfflag == 0) && (fgets (buff, 64, stdin) != NULL)) {
        len = strlen (buff);

        /* Search for CRLF if there is one */
        tmpstr = buff + len;
        if (tmpstr != buff) {
            tmpstr--;
            while (((*tmpstr) == '\n') || ((*tmpstr) == '\r')) {
                crlfflag = 1;
                *tmpstr = '\0';
                len = strlen (buff);
                if (tmpstr == buff) break;
                tmpstr--;
            }
        }

        /* Make sure there is enough space to hold the string */
        sofar += len;
        if (sofar > memlen) {
            memlen += memlen;

            /* Cannot exceed MAX_INT in size */
            if (memlen == 0) return strout;

            tmpstr = (char *)realloc (strout, memlen);

            /* If out of memory, return what we have so far */
            if (tmpstr == NULL) return strout;
            strout = tmpstr;
        }

        /* Concatenate the partial buffer */
        strcat (strout, buff);
    }
    return strout;
}

int main () {
char * line;
    line = nboGrabLine();
    printf ("{%s}\n", line);
    free (line);
    return 0;
}
