Fix losing static address mappings appended to hosts file

This commit is contained in:
df 2020-10-16 15:03:13 +01:00
parent a9dcc648ae
commit 302d113377
1 changed files with 37 additions and 18 deletions

View File

@ -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);
}