summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--config.def.h5
-rw-r--r--pacredir.c97
-rw-r--r--pacredir.conf20
4 files changed, 121 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index ffba1c3..c29932e 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ CFLAGS += -O2 -Wall -Werror
CFLAGS += $(shell pkg-config --libs --cflags libcurl)
CFLAGS += $(shell pkg-config --libs --cflags avahi-client)
CFLAGS += $(shell pkg-config --libs --cflags libmicrohttpd)
+CFLAGS += -liniparser
VERSION := $(shell git describe --tags --long 2>/dev/null)
# this is just a fallback in case you do not use git but downloaded
# a release tarball...
@@ -39,6 +40,7 @@ install: install-bin install-doc
install-bin: pacredir
$(INSTALL) -D -m0755 pacredir $(DESTDIR)/usr/bin/pacredir
+ $(INSTALL) -D -m0644 pacredir.conf $(DESTDIR)/etc/pacredir.conf
$(INSTALL) -D -m0644 pacman/paccache $(DESTDIR)/etc/pacman.d/paccache
$(INSTALL) -D -m0644 avahi/pacserve.service $(DESTDIR)/etc/avahi/services/pacserve.service
$(INSTALL) -D -m0644 avahi/pacdbserve.service $(DESTDIR)/etc/avahi/services/pacdbserve.service
diff --git a/config.def.h b/config.def.h
index 72bf6a8..c81672e 100644
--- a/config.def.h
+++ b/config.def.h
@@ -41,6 +41,11 @@
#define PACSERVE "_pacserve._tcp"
#define PACDBSERVE "_pacdbserve_" ARCH "._tcp"
+/* path to the config file */
+#define CONFIGFILE "/etc/pacredir.conf"
+/* these characters are used as delimiter in config file */
+#define DELIMITER " ,;"
+
/* this is where pacman stores its local copy of db files */
#define SYNCPATH "/var/lib/pacman/sync"
diff --git a/pacredir.c b/pacredir.c
index aef0fba..d889309 100644
--- a/pacredir.c
+++ b/pacredir.c
@@ -15,6 +15,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <time.h>
+#include <net/if.h>
#include <avahi-client/client.h>
#include <avahi-client/lookup.h>
@@ -22,6 +23,7 @@
#include <avahi-common/malloc.h>
#include <avahi-common/error.h>
+#include <iniparser.h>
#include <curl/curl.h>
#include <microhttpd.h>
@@ -46,8 +48,17 @@ struct hosts {
struct hosts * next;
};
+/* ignore interfaces */
+struct ignore_interfaces {
+ /* interface name */
+ char * interface;
+ /* pointer to next struct element */
+ struct ignore_interfaces * next;
+};
+
/* global variables */
struct hosts * hosts = NULL;
+struct ignore_interfaces * ignore_interfaces = NULL;
static AvahiSimplePoll *simple_poll = NULL;
/*** write_log ***/
@@ -130,6 +141,8 @@ int remove_host(const char * host, const char * type) {
static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name,
const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) {
char * host;
+ char intname[IFNAMSIZ];
+ struct ignore_interfaces * tmp_ignore_interfaces = ignore_interfaces;
assert(b);
@@ -143,13 +156,23 @@ static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, Avah
case AVAHI_BROWSER_NEW:
host = get_fqdn(name, domain);
+ if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
+ goto out;
+
+ /* check whether to ignore the interface */
+ if_indextoname(interface, intname);
+ while (tmp_ignore_interfaces->next != NULL) {
+ if (strcmp(intname, tmp_ignore_interfaces->interface) == 0) {
+ write_log(stdout, "Ignoring service '%s' of type '%s' in domain '%s' on interface '%s'\n", name, type, domain, intname);
+ goto out;
+ }
+ tmp_ignore_interfaces = tmp_ignore_interfaces->next;
+ }
+
# if defined DEBUG
write_log(stdout, "NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
# endif
- if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
- goto out;
-
add_host(host, type);
out:
free(host);
@@ -377,6 +400,8 @@ static int ahc_echo(void * cls, struct MHD_Connection * connection, const char *
/*** sigterm_callback ***/
void sigterm_callback(int signal) {
+ write_log(stdout, "Received SIGTERM, quitting.\n");
+
avahi_simple_poll_quit(simple_poll);
}
@@ -395,6 +420,9 @@ void sighup_callback(int signal) {
/*** main ***/
int main(int argc, char ** argv) {
+ dictionary * ini;
+ char * values, * value;
+ struct ignore_interfaces * tmp_ignore_interfaces;
AvahiClient *client = NULL;
AvahiServiceBrowser *pacserve = NULL, *pacdbserve = NULL;
int error;
@@ -414,6 +442,62 @@ int main(int argc, char ** argv) {
hosts->pacdbserve.bad = 0;
hosts->next = NULL;
+ ignore_interfaces = malloc(sizeof(struct ignore_interfaces));
+ ignore_interfaces->interface = NULL;
+ ignore_interfaces->next = NULL;
+
+
+ /* parse config file */
+ if ((ini = iniparser_load(CONFIGFILE)) == NULL) {
+ write_log(stderr, "cannot parse file: " CONFIGFILE "\n");
+ return EXIT_FAILURE ;
+ }
+
+ /* store interfaces to ignore */
+ if ((values = iniparser_getstring(ini, "general:ignore interfaces", NULL)) != NULL) {
+# if defined DEBUG
+ write_log(stdout, "Ignore interface: [%s]\n", values);
+# endif
+ tmp_ignore_interfaces = ignore_interfaces;
+
+ value = strtok(values, DELIMITER);
+ while (value != NULL) {
+ tmp_ignore_interfaces->interface = strdup(value);
+ tmp_ignore_interfaces->next = malloc(sizeof(struct ignore_interfaces));
+ tmp_ignore_interfaces = tmp_ignore_interfaces->next;
+ value = strtok(NULL, DELIMITER);
+ }
+ tmp_ignore_interfaces->interface = NULL;
+ tmp_ignore_interfaces->next = NULL;
+ }
+
+ /* add static pacserve hosts */
+ if ((values = iniparser_getstring(ini, "general:pacserve hosts", NULL)) != NULL) {
+# if defined DEBUG
+ write_log(stdout, "pacserve hosts: [%s]\n", values);
+# endif
+ value = strtok(values, DELIMITER);
+ while (value != NULL) {
+ add_host(value, PACSERVE);
+ value = strtok(NULL, DELIMITER);
+ }
+ }
+
+ /* add static pacdbserve hosts */
+ if ((values = iniparser_getstring(ini, "general:pacdbserve hosts", NULL)) != NULL) {
+# if defined DEBUG
+ write_log(stdout, "pacdbserve hosts: [%s]\n", values);
+# endif
+ value = strtok(values, DELIMITER);
+ while (value != NULL) {
+ add_host(value, PACDBSERVE);
+ value = strtok(NULL, DELIMITER);
+ }
+ }
+
+ /* done reading config file, free */
+ iniparser_freedict(ini);
+
/* allocate main loop object */
if (!(simple_poll = avahi_simple_poll_new())) {
write_log(stderr, "Failed to create simple poll object.\n");
@@ -473,6 +557,13 @@ fail:
hosts = tmphosts;
}
+ while(ignore_interfaces->interface != NULL) {
+ free(ignore_interfaces->interface);
+ tmp_ignore_interfaces = ignore_interfaces->next;
+ free(ignore_interfaces);
+ ignore_interfaces = tmp_ignore_interfaces;
+ }
+
if (pacdbserve)
avahi_service_browser_free(pacdbserve);
diff --git a/pacredir.conf b/pacredir.conf
new file mode 100644
index 0000000..e68393e
--- /dev/null
+++ b/pacredir.conf
@@ -0,0 +1,20 @@
+# pacredir configuration file
+
+# We need a default section and call it 'general', so do not change this line.
+[general]
+
+# Some people like to run avahi on network interfaces with low bandwidth or
+# high cost, for example to use 'Bonjour' (Link-Local Messaging) on it.
+# Add these interfaces here to ignore them by pacredir. Just give multiple
+# interface if desired, separated by space, comma or semicolon.
+#ignore interfaces = tap0
+#ignore interfaces = tun0
+#ignore interfaces = openvpn
+#ignore interfaces = tap0 tun0 openvpn
+
+# You may want to add hosts that do not announce their services via avahi or
+# are connected to a different network segment. Add them here.
+# Please note that pacdbserve hosts depend on the servers architecture!
+#pacserve hosts = test1.domain
+#pacserve hosts = test1.domain test2.domain
+#pacdbserve hosts = test3.domain test4.domain