diff --git a/testmdnsd.c b/testmdnsd.c index cbfdfd9..0f88f9e 100644 --- a/testmdnsd.c +++ b/testmdnsd.c @@ -84,7 +84,7 @@ background() } #endif -void freehostents( struct hostent * h) { +static void freehostents( struct hostent * h) { for (struct hostent *p = h; p->h_name; ++p) { free(p->h_name); free(p->h_addr_list); @@ -92,22 +92,31 @@ void freehostents( struct hostent * h) { free(h); } -struct hostent * add_host(struct hostent * hosts, const char * hostname, struct in_addr ip) { +/* + * Add the mapping from hostname to in_addr_ip to the hosts block. + * The return value is the pointer to the next entry after the added entry. + * Case 1. The block is initially empty. Populate it with a loop like + * for (p = hosts,i=0;; p = add_host(p, hostname[i], addr[i],++i); + * Case 2. The block is in use. The added entry replaces the first one with + * h_length == 0. + */ +static struct hostent * add_host(struct hostent * hosts, const char * hostname, struct in_addr ip) { struct hostent * p; int newname = 1; for (p=hosts;p->h_name;++p) { - newname = 1; if (p->h_length == 0 || 0 == (newname = strcasecmp(p->h_name, hostname))) break; } if (p->h_name) { if (0 != newname) { + /* reusing an entry with a new name */ free(p->h_name); p->h_name = strdup(hostname); } } else { + /* new entry */ p->h_name = strdup(hostname); (p+1)->h_name = 0; } @@ -198,12 +207,18 @@ struct hostent * read_hosts(unsigned int extra) { struct in_addr it; it.s_addr = inet_addr(ip); do { - struct hostent * pp = add_host(p, name, it); - char * dot = strrchr(p->h_name, '.'); - if (dot && 0 == strcasecmp(dot, ".local")) + char * dot = strrchr(name, '.'); + if (dot && 0 == strcasecmp(dot, ".local")) { + struct hostent * pp = add_host(p, name, it); /* flag as expendable */ p->h_length = 0; - p = pp; + p = pp; + } else { + /* try to push down non-local names */ + struct hostent * pp = add_host(hostents, name, it); + /* not pushed down -> appended */ + if (pp > p) p = pp; + } /* running out of space? try for more */ if (--nleft < extra + 1) { @@ -249,7 +264,7 @@ struct hostent * read_hosts(unsigned int extra) { return hostents; } -int write_hosts(const struct hostent * hostents) { +static int write_hosts(const struct hostent * hostents) { int ret = -1; FILE * hosts = fopen( HOSTFILE, "w"); if (!hosts) { @@ -257,7 +272,7 @@ int write_hosts(const struct hostent * hostents) { return ret; } for (const struct hostent * p = hostents;p->h_name;++p) { - //printf( "writing %.255s\n", p->h_name); + /* printf( "writing %.255s\n", p->h_name); */ if (p->h_length > 0) { for (struct in_addr ** pa = (struct in_addr **)(p->h_addr_list); *pa; ++pa) { ret = fprintf( hosts, "%s\t%s\n", inet_ntoa(**pa), p->h_name); @@ -268,13 +283,19 @@ int write_hosts(const struct hostent * hostents) { return ret; } -void dump_hosts(const struct hostent * hostents) { +#if 0 +static void dump_host(const struct hostent * hostent) { + printf( "Host: %.255s\t%.32s\t%d\n", hostent->h_name, + inet_ntoa(*(struct in_addr *)(hostent->h_addr_list[0])), + hostent->h_length); +} + +static void dump_hosts(const struct hostent * hostents) { for (const struct hostent * p = hostents;p->h_name;++p) { - printf( "Host: %.255s\t%.32s\t%d\n", p->h_name, - inet_ntoa(*(struct in_addr *)(p->h_addr_list[0])), - p->h_length); + dump_host(p); } } +#endif static void handler_stop(int sig) { (void)sig; @@ -381,17 +402,15 @@ main(int argc, char **argv) return 1; } //dump_hosts(hosts); - struct hostent * p = hosts; /* recognise own .local hostname */ - p = add_host(p, fullname, saddr); + struct hostent * p = add_host(hosts, fullname, saddr); for (int i = 0; i < numserv; ++i) { struct in_addr it; it.s_addr = svcinfo[i].ipaddr; printf("Host %d: %s (%s)\n", i, svcinfo[i].hostname, inet_ntoa(it)); p = add_host(p, svcinfo[i].hostname, it); - } - p->h_name = 0; - //dump_hosts(hosts); + } + /* p->h_name = 0; */ write_hosts(hosts); freehostents(hosts); }