mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Add --dhcp-hostsdir config option.
This commit is contained in:
119
src/inotify.c
119
src/inotify.c
@@ -19,6 +19,11 @@
|
||||
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
static void check_for_dhcp_inotify(struct inotify_event *in, time_t now);
|
||||
#endif
|
||||
|
||||
|
||||
/* the strategy is to set a inotify on the directories containing
|
||||
resolv files, for any files in the directory which are close-write
|
||||
or moved into the directory.
|
||||
@@ -40,8 +45,6 @@ void inotify_dnsmasq_init()
|
||||
struct resolvc *res;
|
||||
|
||||
inotify_buffer = safe_malloc(INOTIFY_SZ);
|
||||
|
||||
|
||||
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
|
||||
if (daemon->inotifyfd == -1)
|
||||
@@ -66,6 +69,7 @@ void inotify_dnsmasq_init()
|
||||
{
|
||||
*d = 0; /* make path just directory */
|
||||
res->wd = inotify_add_watch(daemon->inotifyfd, path, IN_CLOSE_WRITE | IN_MOVED_TO);
|
||||
|
||||
res->file = d+1; /* pointer to filename */
|
||||
*d = '/';
|
||||
|
||||
@@ -78,7 +82,7 @@ void inotify_dnsmasq_init()
|
||||
}
|
||||
}
|
||||
|
||||
int inotify_check(void)
|
||||
int inotify_check(time_t now)
|
||||
{
|
||||
int hit = 0;
|
||||
|
||||
@@ -101,13 +105,116 @@ int inotify_check(void)
|
||||
for (res = daemon->resolv_files; res; res = res->next)
|
||||
if (res->wd == in->wd && in->len != 0 && strcmp(res->file, in->name) == 0)
|
||||
hit = 1;
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
if (daemon->dhcp || daemon->doing_dhcp6)
|
||||
check_for_dhcp_inotify(in, now);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_DHCP
|
||||
/* initialisation for dhcp-hostdir. Set inotify watch for each directory, and read pre-existing files */
|
||||
void set_dhcp_inotify(void)
|
||||
{
|
||||
struct hostsfile *ah;
|
||||
|
||||
|
||||
for (ah = daemon->inotify_hosts; ah; ah = ah->next)
|
||||
{
|
||||
DIR *dir_stream = NULL;
|
||||
struct dirent *ent;
|
||||
struct stat buf;
|
||||
|
||||
if (stat(ah->fname, &buf) == -1 || !(S_ISDIR(buf.st_mode)))
|
||||
{
|
||||
my_syslog(LOG_ERR, _("bad directory in dhcp-hostsdir %s"), ah->fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(ah->flags & AH_WD_DONE))
|
||||
{
|
||||
ah->wd = inotify_add_watch(daemon->inotifyfd, ah->fname, IN_CLOSE_WRITE | IN_MOVED_TO);
|
||||
ah->flags |= AH_WD_DONE;
|
||||
}
|
||||
/* Read contents of dir _after_ calling add_watch, in the ho[e of avoiding
|
||||
a race which misses files being added as we start */
|
||||
if (ah->wd == -1 || !(dir_stream = opendir(ah->fname)))
|
||||
{
|
||||
my_syslog(LOG_ERR, _("failed to create inotify for %s"), ah->fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((ent = readdir(dir_stream)))
|
||||
{
|
||||
size_t lendir = strlen(ah->fname);
|
||||
size_t lenfile = strlen(ent->d_name);
|
||||
char *path;
|
||||
|
||||
/* ignore emacs backups and dotfiles */
|
||||
if (lenfile == 0 ||
|
||||
ent->d_name[lenfile - 1] == '~' ||
|
||||
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
|
||||
ent->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
if ((path = whine_malloc(lendir + lenfile + 2)))
|
||||
{
|
||||
strcpy(path, ah->fname);
|
||||
strcat(path, "/");
|
||||
strcat(path, ent->d_name);
|
||||
|
||||
/* ignore non-regular files */
|
||||
if (stat(path, &buf) != -1 && S_ISREG(buf.st_mode))
|
||||
option_read_hostsfile(path);
|
||||
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_for_dhcp_inotify(struct inotify_event *in, time_t now)
|
||||
{
|
||||
struct hostsfile *ah;
|
||||
|
||||
/* ignore emacs backups and dotfiles */
|
||||
if (in->len == 0 ||
|
||||
in->name[in->len - 1] == '~' ||
|
||||
(in->name[0] == '#' && in->name[in->len - 1] == '#') ||
|
||||
in->name[0] == '.')
|
||||
return;
|
||||
|
||||
for (ah = daemon->inotify_hosts; ah; ah = ah->next)
|
||||
if (ah->wd == in->wd)
|
||||
{
|
||||
size_t lendir = strlen(ah->fname);
|
||||
char *path;
|
||||
|
||||
if ((path = whine_malloc(lendir + in->len + 2)))
|
||||
{
|
||||
strcpy(path, ah->fname);
|
||||
strcat(path, "/");
|
||||
strcat(path, in->name);
|
||||
|
||||
if (option_read_hostsfile(path))
|
||||
{
|
||||
/* Propogate the consequences of loading a new dhcp-host */
|
||||
dhcp_update_configs(daemon->dhcp_conf);
|
||||
lease_update_from_configs();
|
||||
lease_update_file(now);
|
||||
lease_update_dns(1);
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DHCP */
|
||||
|
||||
#endif /* LINUX_NETWORK */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user