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