mirror of
https://frontier.innolan.net/rainlance/c-ares.git
synced 2026-10-02 14:13:09 +00:00
Dominick Meglio's fix for supporting multiple names in the Nameserver key
on Windows.
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
|
* February 22, 2004
|
||||||
|
- Dominick Meglio made ares init support multiple name servers in the
|
||||||
|
NameServer key on Windows.
|
||||||
|
|
||||||
* February 16, 2004
|
* February 16, 2004
|
||||||
- Modified ares_private.h to include libcurl's memory debug header if
|
- Modified ares_private.h to include libcurl's memory debug header if
|
||||||
CURLDEBUG is set. This makes all the ares-functions supervised properly by
|
CURLDEBUG is set. This makes all the ares-functions supervised properly by
|
||||||
|
|||||||
+168
-117
@@ -44,7 +44,7 @@ static int init_by_defaults(ares_channel channel);
|
|||||||
static int config_domain(ares_channel channel, char *str);
|
static int config_domain(ares_channel channel, char *str);
|
||||||
static int config_lookup(ares_channel channel, const char *str);
|
static int config_lookup(ares_channel channel, const char *str);
|
||||||
static int config_nameserver(struct server_state **servers, int *nservers,
|
static int config_nameserver(struct server_state **servers, int *nservers,
|
||||||
const char *str);
|
char *str);
|
||||||
static int config_sortlist(struct apattern **sortlist, int *nsort,
|
static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||||
const char *str);
|
const char *str);
|
||||||
static int set_search(ares_channel channel, const char *str);
|
static int set_search(ares_channel channel, const char *str);
|
||||||
@@ -230,7 +230,7 @@ static int init_by_environment(ares_channel channel)
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static int get_res_size_nt(HKEY hKey, char *subkey, int *size)
|
static int get_res_size_nt(HKEY hKey, char *subkey, int *size)
|
||||||
{
|
{
|
||||||
return RegQueryValueEx(hKey, subkey, 0, NULL, NULL, size);
|
return RegQueryValueEx(hKey, subkey, 0, NULL, NULL, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Warning: returns a dynamically allocated buffer, the user MUST
|
/* Warning: returns a dynamically allocated buffer, the user MUST
|
||||||
@@ -238,55 +238,56 @@ static int get_res_size_nt(HKEY hKey, char *subkey, int *size)
|
|||||||
*/
|
*/
|
||||||
static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
|
static int get_res_nt(HKEY hKey, char *subkey, char **obuf)
|
||||||
{
|
{
|
||||||
/* Test for the size we need */
|
/* Test for the size we need */
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int result;
|
int result;
|
||||||
result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
|
result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
|
||||||
if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
|
if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
|
||||||
return 0;
|
return 0;
|
||||||
*obuf = malloc(size+1);
|
*obuf = malloc(size+1);
|
||||||
|
|
||||||
if (RegQueryValueEx(hKey, subkey, 0, NULL, *obuf, &size) != ERROR_SUCCESS)
|
if (RegQueryValueEx(hKey, subkey, 0, NULL, *obuf, &size) != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
free(*obuf);
|
free(*obuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (size == 1)
|
if (size == 1)
|
||||||
{
|
{
|
||||||
free(*obuf);
|
free(*obuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_res_interfaces_nt(HKEY hKey, char *subkey, char **obuf)
|
static int get_res_interfaces_nt(HKEY hKey, char *subkey, char **obuf)
|
||||||
{
|
{
|
||||||
char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
|
char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
|
||||||
int enum_size = 39;
|
int enum_size = 39;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
HKEY hVal;
|
HKEY hVal;
|
||||||
while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0, NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
|
while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
|
||||||
{
|
NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
|
||||||
enum_size = 39;
|
{
|
||||||
if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) != ERROR_SUCCESS)
|
enum_size = 39;
|
||||||
continue;
|
if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
|
||||||
if (!get_res_nt(hVal, subkey, obuf))
|
ERROR_SUCCESS)
|
||||||
RegCloseKey(hVal);
|
continue;
|
||||||
else
|
if (!get_res_nt(hVal, subkey, obuf))
|
||||||
{
|
RegCloseKey(hVal);
|
||||||
RegCloseKey(hVal);
|
else
|
||||||
return 1;
|
{
|
||||||
}
|
RegCloseKey(hVal);
|
||||||
}
|
return 1;
|
||||||
return 0;
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int init_by_resolv_conf(ares_channel channel)
|
static int init_by_resolv_conf(ares_channel channel)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
char *line = NULL;
|
||||||
char *line = NULL, *p;
|
int status, nservers = 0, nsort = 0;
|
||||||
int linesize, status, nservers = 0, nsort = 0;
|
|
||||||
struct server_state *servers = NULL;
|
struct server_state *servers = NULL;
|
||||||
struct apattern *sortlist = NULL;
|
struct apattern *sortlist = NULL;
|
||||||
|
|
||||||
@@ -315,8 +316,6 @@ DhcpNameServer
|
|||||||
DWORD data_type;
|
DWORD data_type;
|
||||||
DWORD bytes;
|
DWORD bytes;
|
||||||
DWORD result;
|
DWORD result;
|
||||||
DWORD index;
|
|
||||||
char name[MAX_PATH];
|
|
||||||
DWORD keysize = MAX_PATH;
|
DWORD keysize = MAX_PATH;
|
||||||
|
|
||||||
status = ARES_EFILE;
|
status = ARES_EFILE;
|
||||||
@@ -324,70 +323,75 @@ DhcpNameServer
|
|||||||
if (IsNT)
|
if (IsNT)
|
||||||
{
|
{
|
||||||
if (RegOpenKeyEx(
|
if (RegOpenKeyEx(
|
||||||
HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
|
HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
|
||||||
KEY_READ, &mykey
|
KEY_READ, &mykey
|
||||||
) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
RegOpenKeyEx(mykey, "Interfaces", 0, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
|
|
||||||
if (get_res_nt(mykey, NAMESERVER, &line))
|
|
||||||
{
|
|
||||||
status = config_nameserver(&servers, &nservers, line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
|
|
||||||
{
|
|
||||||
status = config_nameserver(&servers, &nservers, line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
/* Try the interfaces */
|
|
||||||
else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
|
|
||||||
{
|
|
||||||
status = config_nameserver(&servers, &nservers, line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
|
|
||||||
{
|
|
||||||
status = config_nameserver(&servers, &nservers, line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
RegCloseKey(subkey);
|
|
||||||
RegCloseKey(mykey);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (RegOpenKeyEx(
|
|
||||||
HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
|
|
||||||
KEY_READ, &mykey
|
|
||||||
) == ERROR_SUCCESS)
|
) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegOpenKeyEx(mykey, "Interfaces", 0,
|
||||||
|
KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
|
||||||
|
if (get_res_nt(mykey, NAMESERVER, &line))
|
||||||
{
|
{
|
||||||
if ((result = RegQueryValueEx(
|
status = config_nameserver(&servers, &nservers, line);
|
||||||
mykey, NAMESERVER, NULL, &data_type,
|
free(line);
|
||||||
NULL, &bytes
|
}
|
||||||
)
|
else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
|
||||||
) == ERROR_SUCCESS ||
|
{
|
||||||
result == ERROR_MORE_DATA)
|
status = config_nameserver(&servers, &nservers, line);
|
||||||
{
|
free(line);
|
||||||
if (bytes) {
|
}
|
||||||
line = (char *)malloc(bytes+1);
|
/* Try the interfaces */
|
||||||
if (RegQueryValueEx(
|
else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
|
||||||
mykey, NAMESERVER, NULL, &data_type,
|
{
|
||||||
(unsigned char *)line, &bytes
|
status = config_nameserver(&servers, &nservers, line);
|
||||||
) == ERROR_SUCCESS) {
|
free(line);
|
||||||
status = config_nameserver(&servers, &nservers, line);
|
}
|
||||||
}
|
else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
|
||||||
free(line);
|
{
|
||||||
}
|
status = config_nameserver(&servers, &nservers, line);
|
||||||
}
|
free(line);
|
||||||
}
|
}
|
||||||
|
RegCloseKey(subkey);
|
||||||
RegCloseKey(mykey);
|
RegCloseKey(mykey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (RegOpenKeyEx(
|
||||||
|
HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
|
||||||
|
KEY_READ, &mykey
|
||||||
|
) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if ((result = RegQueryValueEx(
|
||||||
|
mykey, NAMESERVER, NULL, &data_type,
|
||||||
|
NULL, &bytes
|
||||||
|
)
|
||||||
|
) == ERROR_SUCCESS ||
|
||||||
|
result == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
if (bytes)
|
||||||
|
{
|
||||||
|
line = (char *)malloc(bytes+1);
|
||||||
|
if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
|
||||||
|
(unsigned char *)line, &bytes) ==
|
||||||
|
ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
status = config_nameserver(&servers, &nservers, line);
|
||||||
|
}
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegCloseKey(mykey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != ARES_EFILE) {
|
if (status != ARES_EFILE)
|
||||||
/*
|
{
|
||||||
|
/*
|
||||||
if (!channel->lookups) {
|
if (!channel->lookups) {
|
||||||
status = config_lookup(channel, "file bind");
|
status = config_lookup(channel, "file bind");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
status = ARES_EOF;
|
status = ARES_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(riscos)
|
#elif defined(riscos)
|
||||||
@@ -416,36 +420,41 @@ DhcpNameServer
|
|||||||
|
|
||||||
if (status == ARES_SUCCESS)
|
if (status == ARES_SUCCESS)
|
||||||
status = ARES_EOF;
|
status = ARES_EOF;
|
||||||
|
|
||||||
free(resolvers);
|
free(resolvers);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
{
|
||||||
fp = fopen(PATH_RESOLV_CONF, "r");
|
char *p;
|
||||||
if (!fp)
|
FILE *fp;
|
||||||
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE;
|
int linesize;
|
||||||
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
|
||||||
|
fp = fopen(PATH_RESOLV_CONF, "r");
|
||||||
|
if (!fp)
|
||||||
|
return (errno == ENOENT) ? ARES_SUCCESS : ARES_EFILE;
|
||||||
|
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
if ((p = try_config(line, "domain")) && channel->ndomains == -1)
|
if ((p = try_config(line, "domain")) && channel->ndomains == -1)
|
||||||
status = config_domain(channel, p);
|
status = config_domain(channel, p);
|
||||||
else if ((p = try_config(line, "lookup")) && !channel->lookups)
|
else if ((p = try_config(line, "lookup")) && !channel->lookups)
|
||||||
status = config_lookup(channel, p);
|
status = config_lookup(channel, p);
|
||||||
else if ((p = try_config(line, "search")) && channel->ndomains == -1)
|
else if ((p = try_config(line, "search")) && channel->ndomains == -1)
|
||||||
status = set_search(channel, p);
|
status = set_search(channel, p);
|
||||||
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
|
else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
|
||||||
status = config_nameserver(&servers, &nservers, p);
|
status = config_nameserver(&servers, &nservers, p);
|
||||||
else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
|
else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
|
||||||
status = config_sortlist(&sortlist, &nsort, p);
|
status = config_sortlist(&sortlist, &nsort, p);
|
||||||
else if ((p = try_config(line, "options")))
|
else if ((p = try_config(line, "options")))
|
||||||
status = set_options(channel, p);
|
status = set_options(channel, p);
|
||||||
else
|
else
|
||||||
status = ARES_SUCCESS;
|
status = ARES_SUCCESS;
|
||||||
if (status != ARES_SUCCESS)
|
if (status != ARES_SUCCESS)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -579,11 +588,52 @@ static int config_lookup(ares_channel channel, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int config_nameserver(struct server_state **servers, int *nservers,
|
static int config_nameserver(struct server_state **servers, int *nservers,
|
||||||
const char *str)
|
char *str)
|
||||||
{
|
{
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
struct server_state *newserv;
|
struct server_state *newserv;
|
||||||
|
/* On Windows, there may be more than one nameserver specified in the same
|
||||||
|
* registry key, so we parse it as a space or comma seperated list.
|
||||||
|
*/
|
||||||
|
#ifdef WIN32
|
||||||
|
char *p = str;
|
||||||
|
char *begin = str;
|
||||||
|
int more = 1;
|
||||||
|
while (more)
|
||||||
|
{
|
||||||
|
more = 0;
|
||||||
|
while (*p && !isspace(*p) && *str != ',')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
if (*p)
|
||||||
|
{
|
||||||
|
*p = 0;
|
||||||
|
more = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip multiple spaces or trailing spaces */
|
||||||
|
if (!*begin)
|
||||||
|
{
|
||||||
|
begin = ++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the part that actually sets the nameserver */
|
||||||
|
addr.s_addr = inet_addr(begin);
|
||||||
|
if (addr.s_addr == INADDR_NONE)
|
||||||
|
continue;
|
||||||
|
newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
|
||||||
|
if (!newserv)
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
newserv[*nservers].addr = addr;
|
||||||
|
*servers = newserv;
|
||||||
|
(*nservers)++;
|
||||||
|
|
||||||
|
if (!more)
|
||||||
|
break;
|
||||||
|
begin = ++p;
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* Add a nameserver entry, if this is a valid address. */
|
/* Add a nameserver entry, if this is a valid address. */
|
||||||
addr.s_addr = inet_addr(str);
|
addr.s_addr = inet_addr(str);
|
||||||
if (addr.s_addr == INADDR_NONE)
|
if (addr.s_addr == INADDR_NONE)
|
||||||
@@ -594,6 +644,7 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
|||||||
newserv[*nservers].addr = addr;
|
newserv[*nservers].addr = addr;
|
||||||
*servers = newserv;
|
*servers = newserv;
|
||||||
(*nservers)++;
|
(*nservers)++;
|
||||||
|
#endif
|
||||||
return ARES_SUCCESS;
|
return ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user