/src/samba/libcli/dns/resolvconf.c
Line | Count | Source |
1 | | /* |
2 | | * Unix SMB/CIFS implementation. |
3 | | * Internal DNS query structures |
4 | | * Copyright (C) Volker Lendecke 2018 |
5 | | * |
6 | | * This program 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 3 of the License, or |
9 | | * (at your option) any later version. |
10 | | * |
11 | | * This program 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, see <http://www.gnu.org/licenses/>. |
18 | | */ |
19 | | |
20 | | #include "replace.h" |
21 | | #include <stdio.h> |
22 | | #include <errno.h> |
23 | | #include "libcli/dns/resolvconf.h" |
24 | | #include "lib/util/memory.h" |
25 | | |
26 | | int parse_resolvconf_fp( |
27 | | FILE *fp, |
28 | | TALLOC_CTX *mem_ctx, |
29 | | char ***pnameservers, |
30 | | size_t *pnum_nameservers) |
31 | 0 | { |
32 | 0 | char *line = NULL; |
33 | 0 | size_t len = 0; |
34 | 0 | char **nameservers = NULL; |
35 | 0 | size_t num_nameservers = 0; |
36 | 0 | int ret = 0; |
37 | |
|
38 | 0 | while (true) { |
39 | 0 | char *saveptr = NULL, *option = NULL, *ns = NULL; |
40 | 0 | char **tmp = NULL; |
41 | 0 | ssize_t n = 0; |
42 | |
|
43 | 0 | n = getline(&line, &len, fp); |
44 | 0 | if (n < 0) { |
45 | 0 | if (!feof(fp)) { |
46 | | /* real error */ |
47 | 0 | ret = errno; |
48 | 0 | } |
49 | 0 | break; |
50 | 0 | } |
51 | 0 | if ((n > 0) && (line[n-1] == '\n')) { |
52 | 0 | line[n-1] = '\0'; |
53 | 0 | } |
54 | |
|
55 | 0 | if ((line[0] == '#') || (line[0] == ';')) { |
56 | 0 | continue; |
57 | 0 | } |
58 | | |
59 | 0 | option = strtok_r(line, " \t", &saveptr); |
60 | 0 | if (option == NULL) { |
61 | 0 | continue; |
62 | 0 | } |
63 | | |
64 | 0 | if (strcmp(option, "nameserver") != 0) { |
65 | 0 | continue; |
66 | 0 | } |
67 | | |
68 | 0 | ns = strtok_r(NULL, " \t", &saveptr); |
69 | 0 | if (ns == NULL) { |
70 | 0 | continue; |
71 | 0 | } |
72 | | |
73 | 0 | tmp = talloc_realloc( |
74 | 0 | mem_ctx, |
75 | 0 | nameservers, |
76 | 0 | char *, |
77 | 0 | num_nameservers+1); |
78 | 0 | if (tmp == NULL) { |
79 | 0 | ret = ENOMEM; |
80 | 0 | break; |
81 | 0 | } |
82 | 0 | nameservers = tmp; |
83 | |
|
84 | 0 | nameservers[num_nameservers] = talloc_strdup(nameservers, ns); |
85 | 0 | if (nameservers[num_nameservers] == NULL) { |
86 | 0 | ret = ENOMEM; |
87 | 0 | break; |
88 | 0 | } |
89 | 0 | num_nameservers += 1; |
90 | 0 | } |
91 | |
|
92 | 0 | SAFE_FREE(line); |
93 | |
|
94 | 0 | if (ret == 0) { |
95 | 0 | *pnameservers = nameservers; |
96 | 0 | *pnum_nameservers = num_nameservers; |
97 | 0 | } else { |
98 | 0 | TALLOC_FREE(nameservers); |
99 | 0 | } |
100 | |
|
101 | 0 | return ret; |
102 | 0 | } |
103 | | |
104 | | int parse_resolvconf( |
105 | | const char *resolvconf, |
106 | | TALLOC_CTX *mem_ctx, |
107 | | char ***pnameservers, |
108 | | size_t *pnum_nameservers) |
109 | 0 | { |
110 | 0 | FILE *fp; |
111 | 0 | int ret; |
112 | |
|
113 | 0 | fp = fopen(resolvconf ? resolvconf : "/etc/resolv.conf", "r"); |
114 | 0 | if (fp == NULL) { |
115 | 0 | return errno; |
116 | 0 | } |
117 | | |
118 | 0 | ret = parse_resolvconf_fp(fp, mem_ctx, pnameservers, pnum_nameservers); |
119 | |
|
120 | 0 | fclose(fp); |
121 | |
|
122 | 0 | return ret; |
123 | 0 | } |