<pre style='margin:0'>
Perry E. Metzger (pmetzger) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/5fe3ba67853eed844655cda80e78a548bc77ff37">https://github.com/macports/macports-ports/commit/5fe3ba67853eed844655cda80e78a548bc77ff37</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 5fe3ba67853 shairport-sync: fix for older systems
</span>5fe3ba67853 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 5fe3ba67853eed844655cda80e78a548bc77ff37
</span>Author: Sergey Fedorov <barracuda@macos-powerpc.org>
AuthorDate: Sun Jun 16 22:26:42 2024 +0800

<span style='display:block; white-space:pre;color:#404040;'>    shairport-sync: fix for older systems
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Closes: https://trac.macports.org/ticket/70148
</span>---
 multimedia/shairport-sync/Portfile                 |  18 +-
 .../0412a84006773098c558ed3f8d4b57b8540244ce.patch |  33 +++
 .../c064b8bae5f1d2816857646382de5ca3a1ab5e15.patch | 311 +++++++++++++++++++++
 3 files changed, 361 insertions(+), 1 deletion(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/multimedia/shairport-sync/Portfile b/multimedia/shairport-sync/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 47f8eddc19b..c060d6fdf21 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/multimedia/shairport-sync/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/multimedia/shairport-sync/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2,9 +2,13 @@
</span> 
 PortSystem          1.0
 PortGroup           github 1.0
<span style='display:block; white-space:pre;background:#e0ffe0;'>+PortGroup           legacysupport 1.1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# _dprintf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+legacysupport.newest_darwin_requires_legacy 10
</span> 
 github.setup        mikebrady shairport-sync 4.3.3
<span style='display:block; white-space:pre;background:#ffe0e0;'>-revision            0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+revision            1
</span> 
 categories          multimedia
 license             MIT BSD ISC
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -34,6 +38,12 @@ depends_lib         path:lib/libssl.dylib:openssl \
</span>                     port:libgcrypt \
                     port:ffmpeg${ffmpeg_ver}
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# Patches from upstream, drop with the next update.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# https://trac.macports.org/ticket/70148
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patch.pre_args-replace -p0 -p1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+patchfiles          c064b8bae5f1d2816857646382de5ca3a1ab5e15.patch \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    0412a84006773098c558ed3f8d4b57b8540244ce.patch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> use_autoreconf      yes
 autoreconf.args     -fvi
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -50,6 +60,12 @@ configure.args      --with-os=darwin \
</span>                     --with-piddir=${prefix}/var \
                     --sysconfdir=${prefix}/etc/shairport-sync
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+# https://github.com/mikebrady/shairport-sync/issues/1860
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${configure.build_arch} in [list ppc ppc64]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    configure.args-delete \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    --with-airplay-2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> variant metadata description {Enable metadata output} {
   configure.args-append --with-metadata
 }
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/multimedia/shairport-sync/files/0412a84006773098c558ed3f8d4b57b8540244ce.patch b/multimedia/shairport-sync/files/0412a84006773098c558ed3f8d4b57b8540244ce.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..93d6601bcc9
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/multimedia/shairport-sync/files/0412a84006773098c558ed3f8d4b57b8540244ce.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,33 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From 0412a84006773098c558ed3f8d4b57b8540244ce Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Mike Brady <4265913+mikebrady@users.noreply.github.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Sat, 15 Jun 2024 16:18:29 +0100
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] BB -- change the order of includes as mentioned in version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 4.3.4-dev-13-gc064b8ba
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ shairport.c | 4 ++--
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 1 file changed, 2 insertions(+), 2 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/shairport.c b/shairport.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 79d5e78f0..7a184ce6c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/shairport.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/shairport.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -25,6 +25,8 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  * OTHER DEALINGS IN THE SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <sys/types.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <fcntl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <getopt.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -35,9 +37,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <popt.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <sys/socket.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <sys/stat.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <sys/types.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <sys/wait.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/multimedia/shairport-sync/files/c064b8bae5f1d2816857646382de5ca3a1ab5e15.patch b/multimedia/shairport-sync/files/c064b8bae5f1d2816857646382de5ca3a1ab5e15.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..d57f5586a2c
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/multimedia/shairport-sync/files/c064b8bae5f1d2816857646382de5ca3a1ab5e15.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,311 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From c064b8bae5f1d2816857646382de5ca3a1ab5e15 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Mike Brady <4265913+mikebrady@users.noreply.github.com>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Sat, 15 Jun 2024 14:31:14 +0100
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] Change order of some include file to facilitiate old Mac OS X
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ builds. Check existence of TCP_KEEPINTVL before trying to use it. Fix a race
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ condition with initial messages to the metadata queues. The race was that the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ queues and mutexes were definied in a thread, so could be delayed to after
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ when the main process was using them.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rtsp.c      | 78 +++++++++++++++++++++++++++++++++--------------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ shairport.c | 17 +++++-------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 2 files changed, 56 insertions(+), 39 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/rtsp.c b/rtsp.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index c1c387922..f997824e9 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/rtsp.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/rtsp.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -430,7 +430,8 @@ int pc_queue_add_item(pc_queue *the_queue, const void *the_stuff, int block) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     } else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       rc = pthread_mutex_lock(&the_queue->pc_queue_lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (rc)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-      debug(1, "Error locking for pc_queue_add_item");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      debug(1, "Error %d (\"%s\") locking for pc_queue_add_item. Block is %d.", rc, strerror(rc),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            block);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pthread_cleanup_push(pc_queue_cleanup_handler, (void *)the_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     // leave this out if you want this to return if the queue is already full
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     // irrespective of the block flag.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1687,7 +1688,7 @@ void handle_get_info(__attribute((unused)) rtsp_conn_info *conn, rtsp_message *r
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               hdr);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     // In Stage 1, look for the DACP and Active-Remote
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     char *ar = msg_get_header(req, "Active-Remote");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (ar) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2101,8 +2102,8 @@ void handle_post(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (strcmp(req->path, "/feedback") == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     resp->respcode = 501;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    debug(1, "Connection %d: Airplay 1. Unhandled POST %s Content-Length %d", conn->connection_number,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-          req->path, req->contentlength);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    debug(1, "Connection %d: Airplay 1. Unhandled POST %s Content-Length %d",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          conn->connection_number, req->path, req->contentlength);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     debug_log_rtsp_message(2, "POST request", req);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3085,7 +3086,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 // iap->ifa_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                 if ((iap->ifa_addr) && (iap->ifa_netmask) && (iap->ifa_flags & IFF_UP) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                     ((iap->ifa_flags & IFF_LOOPBACK) == 0) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-              (config.interface == NULL || (strcmp(config.interface, iap->ifa_name) == 0))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                    (config.interface == NULL || (strcmp(config.interface, iap->ifa_name) == 0))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   char buf[INET6_ADDRSTRLEN + 1]; // +1 for a NUL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   memset(buf, 0, sizeof(buf));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   if (iap->ifa_addr->sa_family == AF_INET6) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4081,13 +4082,9 @@ void metadata_pack_cleanup_function(void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void metadata_thread_cleanup_function(__attribute__((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // debug(2, "metadata_thread_cleanup_function called");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_delete(&metadata_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void *metadata_thread_function(__attribute__((unused)) void *ignore) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // create a pc_queue for passing information to a threaded metadata handler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_init(&metadata_queue, (char *)&metadata_queue_items, sizeof(metadata_package),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                metadata_queue_size, "pipe");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_create_multicast_socket();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_package pack;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   pthread_cleanup_push(metadata_thread_cleanup_function, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4113,13 +4110,9 @@ void *metadata_thread_function(__attribute__((unused)) void *ignore) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void metadata_multicast_thread_cleanup_function(__attribute__((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // debug(2, "metadata_multicast_thread_cleanup_function called");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_delete_multicast_socket();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_delete(&metadata_multicast_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void *metadata_multicast_thread_function(__attribute__((unused)) void *ignore) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // create a pc_queue for passing information to a threaded metadata handler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_init(&metadata_multicast_queue, (char *)&metadata_multicast_queue_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                sizeof(metadata_package), metadata_multicast_queue_size, "multicast");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_create_multicast_socket();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_package pack;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   pthread_cleanup_push(metadata_multicast_thread_cleanup_function, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4154,13 +4147,9 @@ void metadata_hub_close(void) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void metadata_hub_thread_cleanup_function(__attribute__((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // debug(2, "metadata_hub_thread_cleanup_function called");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_hub_close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_delete(&metadata_hub_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void *metadata_hub_thread_function(__attribute__((unused)) void *ignore) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // create a pc_queue for passing information to a threaded metadata handler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_init(&metadata_hub_queue, (char *)&metadata_hub_queue_items, sizeof(metadata_package),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                metadata_hub_queue_size, "hub");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_package pack;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   pthread_cleanup_push(metadata_hub_thread_cleanup_function, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   while (1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4188,14 +4177,10 @@ void metadata_mqtt_close(void) {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void metadata_mqtt_thread_cleanup_function(__attribute__((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // debug(2, "metadata_mqtt_thread_cleanup_function called");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_mqtt_close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_delete(&metadata_mqtt_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // debug(2, "metadata_mqtt_thread_cleanup_function done");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void *metadata_mqtt_thread_function(__attribute__((unused)) void *ignore) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  // create a pc_queue for passing information to a threaded metadata handler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  pc_queue_init(&metadata_mqtt_queue, (char *)&metadata_mqtt_queue_items, sizeof(metadata_package),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-                metadata_mqtt_queue_size, "mqtt");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   metadata_package pack;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   pthread_cleanup_push(metadata_mqtt_thread_cleanup_function, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   while (1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4242,24 +4227,39 @@ void metadata_init(void) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if ((fd == -1) && (errno != ENXIO)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       char errorstring[1024];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       strerror_r(errno, (char *)errorstring, sizeof(errorstring));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-      debug(1, "metadata_hub_thread_function -- error %d (\"%s\") opening pipe: \"%s\".", errno,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++      debug(1, "metadata_init -- error %d (\"%s\") opening pipe: \"%s\".", errno,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             (char *)errorstring, path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       warn("can not open metadata pipe -- error %d (\"%s\") opening pipe: \"%s\".", errno,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            (char *)errorstring, path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     free(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    // initialise the metadata queues first, otherwise the might be a race condition
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    // create a pc_queue for the metadata pipe
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pc_queue_init(&metadata_queue, (char *)&metadata_queue_items, sizeof(metadata_package),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  metadata_queue_size, "pipe");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (pthread_create(&metadata_thread, NULL, metadata_thread_function, NULL) != 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       debug(1, "Failed to create metadata thread!");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    // create a pc_queue for the metadata_multicast_queue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pc_queue_init(&metadata_multicast_queue, (char *)&metadata_multicast_queue_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                  sizeof(metadata_package), metadata_multicast_queue_size, "multicast");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (pthread_create(&metadata_multicast_thread, NULL, metadata_multicast_thread_function,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        NULL) != 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       debug(1, "Failed to create metadata multicast thread!");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef CONFIG_METADATA_HUB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // create a pc_queue for the metadata hub
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  pc_queue_init(&metadata_hub_queue, (char *)&metadata_hub_queue_items, sizeof(metadata_package),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                metadata_hub_queue_size, "hub");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (pthread_create(&metadata_hub_thread, NULL, metadata_hub_thread_function, NULL) != 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     debug(1, "Failed to create metadata hub thread!");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef CONFIG_MQTT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // create a pc_queue for the MQTT handler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  pc_queue_init(&metadata_mqtt_queue, (char *)&metadata_mqtt_queue_items, sizeof(metadata_package),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                metadata_mqtt_queue_size, "mqtt");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (pthread_create(&metadata_mqtt_thread, NULL, metadata_mqtt_thread_function, NULL) != 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     debug(1, "Failed to create metadata mqtt thread!");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4273,6 +4273,7 @@ void metadata_stop(void) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     // debug(2, "metadata stop mqtt thread.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pthread_cancel(metadata_mqtt_thread);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pthread_join(metadata_mqtt_thread, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pc_queue_delete(&metadata_mqtt_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     // debug(2, "metadata stop mqtt done.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef CONFIG_METADATA_HUB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4280,6 +4281,7 @@ void metadata_stop(void) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pthread_cancel(metadata_hub_thread);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pthread_join(metadata_hub_thread, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     // debug(2, "metadata stop hub done.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++    pc_queue_delete(&metadata_hub_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (config.metadata_enabled) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       // debug(2, "metadata stop multicast thread.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4287,12 +4289,14 @@ void metadata_stop(void) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         pthread_cancel(metadata_multicast_thread);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         pthread_join(metadata_multicast_thread, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         // debug(2, "metadata stop multicast done.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        pc_queue_delete(&metadata_multicast_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       if (metadata_thread) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         // debug(2, "metadata stop metadata_thread thread.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         pthread_cancel(metadata_thread);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         pthread_join(metadata_thread, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         // debug(2, "metadata_stop finished successfully.");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        pc_queue_delete(&metadata_queue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -4343,6 +4347,8 @@ int send_metadata_to_queue(pc_queue *queue, uint32_t type, uint32_t code, char *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (data)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       pack.data = memdup(data, length); // only if it's not a null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  // debug(1, "send_metadata_to_queue %x/%x", type, code);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   int rc = pc_queue_add_item(queue, &pack, block);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (rc != 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (pack.carrier) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5642,22 +5648,33 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         size_of_reply = sizeof(SOCKADDR);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         if (getsockname(conn->fd, (struct sockaddr *)&conn->local, &size_of_reply) == 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// skip this stuff in OpenBSD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifndef COMPILE_FOR_OPENBSD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           // Thanks to https://holmeshe.me/network-essentials-setsockopt-SO_KEEPALIVE/ for this.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           // turn on keepalive stuff -- wait for keepidle + (keepcnt * keepinttvl time) seconds
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           // before giving up an ETIMEOUT error is returned if the keepalive check fails
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // if TCP_KEEPINTVL is defined, check a few times before declaring the line dead
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          // otherwise just wait a little while longer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef TCP_KEEPINTVL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           int keepAliveIdleTime = 35; // wait this many seconds before checking for a dropped client
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           int keepAliveCount = 5;     // check this many times
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           int keepAliveInterval = 5;  // wait this many seconds between checks
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++          int keepAliveIdleTime = 60; // wait this many seconds before dropping a client
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// --- the following is a bit  too complicated
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// decide to use IPPROTO_TCP or SOL_TCP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if defined COMPILE_FOR_BSD || defined COMPILE_FOR_OSX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define SOL_OPTION IPPROTO_TCP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define SOL_OPTION SOL_TCP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// decide to use TCP_KEEPALIVE or TCP_KEEPIDLE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef COMPILE_FOR_OSX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define KEEP_ALIVE_OR_IDLE_OPTION TCP_KEEPALIVE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5666,17 +5683,20 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (setsockopt(conn->fd, SOL_OPTION, KEEP_ALIVE_OR_IDLE_OPTION,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                          (void *)&keepAliveIdleTime, sizeof(keepAliveIdleTime))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            debug(1, "can't set the keepidle wait time");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            debug(1, "can't set the keepAliveIdleTime wait time");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// ---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// if TCP_KEEPINTVL is defined...
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef TCP_KEEPINTVL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPCNT, (void *)&keepAliveCount,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                          sizeof(keepAliveCount))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            debug(1, "can't set the keepidle missing count");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            debug(1, "can't set the keepAliveCount count");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           if (setsockopt(conn->fd, SOL_OPTION, TCP_KEEPINTVL, (void *)&keepAliveInterval,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                          sizeof(keepAliveInterval))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-            debug(1, "can't set the keepidle missing count interval");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            debug(1, "can't set the keepAliveCount count interval");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           // initialise the connection info
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -5736,8 +5756,8 @@ void *rtsp_listen_loop(__attribute((unused)) void *arg) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     pthread_cleanup_pop(1); // should never happen
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     die("could not establish a service on port %d -- program terminating. Is another instance of "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-         "Shairport Sync running on this device?",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-         config.port);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        "Shairport Sync running on this device?",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        config.port);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   debug(1, "Oops -- fell out of the RTSP select loop");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   pthread_exit(NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/shairport.c b/shairport.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index cb1e6cb30..79d5e78f0 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/shairport.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/shairport.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1207,8 +1207,8 @@ int parse_options(int argc, char **argv) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       if (config_error_type(&config_file_stuff) == CONFIG_ERR_FILE_IO)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-        die("Error reading configuration file \"%s\": \"%s\".",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-              config_file_real_path, config_error_text(&config_file_stuff));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++        die("Error reading configuration file \"%s\": \"%s\".", config_file_real_path,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++            config_error_text(&config_file_stuff));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+       else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         die("Line %d of the configuration file \"%s\":\n%s", config_error_line(&config_file_stuff),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             config_error_file(&config_file_stuff), config_error_text(&config_file_stuff));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2110,12 +2110,9 @@ int main(int argc, char **argv) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef COMPILE_FOR_OPENBSD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* Any command to be executed at runtime? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-  int run_cmds =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    config.cmd_active_start != NULL ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    config.cmd_active_stop != NULL ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    config.cmd_set_volume != NULL ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    config.cmd_start != NULL ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-    config.cmd_stop != NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++  int run_cmds = config.cmd_active_start != NULL || config.cmd_active_stop != NULL ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                 config.cmd_set_volume != NULL || config.cmd_start != NULL ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++                 config.cmd_stop != NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   // mDNS supports maximum of 63-character names (we append 13).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2381,11 +2378,11 @@ int main(int argc, char **argv) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef COMPILE_FOR_OPENBSD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* Past first and last sio_open(3), sndio(7) only needs "audio". */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# ifdef CONFIG_METADATA
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef CONFIG_METADATA
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   /* Only coverart cache is created.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    * Only metadata pipe is special. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   if (!config.metadata_enabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-# endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+   {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     /* Drop "cpath dpath". */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     if (run_cmds) {
</span></pre><pre style='margin:0'>

</pre>