Home | History | Annotate | Download | only in c-ares
      1 
      2 /* Copyright 1998 by the Massachusetts Institute of Technology.
      3  *
      4  * Permission to use, copy, modify, and distribute this
      5  * software and its documentation for any purpose and without
      6  * fee is hereby granted, provided that the above copyright
      7  * notice appear in all copies and that both that copyright
      8  * notice and this permission notice appear in supporting
      9  * documentation, and that the name of M.I.T. not be used in
     10  * advertising or publicity pertaining to distribution of the
     11  * software without specific, written prior permission.
     12  * M.I.T. makes no representations about the suitability of
     13  * this software for any purpose.  It is provided "as is"
     14  * without express or implied warranty.
     15  */
     16 
     17 #include "ares_setup.h"
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <string.h>
     21 #include "ares.h"
     22 #include "ares_nowarn.h"
     23 #include "ares_private.h"
     24 
     25 /* This is an internal function.  Its contract is to read a line from
     26  * a file into a dynamically allocated buffer, zeroing the trailing
     27  * newline if there is one.  The calling routine may call
     28  * ares__read_line multiple times with the same buf and bufsize
     29  * pointers; *buf will be reallocated and *bufsize adjusted as
     30  * appropriate.  The initial value of *buf should be NULL.  After the
     31  * calling routine is done reading lines, it should free *buf.
     32  */
     33 int ares__read_line(FILE *fp, char **buf, size_t *bufsize)
     34 {
     35   char *newbuf;
     36   size_t offset = 0;
     37   size_t len;
     38 
     39   if (*buf == NULL)
     40     {
     41       *buf = malloc(128);
     42       if (!*buf)
     43         return ARES_ENOMEM;
     44       *bufsize = 128;
     45     }
     46 
     47   for (;;)
     48     {
     49       int bytestoread = aresx_uztosi(*bufsize - offset);
     50 
     51       if (!fgets(*buf + offset, bytestoread, fp))
     52         return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF;
     53       len = offset + strlen(*buf + offset);
     54       if ((*buf)[len - 1] == '\n')
     55         {
     56           (*buf)[len - 1] = 0;
     57           break;
     58         }
     59       offset = len;
     60       if(len < *bufsize - 1)
     61         continue;
     62 
     63       /* Allocate more space. */
     64       newbuf = realloc(*buf, *bufsize * 2);
     65       if (!newbuf)
     66         return ARES_ENOMEM;
     67       *buf = newbuf;
     68       *bufsize *= 2;
     69     }
     70   return ARES_SUCCESS;
     71 }
     72