aboutsummaryrefslogtreecommitdiff
path: root/ares/ares_init.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-06-30 12:48:25 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-06-30 12:48:25 +0000
commit67f139e0166083c808f2de3a231ba5a9206ea1a5 (patch)
treec137aae9aec34bc7c9759471ece8b7bc8788156c /ares/ares_init.c
parent654f0473025afeaaa1cbfe64a13ae0b3ca306361 (diff)
- As was pointed out to me by Andreas Schuldei, the MAXHOSTNAMELEN define is
not posix or anything and thus c-ares failed to build on hurd (and possibly elsewhere). The define was also somewhat artificially used in the windows port. Now, I instead rewrote the use of gethostbyname to enlarge the host name buffer in case of need and totally avoid the use of the MAXHOSTNAMELEN define. I thus also removed the defien from the namser.h file where it was once added for the windows build. I also fixed init_by_defaults() function to not leak memory in case if error.
Diffstat (limited to 'ares/ares_init.c')
-rw-r--r--ares/ares_init.c133
1 files changed, 92 insertions, 41 deletions
diff --git a/ares/ares_init.c b/ares/ares_init.c
index 0b9637105..e33c3973a 100644
--- a/ares/ares_init.c
+++ b/ares/ares_init.c
@@ -912,7 +912,8 @@ okay:
static int init_by_defaults(ares_channel channel)
{
- char hostname[MAXHOSTNAMELEN + 1];
+ char *hostname = NULL;
+ int rc = ARES_SUCCESS;
if (channel->flags == -1)
channel->flags = 0;
@@ -927,53 +928,103 @@ static int init_by_defaults(ares_channel channel)
if (channel->tcp_port == -1)
channel->tcp_port = htons(NAMESERVER_PORT);
- if (channel->nservers == -1)
- {
- /* If nobody specified servers, try a local named. */
- channel->servers = malloc(sizeof(struct server_state));
- if (!channel->servers)
- return ARES_ENOMEM;
- channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
- channel->nservers = 1;
+ if (channel->nservers == -1) {
+ /* If nobody specified servers, try a local named. */
+ channel->servers = malloc(sizeof(struct server_state));
+ if (!channel->servers) {
+ rc = ARES_ENOMEM;
+ goto error;
}
+ channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
+ channel->nservers = 1;
+ }
- if (channel->ndomains == -1)
- {
- /* Derive a default domain search list from the kernel hostname,
- * or set it to empty if the hostname isn't helpful.
- */
- if (gethostname(hostname, sizeof(hostname)) == -1
- || !strchr(hostname, '.'))
- {
- channel->ndomains = 0;
- }
- else
- {
- channel->domains = malloc(sizeof(char *));
- if (!channel->domains)
- return ARES_ENOMEM;
- channel->ndomains = 0;
- channel->domains[0] = strdup(strchr(hostname, '.') + 1);
- if (!channel->domains[0])
- return ARES_ENOMEM;
- channel->ndomains = 1;
- }
- }
+#ifdef ENAMETOOLONG
+#define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
+#else
+#define toolong(x) (x == -1) && (EINVAL == errno)
+#endif
- if (channel->nsort == -1)
- {
- channel->sortlist = NULL;
- channel->nsort = 0;
+ if (channel->ndomains == -1) {
+ /* Derive a default domain search list from the kernel hostname,
+ * or set it to empty if the hostname isn't helpful.
+ */
+ size_t len = 64;
+ int res;
+
+ hostname = (char *)malloc(len);
+ if(!hostname) {
+ rc = ARES_ENOMEM;
+ goto error;
}
- if (!channel->lookups)
- {
- channel->lookups = strdup("fb");
- if (!channel->lookups)
- return ARES_ENOMEM;
+ do {
+ res = gethostname(hostname, len);
+
+ if(toolong(res)) {
+ char *p;
+ len *= 2;
+ p = realloc(hostname, len);
+ if(!p) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ hostname = p;
+ continue;
+ }
+ else if(res) {
+ rc = ARES_EBADNAME;
+ goto error;
+ }
+
+ } while(0);
+
+ channel->ndomains = 0; /* default to none */
+ if (strchr(hostname, '.')) {
+ /* a dot was found */
+
+ channel->domains = malloc(sizeof(char *));
+ if (!channel->domains) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->domains[0] = strdup(strchr(hostname, '.') + 1);
+ if (!channel->domains[0]) {
+ rc = ARES_ENOMEM;
+ goto error;
+ }
+ channel->ndomains = 1;
}
+ }
- return ARES_SUCCESS;
+ if (channel->nsort == -1) {
+ channel->sortlist = NULL;
+ channel->nsort = 0;
+ }
+
+ if (!channel->lookups) {
+ channel->lookups = strdup("fb");
+ if (!channel->lookups)
+ rc = ARES_ENOMEM;
+ }
+
+ error:
+ if(rc) {
+ if(channel->servers)
+ free(channel->servers);
+
+ if(channel->domains && channel->domains[0])
+ free(channel->domains[0]);
+ if(channel->domains)
+ free(channel->domains);
+ if(channel->lookups)
+ free(channel->lookups);
+ }
+
+ if(hostname)
+ free(hostname);
+
+ return rc;
}
#ifndef WIN32