aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore10
-rw-r--r--Makefile18
-rw-r--r--README.md7
-rw-r--r--config.def.h12
-rw-r--r--html.h99
-rw-r--r--logo.pngbin0 -> 3667 bytes
-rw-r--r--logo.svg98
-rw-r--r--pacredir.c171
-rw-r--r--pacredir.h8
9 files changed, 372 insertions, 51 deletions
diff --git a/.gitignore b/.gitignore
index 6ff0f2f..ad59caa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,12 @@
*~
*.html
*.o
-pacredir
-config.h
compat/pacserve-announce.service
-systemd/pacserve.service
-version.h
+config.h
+favicon.h
+favicon.png
+pacredir
pacredir-*.tar.xz
pacredir-*.tar.xz.asc
+systemd/pacserve.service
+version.h
diff --git a/Makefile b/Makefile
index 879ff37..d7c7e4b 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ ID := $(shell shopt -u extglob && source /etc/os-release && echo $$ID)
# this is just a fallback in case you do not use git but downloaded
# a release tarball...
-VERSION := 0.6.0
+VERSION := 0.7.2
SERVICESIN = $(wildcard */*.service.in)
SERVICES = $(SERVICESIN:.in=)
@@ -36,14 +36,24 @@ HTML = $(MARKDOWN:.md=.html)
all: pacredir $(SERVICES) $(HTML)
-pacredir: pacredir.c pacredir.h config.h version.h
+pacredir: pacredir.c pacredir.h config.h favicon.h html.h version.h
$(CC) $< $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -DREPRODUCIBLE=$(REPRODUCIBLE) -o $@
config.h: config.def.h
$(CP) $< $@
version.h: $(wildcard .git/HEAD .git/index .git/refs/tags/*) Makefile
- printf "#ifndef VERSION\n#define VERSION \"%s\"\n#endif\n#define ARCH \"%s\"\n#define ID \"%s\"\n" $(shell git describe --long 2>/dev/null || echo ${VERSION}) $(ARCH) $(ID) > $@
+ printf '#ifndef VERSION_H\n#define VERSION_H\n#define VERSION\t"%s"\n#define ARCH\t"%s"\n#define ID\t"%s"\n#endif\n' $(shell git describe --long 2>/dev/null || echo ${VERSION}) $(ARCH) $(ID) > $@
+
+favicon.png: logo.svg Makefile
+ rsvg-convert --width 32 --height 32 $< > $@
+ oxipng $@
+
+favicon.h: favicon.png Makefile
+ printf '#ifndef FAVICON_H\n#define FAVICON_H\n' > $@
+ printf 'static unsigned char favicon[] = {\n' >> $@
+ od -t x1 -A n -v < $< | sed 's/\([0-9a-f]\{2\}\)/0x\1,/g' >> $@
+ printf '};\n#define FAVICON_SHA1 "%s"\n#endif\n' $(shell sha1sum $< | cut -d' ' -f1) >> $@
%.service: %.service.in
$(SED) 's/%ARCH%/$(ARCH)/; s/%ARCH_BYTES%/$(shell (printf $(ARCH) | wc -c; printf $(ARCH) | od -t d1 -A n) | tr -s " ")/; s/%ID%/$(ID)/; s/%ID_BYTES%/$(shell (printf $(ID) | wc -c; printf $(ID) | od -t d1 -A n) | tr -s " ")/' $< > $@
@@ -79,7 +89,7 @@ install-avahi: compat/pacserve-announce.service
$(INSTALL) -D -m0644 compat/02-pacredir-avahi-MulticastDNS-resolve.conf $(DESTDIR)/etc/systemd/resolved.conf.d/02-pacredir-avahi-MulticastDNS-resolve.conf
clean:
- $(RM) -f *.o *~ pacredir $(SERVICES) $(HTML) version.h
+ $(RM) -f *.o *~ pacredir $(SERVICES) $(HTML) favicon.png favicon.h version.h
distclean:
$(RM) -f *.o *~ pacredir $(SERVICES) $(HTML) version.h config.h
diff --git a/README.md b/README.md
index 0ce3009..c70f201 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,8 @@ pacredir
**pacredir - redirect pacman requests, assisted by mDNS Service Discovery**
+![pacredir logo](logo.svg)
+
By default every [Arch Linux ↗️](https://archlinux.org/) installation
downloads its package files from online mirrors, transferring all the
bits via WAN connection.
@@ -80,6 +82,11 @@ repository definitions in `pacman.conf`:
To get a better idea what happens in the background have a look at
[the request flow chart](FLOW.md).
+### Status page
+
+A simple status page is available when `pacredir` is running. Just point
+your browser to [your local instance](http://localhost:7077/).
+
### Databases from cache server
By default databases are not fetched from cache servers. To make that
diff --git a/config.def.h b/config.def.h
index fef2e1c..b2e29fe 100644
--- a/config.def.h
+++ b/config.def.h
@@ -23,15 +23,9 @@
#define DROP_PRIV_UID 65534
#define DROP_PRIV_GID 65534
-/* website url */
-#define WEBSITE "https://pacredir.eworm.de/"
-
-/* This is used for default documents. Usually you will not see this anyway. */
-#define PAGE307 "<html><head><title>307 temporary redirect</title>" \
- "</head><body>307 temporary redirect: " \
- "<a href=\"%s\">%s</a></body></html>"
-#define PAGE404 "<html><head><title>404 Not Found</title>" \
- "</head><body>404 Not Found: %s</body></html>"
+/* website & url */
+#define WEBSITE "pacredir.eworm.de"
+#define WEBURL "https://" WEBSITE "/"
/* the ports pacredir and pacserve listen to */
#define PORT_PACREDIR 7077
diff --git a/html.h b/html.h
new file mode 100644
index 0000000..082a2a7
--- /dev/null
+++ b/html.h
@@ -0,0 +1,99 @@
+/*
+ * (C) 2013-2025 by Christian Hesse <mail@eworm.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef _HTML_H
+#define _HTML_H
+
+/* This is used for default documents. Usually you will not see this anyway. */
+#define PAGE307 \
+ "<html><head><title>307 temporary redirect</title>" \
+ "</head><body>307 temporary redirect: " \
+ "<a href=\"%s\">%s</a></body></html>"
+#define PAGE404 \
+ "<html><head><title>404 Not Found</title>" \
+ "</head><body>404 Not Found: %s</body></html>"
+
+/* status page */
+#define CIRCLE_GREEN "&#x1F7E2;"
+#define CIRCLE_YELLOW "&#x1F7E1;"
+#define CIRCLE_ORANGE "&#x1F7E0;"
+#define CIRCLE_RED "&#x1F534;"
+#define CIRCLE_BLUE "&#x1F535;"
+
+#define STATUS_HEAD \
+ "<!DOCTYPE html><html lang=\"en\">" \
+ "<head><title>pacredir status</title>" \
+ "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" \
+ "<meta http-equiv=\"refresh\" content=\"30\">" \
+ "<style>body { font-family: sans-serif; } " \
+ "h1 { padding-left: 36px; background-image: url(\"/favicon.png\"); background-repeat: no-repeat; } " \
+ "a { color: black; text-decoration: none; } " \
+ "a:hover { text-decoration: underline; } " \
+ "th { background: #efefef; } " \
+ "td { text-align: center; padding: 1px 5px; } " \
+ "tr:nth-child(even) { background: #dfdfdf; } " \
+ "tr:nth-child(odd) { background: #efefef; } " \
+ "tr:hover { background: #dfefef; }</style>" \
+ "<link rel=\"icon\" href=\"/favicon.png \" type=\"image/png\">" \
+ "</head><body><h1>pacredir status</h1>" \
+ "<p>This is <code>pacredir</code> version <i>" VERSION "</i> running on localhost. " \
+ "Visit <a href=\"" WEBURL "\">" WEBSITE "</a> for documentation.</p>" \
+ "<table>" \
+ "<tr><td>Distribution:</td><td><b>" ID "</b></td></tr>" \
+ "<tr><td>Architecture:</td><td><b>" ARCH "</b></td></tr>" \
+ "<tr><td>Redirects:</td><td><b>%d</b></td></tr>" \
+ "<tr><td>Not found:</td><td><b>%d</b></td></tr>" \
+ "<tr><td>Over all:</td><td><b>%s</b></td></tr>" \
+ "</table>"
+
+#define STATUS_INT_HEAD \
+ "<h2 id=\"ignored-interfaces\"><a href=\"#ignored-interfaces\">Ignored interfaces</a></h2>" \
+ "<table><tr><th>interface</th><th>link</th></tr>"
+#define STATUS_INT_ONE \
+ "<tr><td>%s</td><td>%d</td></tr>"
+#define STATUS_INT_ONE_NA \
+ "<tr><td>%s</td><td>" CIRCLE_ORANGE "</td></tr>"
+#define STATUS_INT_NONE \
+ "<tr><td colspan=2>(none)</td></tr>"
+#define STATUS_INT_FOOT \
+ "</table>"
+
+#define STATUS_HOST_HEAD \
+ "<h2 id=\"hosts\"><a href=\"#hosts\">Hosts</a></h2>" \
+ "<table><tr>" \
+ "<th>host</th>" \
+ "<th>port</th>" \
+ "<th colspan=2>state</th>" \
+ "<th colspan=2>finds</th>" \
+ "<th colspan=2>bad</th></tr>"
+#define STATUS_HOST_ONE \
+ "<tr>" \
+ "<td>%s</td>" \
+ "<td>%d</td>" \
+ "<td>%s</td><td>%s</td>" \
+ "<td>%s</td><td>%d</td>" \
+ "<td>%s</td><td>%d</td></tr>"
+#define STATUS_HOST_NONE \
+ "<tr><td colspan=9>(none)</td></tr>"
+#define STATUS_HOST_FOOT \
+ "</table>"
+
+#define STATUS_FOOT \
+ "</body></html>"
+
+#endif /* _HTML_H */
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000..5dad40f
--- /dev/null
+++ b/logo.png
Binary files differ
diff --git a/logo.svg b/logo.svg
new file mode 100644
index 0000000..6626c12
--- /dev/null
+++ b/logo.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
+
+<svg
+ fill="#000000"
+ width="96"
+ height="96"
+ viewBox="0 0 2.88 2.88"
+ version="1.1"
+ id="svg1"
+ sodipodi:docname="logo.svg"
+ inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
+ inkscape:export-filename="pacman-redir.png"
+ inkscape:export-xdpi="192"
+ inkscape:export-ydpi="192"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs1" />
+ <sodipodi:namedview
+ id="namedview1"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="8.8561223"
+ inkscape:cx="47.932942"
+ inkscape:cy="45.956908"
+ inkscape:window-width="1920"
+ inkscape:window-height="1047"
+ inkscape:window-x="0"
+ inkscape:window-y="33"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg1" />
+ <g
+ id="g2">
+ <rect
+ style="fill:#ffffff;stroke-width:0.06;stroke-linecap:round;stroke-linejoin:round"
+ id="rect1"
+ x="0"
+ y="0"
+ height="2.8800001"
+ width="2.8800001"
+ rx="0.45000005"
+ ry="0.45000005" />
+ <path
+ style="fill:#ffcc00;fill-opacity:1;stroke:#000000;stroke-width:0.18;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
+ id="path2"
+ sodipodi:type="arc"
+ sodipodi:cx="1.35"
+ sodipodi:cy="1.3500063"
+ sodipodi:rx="1.17"
+ sodipodi:ry="1.17"
+ sodipodi:start="0.61086524"
+ sodipodi:end="5.6723201"
+ sodipodi:arc-type="slice"
+ d="M 2.3084079,2.0210907 A 1.17,1.17 0 0 1 0.99817424,2.4658551 1.17,1.17 0 0 1 0.18000007,1.3500063 1.17,1.17 0 0 1 0.99817428,0.23415754 1.17,1.17 0 0 1 2.3084079,0.67892197 L 1.35,1.3500063 Z" />
+ <circle
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.06;stroke-linecap:round;stroke-linejoin:round"
+ id="path3"
+ cx="1.08"
+ cy="0.81000006"
+ r="0.27000001" />
+ <g
+ id="g1">
+ <rect
+ style="fill:#dd55ff;fill-opacity:1;stroke:#000000;stroke-width:0.18;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
+ id="rect4"
+ width="1.2335274"
+ height="0.60436016"
+ x="1.4664726"
+ y="1.8063096"
+ ry="0.30218008" />
+ <path
+ sodipodi:type="star"
+ style="fill:#dd55ff;fill-opacity:1;stroke:#000000;stroke-width:0.06;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-dasharray:none"
+ id="path4"
+ inkscape:flatsided="true"
+ sodipodi:sides="3"
+ sodipodi:cx="-0.16725793"
+ sodipodi:cy="0.41981158"
+ sodipodi:r1="0.22600283"
+ sodipodi:r2="0.2553075"
+ sodipodi:arg1="1.017775"
+ sodipodi:arg2="2.0649725"
+ inkscape:rounded="0.1"
+ inkscape:randomized="0"
+ d="m -0.04854756,0.61212674 c -0.03330996,0.0205612 -0.34346381,-0.14653865 -0.34461539,-0.18566654 -0.001152,-0.0391279 0.29863811,-0.22417907 0.33309965,-0.20561241 0.03446154,0.0185667 0.04482571,0.37071771 0.01151574,0.39127895 z"
+ transform="matrix(3.0000001,0,0,3.0000001,2.036195,0.85837623)" />
+ </g>
+ </g>
+</svg>
diff --git a/pacredir.c b/pacredir.c
index cf9db07..eab868c 100644
--- a/pacredir.c
+++ b/pacredir.c
@@ -38,9 +38,10 @@ unsigned int count_redirect = 0, count_not_found = 0;
/*** write_log ***/
static int write_log(FILE *stream, const char *format, ...) {
va_list args;
- va_start(args, format);
+ va_start(args, format);
vfprintf(stream, format, args);
+ va_end(args);
fflush(stream);
return EXIT_SUCCESS;
@@ -136,7 +137,7 @@ static void update_hosts(const uint8_t refcnt) {
r = sd_bus_open_system(&bus);
if (r < 0) {
write_log(stderr, "Failed to open system bus: %s\n", strerror(-r));
- goto finish;
+ goto fast_finish;
}
r = sd_bus_call_method(bus, "org.freedesktop.resolve1", "/org/freedesktop/resolve1",
@@ -157,7 +158,7 @@ static void update_hosts(const uint8_t refcnt) {
if (refcnt == 0) {
usleep(250000);
update_hosts(refcnt + 1);
- goto finish;
+ goto fast_finish;
}
r = sd_bus_message_enter_container(reply_record, 'a', "(iqqay)");
@@ -337,6 +338,12 @@ finish_service:
if (r < 0)
goto parse_failure_record;
+ goto finish;
+
+parse_failure_record:
+ write_log(stderr, "Parse failure for record: %s\n", strerror(-r));
+
+finish:
/* mark hosts offline that did not show up in query */
hosts_ptr = hosts;
while (hosts_ptr->host != NULL) {
@@ -348,12 +355,7 @@ finish_service:
hosts_ptr = hosts_ptr->next;
}
- goto finish;
-
-parse_failure_record:
- write_log(stderr, "Parse failure for record: %s\n", strerror(-r));
-
-finish:
+fast_finish:
sd_bus_message_unref(reply_record);
sd_bus_flush_close_unref(bus);
}
@@ -382,6 +384,7 @@ static int add_host(const char * host, const uint16_t port, const uint8_t mdns)
hosts_ptr->mdns = mdns;
hosts_ptr->badtime = 0;
hosts_ptr->badcount = 0;
+ hosts_ptr->finds = 0;
hosts_ptr->next = malloc(sizeof(struct hosts));
hosts_ptr->next->host = NULL;
@@ -489,6 +492,87 @@ static void * get_http_code(void * data) {
return NULL;
}
+/* append_string */
+static char * append_string(char * string, const char *format, ...) {
+ va_list args;
+ size_t string_len = 0, append_len;
+
+ if (string != NULL)
+ string_len = strlen(string);
+
+ va_start(args, format);
+ append_len = vsnprintf(NULL, 0, format, args) + 1;
+ va_end(args);
+
+ string = realloc(string, string_len + append_len);
+
+ va_start(args, format);
+ vsnprintf(string + string_len, append_len, format, args);
+ va_end(args);
+
+ return string;
+}
+/*** status_page ***/
+static char * status_page(void) {
+ struct ignore_interfaces * ignore_interfaces_ptr = ignore_interfaces;
+ struct hosts * hosts_ptr = hosts;
+ char *page = NULL, *overall = CIRCLE_BLUE;
+
+ if (count_redirect + count_not_found)
+ switch (count_redirect * 4 / (count_redirect + count_not_found)) {
+ case 0:
+ overall = CIRCLE_RED;
+ break;
+ case 1:
+ overall = CIRCLE_ORANGE;
+ break;
+ case 2:
+ overall = CIRCLE_YELLOW;
+ break;
+ default:
+ overall = CIRCLE_GREEN;
+ break;
+ }
+
+ page = append_string(page, STATUS_HEAD, count_redirect, count_not_found, overall);
+
+ page = append_string(page, STATUS_INT_HEAD);
+ if (ignore_interfaces_ptr->interface == NULL)
+ page = append_string(page, STATUS_INT_NONE);
+ while (ignore_interfaces_ptr->interface != NULL) {
+ if (ignore_interfaces_ptr->ifindex > 0)
+ /* write_log(stdout, STATUS_INT_ONE,
+ ignore_interfaces_ptr->interface, ignore_interfaces_ptr->ifindex); */
+ page = append_string(page, STATUS_INT_ONE,
+ ignore_interfaces_ptr->interface, ignore_interfaces_ptr->ifindex);
+ else
+ page = append_string(page, STATUS_INT_ONE_NA,
+ ignore_interfaces_ptr->interface);
+
+ ignore_interfaces_ptr = ignore_interfaces_ptr->next;
+ }
+ page = append_string(page, STATUS_INT_FOOT);
+
+ page = append_string(page, STATUS_HOST_HEAD);
+ if (hosts_ptr->host == NULL)
+ page = append_string(page, STATUS_HOST_NONE);
+ while (hosts_ptr->host != NULL) {
+ page = append_string(page, STATUS_HOST_ONE,
+ hosts_ptr->host, hosts_ptr->port,
+ hosts_ptr->mdns ? (hosts_ptr->online ? CIRCLE_GREEN : CIRCLE_RED) : CIRCLE_BLUE,
+ hosts_ptr->mdns ? (hosts_ptr->online ? "online" : "offline") : "static",
+ hosts_ptr->finds ? CIRCLE_GREEN : CIRCLE_BLUE, hosts_ptr->finds,
+ hosts_ptr->badcount ? CIRCLE_RED : CIRCLE_BLUE, hosts_ptr->badcount);
+
+ hosts_ptr = hosts_ptr->next;
+ }
+ page = append_string(page, STATUS_HOST_FOOT);
+
+ page = append_string(page, STATUS_FOOT);
+
+ return page;
+}
+
/*** ahc_echo ***
* called whenever a http request is received */
static enum MHD_Result ahc_echo(void * cls,
@@ -516,13 +600,33 @@ static enum MHD_Result ahc_echo(void * cls,
pthread_t * tid = NULL;
struct request ** requests = NULL;
struct request * request = NULL;
- long http_code = 0;
+ long http_code = MHD_HTTP_NOT_FOUND;
double time_total = INFINITY;
char ctime[26];
/* initialize struct timeval */
gettimeofday(&tv, NULL);
+ /* give status page */
+ if (strcmp(uri, "/") == 0) {
+ http_code = MHD_HTTP_OK;
+ page = status_page();
+ goto response;
+ }
+
+ /* give favicon */
+ if (strcmp(uri, "/favicon.png") == 0) {
+ http_code = MHD_HTTP_OK;
+ goto response;
+ }
+
+ /* give a simple ok response for monitoring */
+ if (strcmp(uri, "/check") == 0) {
+ http_code = MHD_HTTP_OK;
+ page = strdup("OK");
+ goto response;
+ }
+
/* we want the filename, not the path */
basename = uri;
while (strstr(basename, "/") != NULL)
@@ -546,15 +650,6 @@ static enum MHD_Result ahc_echo(void * cls,
/* clear context pointer */
*ptr = NULL;
- /* redirect to website if no file given */
- if (*basename == 0) {
- http_code = MHD_HTTP_OK;
- /* duplicate string so we can free it later */
- url = strdup(WEBSITE);
- host = basename = "project site";
- goto response;
- }
-
/* process db file request (*.db and *.files) */
if ((strlen(basename) > 3 && strcmp(basename + strlen(basename) - 3, ".db") == 0) ||
(strlen(basename) > 6 && strcmp(basename + strlen(basename) - 6, ".files") == 0)) {
@@ -663,11 +758,12 @@ static enum MHD_Result ahc_echo(void * cls,
request->time_total < time_total))) ||
/* for packages try to guess the fastest peer */
(dbfile == 0 && request->time_total < time_total))) {
+ request->host->finds++;
if (url != NULL)
free(url);
url = request->url;
host = request->host->host;
- http_code = MHD_HTTP_OK;
+ http_code = MHD_HTTP_TEMPORARY_REDIRECT;
last_modified = request->last_modified;
time_total = request->time_total;
} else
@@ -677,22 +773,33 @@ static enum MHD_Result ahc_echo(void * cls,
/* increase counters before reponse label,
do not count redirects to project page */
- if (http_code == MHD_HTTP_OK)
+ if (http_code == MHD_HTTP_TEMPORARY_REDIRECT)
count_redirect++;
else
count_not_found++;
response:
/* give response */
- if (http_code == MHD_HTTP_OK) {
+ if (http_code == MHD_HTTP_TEMPORARY_REDIRECT) {
write_log(stdout, "Redirecting to %s: %s\n", host, url);
page = malloc(strlen(PAGE307) + strlen(url) + strlen(basename) + 1);
sprintf(page, PAGE307, url, basename);
response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE);
ret = MHD_add_response_header(response, "Location", url);
- ret = MHD_queue_response(connection, MHD_HTTP_TEMPORARY_REDIRECT, response);
free(url);
- } else {
+ } else if (http_code == MHD_HTTP_OK) {
+ if (page != NULL) {
+ write_log(stdout, "Sending status page.\n");
+ response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE);
+ ret = MHD_add_response_header (response, "Content-Type", "text/html");
+ } else {
+ write_log(stdout, "Sending favicon.\n");
+ response = MHD_create_response_from_buffer(sizeof(favicon), favicon, MHD_RESPMEM_PERSISTENT);
+ ret = MHD_add_response_header(response, "ETag", FAVICON_SHA1);
+ ret = MHD_add_response_header(response, "Cache-Control", "max-age=86400");
+ ret = MHD_add_response_header (response, "Content-Type", "image/png");
+ }
+ } else { /* MHD_HTTP_NOT_FOUND */
if (req_count < 0)
write_log(stdout, "Currently no peers are available to check for %s.\n",
basename);
@@ -706,9 +813,10 @@ response:
page = malloc(strlen(PAGE404) + strlen(basename) + 1);
sprintf(page, PAGE404, basename);
response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE);
- ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response);
}
+ ret = MHD_add_response_header(response, "Server", PROGNAME " v" VERSION " " ID "/" ARCH);
+ ret = MHD_queue_response(connection, http_code, response);
MHD_destroy_response(response);
/* report counts to systemd */
@@ -770,15 +878,10 @@ static void sigusr_callback(int signal) {
if (hosts_ptr->host == NULL)
write_log(stdout, " (none)\n");
while (hosts_ptr->host != NULL) {
- if (hosts_ptr->badcount > 0)
- write_log(stdout, " -> %s (%s, %s, port: %d, bad count: %d)\n",
- hosts_ptr->host, hosts_ptr->mdns ? "mdns" : "static",
- hosts_ptr->online ? "online" : "offline", hosts_ptr->port,
- hosts_ptr->badcount);
- else
- write_log(stdout, " -> %s (%s, %s, port: %d)\n",
- hosts_ptr->host, hosts_ptr->mdns ? "mdns" : "static",
- hosts_ptr->online ? "online" : "offline", hosts_ptr->port);
+ write_log(stdout, " -> %s (%s, %s, port: %d, finds: %d, bad: %d)\n",
+ hosts_ptr->host, hosts_ptr->mdns ? "mdns" : "static",
+ hosts_ptr->online ? "online" : "offline", hosts_ptr->port,
+ hosts_ptr->finds, hosts_ptr->badcount);
hosts_ptr = hosts_ptr->next;
}
diff --git a/pacredir.h b/pacredir.h
index 7423c54..97621d3 100644
--- a/pacredir.h
+++ b/pacredir.h
@@ -47,6 +47,8 @@
/* compile time configuration */
#include "config.h"
#include "version.h"
+#include "html.h"
+#include "favicon.h"
#define DNS_CLASS_IN 1U
#define DNS_TYPE_PTR 12U
@@ -76,6 +78,8 @@ struct hosts {
__time_t badtime;
/* count the number of bad requests */
unsigned int badcount;
+ /* count finds */
+ unsigned int finds;
/* pointer to next struct element */
struct hosts * next;
};
@@ -125,6 +129,10 @@ static int add_host(const char * host, const uint16_t port, const uint8_t mdns);
/* get_http_code */
static void * get_http_code(void * data);
+/* append_string */
+static char * append_string(char * string, const char *format, ...);
+/* status_page */
+static char * status_page(void);
/* ahc_echo */
static enum MHD_Result ahc_echo(void * cls,
struct MHD_Connection * connection,