Enhance --hostdir so that records are automatically removed when re-reading.

Initial patch from Dominik Derigs, re-written by Simon Kelley.
This commit is contained in:
Dominik Derigs
2022-10-16 22:08:45 +01:00
committed by Simon Kelley
parent 0ba25a0512
commit 0017dd74d5
5 changed files with 33 additions and 2 deletions

View File

@@ -18,6 +18,10 @@ version 2.88
flushed when its TTL expires, so the cache becomes flushed when its TTL expires, so the cache becomes
strictly least-recently-used. strictly least-recently-used.
Make --hostsdir (but NOT --dhcp-hostsdir and --dhcp-optsdir)
handle removal of whole files or entries within files.
Thanks to Dominik Derigs for the initial patches for this.
version 2.87 version 2.87
Allow arbitrary prefix lengths in --rev-server and Allow arbitrary prefix lengths in --rev-server and

View File

@@ -60,7 +60,8 @@ in alphabetical order.
.TP .TP
.B --hostsdir=<path> .B --hostsdir=<path>
Read all the hosts files contained in the directory. New or changed files Read all the hosts files contained in the directory. New or changed files
are read automatically. See \fB--dhcp-hostsdir\fP for details. are read automatically and modified and deleted files have removed records
automatically deleted.
.TP .TP
.B \-E, --expand-hosts .B \-E, --expand-hosts
Add the domain to simple names (without a period) in /etc/hosts Add the domain to simple names (without a period) in /etc/hosts

View File

@@ -388,6 +388,27 @@ static int is_expired(time_t now, struct crec *crecp)
return 1; return 1;
} }
/* Remove entries with a given UID from the cache */
unsigned int cache_remove_uid(const unsigned int uid)
{
int i;
unsigned int removed = 0;
struct crec *crecp, **up;
for (i = 0; i < hash_size; i++)
for (crecp = hash_table[i], up = &hash_table[i]; crecp; crecp = crecp->hash_next)
if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && crecp->uid == uid)
{
*up = crecp->hash_next;
free(crecp);
removed++;
}
else
up = &crecp->hash_next;
return removed;
}
static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now, static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,
unsigned int flags, struct crec **target_crec, unsigned int *target_uid) unsigned int flags, struct crec **target_crec, unsigned int *target_uid)
{ {

View File

@@ -1304,6 +1304,7 @@ struct crec *cache_find_by_name(struct crec *crecp,
char *name, time_t now, unsigned int prot); char *name, time_t now, unsigned int prot);
void cache_end_insert(void); void cache_end_insert(void);
void cache_start_insert(void); void cache_start_insert(void);
unsigned int cache_remove_uid(const unsigned int uid);
int cache_recv_insert(time_t now, int fd); int cache_recv_insert(time_t now, int fd);
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned int flags); time_t now, unsigned long ttl, unsigned int flags);

View File

@@ -294,12 +294,16 @@ int inotify_check(time_t now)
strcat(path, "/"); strcat(path, "/");
strcat(path, in->name); strcat(path, in->name);
my_syslog(LOG_INFO, _("inotify, new or changed file %s"), path); my_syslog(LOG_INFO, _("inotify: new, removed or changed file %s"), path);
if (dd->flags & AH_HOSTS) if (dd->flags & AH_HOSTS)
{ {
if ((ah = dyndir_addhosts(dd, path))) if ((ah = dyndir_addhosts(dd, path)))
{ {
const unsigned int removed = cache_remove_uid(ah->index);
if (removed > 0)
my_syslog(LOG_INFO, _("flushed %u outdated entries"), removed);
read_hostsfile(path, ah->index, 0, NULL, 0); read_hostsfile(path, ah->index, 0, NULL, 0);
#ifdef HAVE_DHCP #ifdef HAVE_DHCP
if (daemon->dhcp || daemon->doing_dhcp6) if (daemon->dhcp || daemon->doing_dhcp6)