• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 1998 Massachusetts Institute of Technology
4  * Copyright (c) The c-ares project and its contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * SPDX-License-Identifier: MIT
26  */
27 
28 #include "ares_setup.h"
29 
30 #include "ares.h"
31 #include "ares_private.h"
32 
33 /* This is an internal function.  Its contract is to read a line from
34  * a file into a dynamically allocated buffer, zeroing the trailing
35  * newline if there is one.  The calling routine may call
36  * ares__read_line multiple times with the same buf and bufsize
37  * pointers; *buf will be reallocated and *bufsize adjusted as
38  * appropriate.  The initial value of *buf should be NULL.  After the
39  * calling routine is done reading lines, it should free *buf.
40  */
ares__read_line(FILE * fp,char ** buf,size_t * bufsize)41 ares_status_t ares__read_line(FILE *fp, char **buf, size_t *bufsize)
42 {
43   char  *newbuf;
44   size_t offset = 0;
45   size_t len;
46 
47   if (*buf == NULL) {
48     *buf = ares_malloc(128);
49     if (!*buf) {
50       return ARES_ENOMEM;
51     }
52     *bufsize = 128;
53   }
54 
55   for (;;) {
56     int bytestoread = (int)(*bufsize - offset);
57 
58     if (!fgets(*buf + offset, bytestoread, fp)) {
59       return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF;
60     }
61     len = offset + ares_strlen(*buf + offset);
62 
63     /* Probably means there was an embedded NULL as the first character in
64      * the line, throw away line */
65     if (len == 0) {
66       offset = 0;
67       continue;
68     }
69 
70     if ((*buf)[len - 1] == '\n') {
71       (*buf)[len - 1] = 0;
72       break;
73     }
74     offset = len;
75     if (len < *bufsize - 1) {
76       continue;
77     }
78 
79     /* Allocate more space. */
80     newbuf = ares_realloc(*buf, *bufsize * 2);
81     if (!newbuf) {
82       ares_free(*buf);
83       *buf = NULL;
84       return ARES_ENOMEM;
85     }
86     *buf      = newbuf;
87     *bufsize *= 2;
88   }
89   return ARES_SUCCESS;
90 }
91