aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.def.h6
-rw-r--r--pacredir.c183
2 files changed, 73 insertions, 116 deletions
diff --git a/config.def.h b/config.def.h
index bb29921..68405cb 100644
--- a/config.def.h
+++ b/config.def.h
@@ -24,8 +24,10 @@
#define PAGE404 "<html><head><title>404 Not Found</title>" \
"</head><body>404 Not Found: %s</body></html>"
-/* the port pacredir listens to */
-#define PORT 7077
+/* the port pacredir, pacserve and pacdbserve listen to */
+#define PORT_PACREDIR 7077
+#define PORT_PACSERVE 7078
+#define PORT_PACDBSERVE 7079
/* avahi service names */
#define PACSERVE "_pacserve._tcp"
diff --git a/pacredir.c b/pacredir.c
index 9a105fc..0c997a6 100644
--- a/pacredir.c
+++ b/pacredir.c
@@ -6,6 +6,7 @@
*/
#include <assert.h>
+#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -26,8 +27,6 @@
/* services */
struct services {
- /* http port */
- uint16_t port;
/* true if host/service is online */
uint8_t online;
/* unix timestamp of last bad request */
@@ -38,7 +37,7 @@ struct services {
struct hosts {
/* host name */
char * host;
- /* port and bad time for services */
+ /* online status and bad time for services */
struct services pacserve;
struct services pacdbserve;
/* pointer to next struct element */
@@ -50,138 +49,105 @@ struct hosts * hosts = NULL;
static AvahiSimplePoll *simple_poll = NULL;
char * localname = NULL;
-/*** resolve_callback_new ***
- * Called whenever a service has been resolved successfully or timed out */
-static void resolve_callback_new(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol,
- AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host, const AvahiAddress *address,
- AVAHI_GCC_UNUSED uint16_t port, AVAHI_GCC_UNUSED AvahiStringList *txt, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
- AVAHI_GCC_UNUSED void* userdata) {
- struct hosts * tmphosts = hosts;
+/*** get_fqdn ***/
+char * get_fqdn(const char * hostname, const char * domainname) {
+ char * name;
+
+ name = malloc(strlen(hostname) + strlen(domainname) + 2 /* '.' and null char */);
+ sprintf(name, "%s.%s", hostname, domainname);
+ return name;
+}
- assert(r);
+/*** browse_callback ***
+ * Called whenever a new services becomes available on the LAN or is removed from the LAN */
+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) {
+ struct hosts * tmphosts = hosts;
+ char * host;
+ assert(b);
+
switch (event) {
- case AVAHI_RESOLVER_FAILURE:
- fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
- name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
- break;
+ case AVAHI_BROWSER_FAILURE:
+
+ fprintf(stderr, "%s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
+ avahi_simple_poll_quit(simple_poll);
+ return;
+
+ case AVAHI_BROWSER_NEW:
+ host = get_fqdn(name, domain);
+
+# if defined DEBUG
+ fprintf(stderr, "NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+# endif
+
+ /* We ignore the returned resolver object. In the callback
+ * function we free it. If the server is terminated before
+ * the callback function is called the server will free
+ * the resolver for us. */
+
+ /*if (avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback_new, c) == NULL)
+ fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); */
- case AVAHI_RESOLVER_FOUND: {
- /* ignore self */
if (strcmp(host, localname) == 0)
goto out;
while (tmphosts->host != NULL) {
if (strcmp(tmphosts->host, host) == 0) {
- printf("Updating service: %s, %s on port %d\n", host, type, port);
- goto out;
+ /* host already exists */
+ printf("Updating service %s on %s\n", type, host);
+ goto update;
}
tmphosts = tmphosts->next;
}
- printf("Adding host: %s, %s on port %d\n", host, type, port);
+ /* host not found, adding a new one */
+ printf("Adding host %s with service %s\n", host, type);
tmphosts->host = strdup(host);
- tmphosts->pacserve.port = 0;
tmphosts->pacserve.online = 0;
tmphosts->pacserve.bad = 0;
- tmphosts->pacdbserve.port = 0;
tmphosts->pacdbserve.online = 0;
tmphosts->pacdbserve.bad = 0;
tmphosts->next = realloc(tmphosts->next, sizeof(struct hosts));
tmphosts->next->host = NULL;
tmphosts->next->next = NULL;
-out:
+update:
if (strcmp(type, PACSERVE) == 0) {
- tmphosts->pacserve.port = port;
tmphosts->pacserve.online = 1;
tmphosts->pacserve.bad = 0;
- } else {
- tmphosts->pacdbserve.port = port;
+ } else if (strcmp(type, PACDBSERVE) == 0) {
tmphosts->pacdbserve.online = 1;
tmphosts->pacdbserve.bad = 0;
}
- break;
- }
- }
-
- avahi_service_resolver_free(r);
-}
+out:
+ free(host);
-/*** resolve_callback_remove ***
- * Called whenever a service has been resolved successfully or timed out */
-static void resolve_callback_remove(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol,
- AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host, const AvahiAddress *address,
- AVAHI_GCC_UNUSED uint16_t port, AVAHI_GCC_UNUSED AvahiStringList *txt, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
- AVAHI_GCC_UNUSED void* userdata) {
- struct hosts * tmphosts = hosts;
+ break;
- assert(r);
+ case AVAHI_BROWSER_REMOVE:
+ host = get_fqdn(name, domain);
- switch (event) {
- case AVAHI_RESOLVER_FAILURE:
- fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n",
- name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r))));
- break;
+# if defined DEBUG
+ fprintf(stderr, "REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
+# endif
- case AVAHI_RESOLVER_FOUND: {
+ /*if (avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback_remove, c) == NULL)
+ fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); */
while (tmphosts->host != NULL) {
if (strcmp(tmphosts->host, host) == 0) {
printf("Marking service %s on host %s offline\n", type, host);
if (strcmp(type, PACSERVE) == 0) {
tmphosts->pacserve.online = 0;
- } else {
+ } else if (strcmp(type, PACDBSERVE) == 0) {
tmphosts->pacdbserve.online = 0;
}
- goto out;
+ break;
}
tmphosts = tmphosts->next;
}
- break;
- }
- }
-
-out:
- avahi_service_resolver_free(r);
-}
-
-/*** browse_callback ***
- * Called whenever a new services becomes available on the LAN or is removed from the LAN */
-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) {
- AvahiClient *c = userdata;
-
- assert(b);
-
- switch (event) {
- case AVAHI_BROWSER_FAILURE:
-
- fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b))));
- avahi_simple_poll_quit(simple_poll);
- return;
-
- case AVAHI_BROWSER_NEW:
-# if defined DEBUG
- fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
-# endif
-
- /* We ignore the returned resolver object. In the callback
- * function we free it. If the server is terminated before
- * the callback function is called the server will free
- * the resolver for us. */
-
- if (avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback_new, c) == NULL)
- fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
-
- break;
-
- case AVAHI_BROWSER_REMOVE:
-# if defined DEBUG
- fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain);
-# endif
- if (avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback_remove, c) == NULL)
- fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c)));
+ free(host);
break;
@@ -316,11 +282,11 @@ static int ahc_echo(void * cls, struct MHD_Connection * connection, const char *
continue;
}
- url = realloc(url, 10 + strlen(tmphosts->host) + 5 + strlen(basename));
- sprintf(url, "http://%s:%d/%s", tmphosts->host, tmphosts->pacdbserve.port, basename);
+ url = realloc(url, 10 + strlen(tmphosts->host) + (log10(PORT_PACDBSERVE)+1) + strlen(basename));
+ sprintf(url, "http://%s:%d/%s", tmphosts->host, PORT_PACDBSERVE, basename);
printf("Trying %s\n", url);
- if (get_http_code(tmphosts->host, tmphosts->pacdbserve.port, url, &http_code, &last_modified) == EXIT_FAILURE)
+ if (get_http_code(tmphosts->host, PORT_PACDBSERVE, url, &http_code, &last_modified) == EXIT_FAILURE)
tmphosts->pacdbserve.bad = tv.tv_sec;
else if (http_code == MHD_HTTP_OK && last_modified > last_modified_recent) {
if (recent > 0)
@@ -354,11 +320,11 @@ static int ahc_echo(void * cls, struct MHD_Connection * connection, const char *
continue;
}
- url = realloc(url, 10 + strlen(tmphosts->host) + 5 + strlen(basename));
- sprintf(url, "http://%s:%d/%s", tmphosts->host, tmphosts->pacserve.port, basename);
+ url = realloc(url, 10 + strlen(tmphosts->host) + (log10(PORT_PACSERVE)+1) + strlen(basename));
+ sprintf(url, "http://%s:%d/%s", tmphosts->host, PORT_PACSERVE, basename);
printf("Trying %s\n", url);
- if (get_http_code(tmphosts->host, tmphosts->pacserve.port, url, &http_code, &last_modified) == EXIT_FAILURE)
+ if (get_http_code(tmphosts->host, PORT_PACSERVE, url, &http_code, &last_modified) == EXIT_FAILURE)
tmphosts->pacserve.bad = tv.tv_sec;
else if (http_code == MHD_HTTP_OK)
break;
@@ -409,15 +375,6 @@ void sighup_callback(int signal) {
}
}
-/*** get_fqdn ***/
-char * get_fqdn(const char * hostname, const char * domainname) {
- char * name;
-
- name = malloc(strlen(hostname) + strlen(domainname) + 2 /* '.' and null char */);
- sprintf(name, "%s.%s", hostname, domainname);
- return name;
-}
-
/*** main ***/
int main(int argc, char ** argv) {
AvahiClient *client = NULL;
@@ -432,10 +389,8 @@ int main(int argc, char ** argv) {
/* allocate first struct element as dummy */
hosts = malloc(sizeof(struct hosts));
hosts->host = NULL;
- hosts->pacserve.port = 0;
hosts->pacserve.online = 0;
hosts->pacserve.bad = 0;
- hosts->pacdbserve.port = 0;
hosts->pacdbserve.online = 0;
hosts->pacdbserve.bad = 0;
hosts->next = NULL;
@@ -455,6 +410,9 @@ int main(int argc, char ** argv) {
goto fail;
}
+ /* get the local hostname used by avahi */
+ localname = get_fqdn(avahi_client_get_host_name(client), avahi_client_get_domain_name(client));
+
/* create the service browser for PACSERVE */
if ((pacserve = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, PACSERVE, NULL, 0, browse_callback, client)) == NULL) {
fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
@@ -467,12 +425,9 @@ int main(int argc, char ** argv) {
goto fail;
}
- /* get the local hostname used by avahi */
- localname = get_fqdn(avahi_client_get_host_name(client), avahi_client_get_domain_name(client));
-
/* start http server */
- if ((mhd = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, PORT, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END)) == NULL) {
- fprintf(stderr, "Could not start daemon on port %d.\n", PORT);
+ if ((mhd = MHD_start_daemon(MHD_USE_THREAD_PER_CONNECTION, PORT_PACREDIR, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END)) == NULL) {
+ fprintf(stderr, "Could not start daemon on port %d.\n", PORT_PACREDIR);
return EXIT_FAILURE;
}