"Fossies" - the Fresh Open Source Software Archive 
Member "udns-0.4/udns_init.c" (5 Jul 2011, 6842 Bytes) of package /linux/misc/dns/udns-0.4.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "udns_init.c" see the
Fossies "Dox" file reference documentation.
1 /* udns_init.c
2 resolver initialisation stuff
3
4 Copyright (C) 2006 Michael Tokarev <mjt@corpit.ru>
5 This file is part of UDNS library, an async DNS stub resolver.
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library, in file named COPYING.LGPL; if not,
19 write to the Free Software Foundation, Inc., 59 Temple Place,
20 Suite 330, Boston, MA 02111-1307 USA
21
22 */
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27 #ifdef WINDOWS
28 # include <winsock2.h> /* includes <windows.h> */
29 # include <iphlpapi.h> /* for dns server addresses etc */
30 #else
31 # include <sys/types.h>
32 # include <unistd.h>
33 # include <fcntl.h>
34 #endif /* !WINDOWS */
35
36 #include <stdlib.h>
37 #include <string.h>
38 #include "udns.h"
39
40 #define ISSPACE(x) (x == ' ' || x == '\t' || x == '\r' || x == '\n')
41
42 static const char space[] = " \t\r\n";
43
44 static void dns_set_serv_internal(struct dns_ctx *ctx, char *serv) {
45 dns_add_serv(ctx, NULL);
46 for(serv = strtok(serv, space); serv; serv = strtok(NULL, space))
47 dns_add_serv(ctx, serv);
48 }
49
50 static void dns_set_srch_internal(struct dns_ctx *ctx, char *srch) {
51 dns_add_srch(ctx, NULL);
52 for(srch = strtok(srch, space); srch; srch = strtok(NULL, space))
53 dns_add_srch(ctx, srch);
54 }
55
56 #ifdef WINDOWS
57
58 #ifndef NO_IPHLPAPI
59 /* Apparently, some systems does not have proper headers for IPHLPAIP to work.
60 * The best is to upgrade headers, but here's another, ugly workaround for
61 * this: compile with -DNO_IPHLPAPI.
62 */
63
64 typedef DWORD (WINAPI *GetAdaptersAddressesFunc)(
65 ULONG Family, DWORD Flags, PVOID Reserved,
66 PIP_ADAPTER_ADDRESSES pAdapterAddresses,
67 PULONG pOutBufLen);
68
69 static int dns_initns_iphlpapi(struct dns_ctx *ctx) {
70 HANDLE h_iphlpapi;
71 GetAdaptersAddressesFunc pfnGetAdAddrs;
72 PIP_ADAPTER_ADDRESSES pAddr, pAddrBuf;
73 PIP_ADAPTER_DNS_SERVER_ADDRESS pDnsAddr;
74 ULONG ulOutBufLen;
75 DWORD dwRetVal;
76 int ret = -1;
77
78 h_iphlpapi = LoadLibrary("iphlpapi.dll");
79 if (!h_iphlpapi)
80 return -1;
81 pfnGetAdAddrs = (GetAdaptersAddressesFunc)
82 GetProcAddress(h_iphlpapi, "GetAdaptersAddresses");
83 if (!pfnGetAdAddrs) goto freelib;
84 ulOutBufLen = 0;
85 dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, NULL, &ulOutBufLen);
86 if (dwRetVal != ERROR_BUFFER_OVERFLOW) goto freelib;
87 pAddrBuf = malloc(ulOutBufLen);
88 if (!pAddrBuf) goto freelib;
89 dwRetVal = pfnGetAdAddrs(AF_UNSPEC, 0, NULL, pAddrBuf, &ulOutBufLen);
90 if (dwRetVal != ERROR_SUCCESS) goto freemem;
91 for (pAddr = pAddrBuf; pAddr; pAddr = pAddr->Next)
92 for (pDnsAddr = pAddr->FirstDnsServerAddress;
93 pDnsAddr;
94 pDnsAddr = pDnsAddr->Next)
95 dns_add_serv_s(ctx, pDnsAddr->Address.lpSockaddr);
96 ret = 0;
97 freemem:
98 free(pAddrBuf);
99 freelib:
100 FreeLibrary(h_iphlpapi);
101 return ret;
102 }
103
104 #else /* NO_IPHLPAPI */
105
106 #define dns_initns_iphlpapi(ctx) (-1)
107
108 #endif /* NO_IPHLPAPI */
109
110 static int dns_initns_registry(struct dns_ctx *ctx) {
111 LONG res;
112 HKEY hk;
113 DWORD type = REG_EXPAND_SZ | REG_SZ;
114 DWORD len;
115 char valBuf[1024];
116
117 #define REGKEY_WINNT "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"
118 #define REGKEY_WIN9x "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP"
119 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINNT, 0, KEY_QUERY_VALUE, &hk);
120 if (res != ERROR_SUCCESS)
121 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WIN9x,
122 0, KEY_QUERY_VALUE, &hk);
123 if (res != ERROR_SUCCESS)
124 return -1;
125 len = sizeof(valBuf) - 1;
126 res = RegQueryValueEx(hk, "NameServer", NULL, &type, (BYTE*)valBuf, &len);
127 if (res != ERROR_SUCCESS || !len || !valBuf[0]) {
128 len = sizeof(valBuf) - 1;
129 res = RegQueryValueEx(hk, "DhcpNameServer", NULL, &type,
130 (BYTE*)valBuf, &len);
131 }
132 RegCloseKey(hk);
133 if (res != ERROR_SUCCESS || !len || !valBuf[0])
134 return -1;
135 valBuf[len] = '\0';
136 /* nameservers are stored as a whitespace-seperate list:
137 * "192.168.1.1 123.21.32.12" */
138 dns_set_serv_internal(ctx, valBuf);
139 return 0;
140 }
141
142 #else /* !WINDOWS */
143
144 static int dns_init_resolvconf(struct dns_ctx *ctx) {
145 char *v;
146 char buf[2049]; /* this buffer is used to hold /etc/resolv.conf */
147 int has_srch = 0;
148
149 /* read resolv.conf... */
150 { int fd = open("/etc/resolv.conf", O_RDONLY);
151 if (fd >= 0) {
152 int l = read(fd, buf, sizeof(buf) - 1);
153 close(fd);
154 buf[l < 0 ? 0 : l] = '\0';
155 }
156 else
157 buf[0] = '\0';
158 }
159 if (buf[0]) { /* ...and parse it */
160 char *line, *nextline;
161 line = buf;
162 do {
163 nextline = strchr(line, '\n');
164 if (nextline) *nextline++ = '\0';
165 v = line;
166 while(*v && !ISSPACE(*v)) ++v;
167 if (!*v) continue;
168 *v++ = '\0';
169 while(ISSPACE(*v)) ++v;
170 if (!*v) continue;
171 if (strcmp(line, "domain") == 0) {
172 dns_set_srch_internal(ctx, strtok(v, space));
173 has_srch = 1;
174 }
175 else if (strcmp(line, "search") == 0) {
176 dns_set_srch_internal(ctx, v);
177 has_srch = 1;
178 }
179 else if (strcmp(line, "nameserver") == 0)
180 dns_add_serv(ctx, strtok(v, space));
181 else if (strcmp(line, "options") == 0)
182 dns_set_opts(ctx, v);
183 } while((line = nextline) != NULL);
184 }
185
186 buf[sizeof(buf)-1] = '\0';
187
188 /* get list of nameservers from env. vars. */
189 if ((v = getenv("NSCACHEIP")) != NULL ||
190 (v = getenv("NAMESERVERS")) != NULL) {
191 strncpy(buf, v, sizeof(buf) - 1);
192 dns_set_serv_internal(ctx, buf);
193 }
194 /* if $LOCALDOMAIN is set, use it for search list */
195 if ((v = getenv("LOCALDOMAIN")) != NULL) {
196 strncpy(buf, v, sizeof(buf) - 1);
197 dns_set_srch_internal(ctx, buf);
198 has_srch = 1;
199 }
200 if ((v = getenv("RES_OPTIONS")) != NULL)
201 dns_set_opts(ctx, v);
202
203 /* if still no search list, use local domain name */
204 if (has_srch &&
205 gethostname(buf, sizeof(buf) - 1) == 0 &&
206 (v = strchr(buf, '.')) != NULL &&
207 *++v != '\0')
208 dns_add_srch(ctx, v);
209
210 return 0;
211 }
212
213 #endif /* !WINDOWS */
214
215 int dns_init(struct dns_ctx *ctx, int do_open) {
216 if (!ctx)
217 ctx = &dns_defctx;
218 dns_reset(ctx);
219
220 #ifdef WINDOWS
221 if (dns_initns_iphlpapi(ctx) != 0)
222 dns_initns_registry(ctx);
223 /*XXX WINDOWS: probably good to get default domain and search list too...
224 * And options. Something is in registry. */
225 /*XXX WINDOWS: maybe environment variables are also useful? */
226 #else
227 dns_init_resolvconf(ctx);
228 #endif
229
230 return do_open ? dns_open(ctx) : 0;
231 }