Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nqptp for openSUSE:Factory checked 
in at 2026-06-04 18:54:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nqptp (Old)
 and      /work/SRC/openSUSE:Factory/.nqptp.new.2375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nqptp"

Thu Jun  4 18:54:56 2026 rev:3 rq:1357027 version:1.2.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/nqptp/nqptp.changes      2024-09-05 
15:48:26.875211250 +0200
+++ /work/SRC/openSUSE:Factory/.nqptp.new.2375/nqptp.changes    2026-06-04 
18:57:04.807723079 +0200
@@ -1,0 +2,19 @@
+Wed Jun  3 18:33:07 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 1.2.8:
+  * The systemd service now runs as a DynamicUser and uses
+    AmbientCapabilities=CAP_NET_BIND_SERVICE to bind ports
+    319/320, so no static user and no setcap on the binary are
+    needed anymore
+  * Improved error messages; ship a nqptp(8) man page
+  * Add FreeBSD and OpenBSD support
+- Drop backported patches (merged upstream):
+  * backport-050a8c2de9f3e1f4859abf9b36d2f18afd4c34d7.patch
+  * backport-b5321a88d21b854aaa461dc0f6c226d650309b91.patch
+- Drop disable-user-group-generation.patch and the nqptp-user.conf
+  sysusers file: upstream no longer creates a static user (it uses
+  systemd DynamicUser), so the sysusers handling is obsolete
+- The service file is now installed to the proper systemd unit
+  directory directly, so the manual relocation is dropped
+
+-------------------------------------------------------------------

Old:
----
  backport-050a8c2de9f3e1f4859abf9b36d2f18afd4c34d7.patch
  backport-b5321a88d21b854aaa461dc0f6c226d650309b91.patch
  disable-user-group-generation.patch
  nqptp-1.2.4.tar.gz
  nqptp-user.conf

New:
----
  nqptp-1.2.8.tar.gz

----------(Old B)----------
  Old:- Drop backported patches (merged upstream):
  * backport-050a8c2de9f3e1f4859abf9b36d2f18afd4c34d7.patch
  * backport-b5321a88d21b854aaa461dc0f6c226d650309b91.patch
  Old:  * backport-050a8c2de9f3e1f4859abf9b36d2f18afd4c34d7.patch
  * backport-b5321a88d21b854aaa461dc0f6c226d650309b91.patch
- Drop disable-user-group-generation.patch and the nqptp-user.conf
  Old:  * backport-b5321a88d21b854aaa461dc0f6c226d650309b91.patch
- Drop disable-user-group-generation.patch and the nqptp-user.conf
  sysusers file: upstream no longer creates a static user (it uses
----------(Old E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nqptp.spec ++++++
--- /var/tmp/diff_new_pack.cS4vAJ/_old  2026-06-04 18:57:05.735761410 +0200
+++ /var/tmp/diff_new_pack.cS4vAJ/_new  2026-06-04 18:57:05.735761410 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package nqptp
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,24 +17,16 @@
 
 
 Name:           nqptp
-Version:        1.2.4
+Version:        1.2.8
 Release:        0
 Summary:        Not Quite PTP
 License:        GPL-2.0-only
 URL:            https://github.com/mikebrady/nqptp
 Source0:        
https://github.com/mikebrady/%{name}/archive/%{version}/%{name}-%{version}.tar.gz
-Source1:        nqptp-user.conf
-# Backported from 1.2.5-dev:
-Patch0:         backport-050a8c2de9f3e1f4859abf9b36d2f18afd4c34d7.patch
-# Backported from 1.2.5-dev:
-Patch1:         backport-b5321a88d21b854aaa461dc0f6c226d650309b91.patch
-Patch2:         disable-user-group-generation.patch
 BuildRequires:  autoconf
 BuildRequires:  automake
 BuildRequires:  systemd-rpm-macros
-BuildRequires:  sysuser-tools
 %{?systemd_ordering}
-%sysusers_requires
 
 %description
 nqptp is a daemon that monitors timing data from any PTP clocks – up to 64 – it
@@ -51,14 +43,9 @@
 autoreconf -i -f
 %configure --with-systemd-startup
 %make_build
-%sysusers_generate_pre %{SOURCE1} nqptp nqptp-user.conf
 
 %install
 %make_install
-mkdir -p %{buildroot}%{_unitdir}
-mv %{buildroot}%{_libdir}/systemd/system/%{name}.service \
-   %{buildroot}%{_unitdir}/%{name}.service
-install -D -m 0644 %{SOURCE1} %{buildroot}%{_sysusersdir}/nqptp.conf
 
 %pre
 %service_add_pre %{name}.service
@@ -76,6 +63,6 @@
 %license LICENSE
 %doc README.md RELEASE_NOTES.md
 %{_bindir}/%{name}
+%{_mandir}/man8/%{name}.8%{?ext_man}
 %{_unitdir}/%{name}.service
-%{_sysusersdir}/nqptp.conf
 

++++++ nqptp-1.2.4.tar.gz -> nqptp-1.2.8.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/.gitignore new/nqptp-1.2.8/.gitignore
--- old/nqptp-1.2.4/.gitignore  2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/.gitignore  2026-05-13 16:33:47.000000000 +0200
@@ -53,6 +53,7 @@
 # Executable
 nqptp
 
-# Version file generated from '$ git describe --dirty'
+# Version files generated from check-gitversion
 gitversion.h
+gitversion-stamp
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/Makefile.am new/nqptp-1.2.8/Makefile.am
--- old/nqptp-1.2.4/Makefile.am 2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/Makefile.am 2026-05-13 16:33:47.000000000 +0200
@@ -1,33 +1,30 @@
 bin_PROGRAMS = nqptp
 nqptp_SOURCES = nqptp.c nqptp-clock-sources.c nqptp-message-handlers.c 
nqptp-utilities.c general-utilities.c debug.c
+man_MANS = nqptp.8
 
 AM_CFLAGS = -fno-common -Wall -Wextra -pthread --include=config.h
-CLEANFILES =
+
 
 if USE_GIT_VERSION
-nqptp.c: gitversion.h
-gitversion.h: .git/index
-       echo "// Do not edit!" > gitversion.h
-       echo "// This file is automatically generated by 'git describe --tags 
--dirty --broken', if available." >> gitversion.h
-       echo -n "  char git_version_string[] = \"" >> gitversion.h
-       git describe --tags --dirty --broken | tr -d '[[:space:]]' >> 
gitversion.h
-       echo "\";" >> gitversion.h
-FORCE: ;
-CLEANFILES += gitversion.h
-endif
+## Check if the git version information has changed and rebuild gitversion.h 
if so
+.PHONY: gitversion-check
+gitversion-check: 
+       $(top_srcdir)/check-gitversion
 
+BUILT_SOURCES = gitversion-check
+CLEANFILES = gitversion-stamp gitversion.h
+endif
 
 install-exec-hook:
 if BUILD_FOR_LINUX
-# NQPTP runs as user/group nqptp/nqptp on Linux and uses setcap to access 
ports 319 and 320
-       setcap 'cap_net_bind_service=+ep' $(bindir)/nqptp
+# Note: 1. NQPTP runs as a dynamic user on systemd-based Linux.
+#       2. Access to ports 319 and 320 is given via AmbientCapabilities in the 
service file.
+# If you want to run NQPTP from the command line, e.g. for debugging, run it 
as root user.
 # no installer for System V
 if INSTALL_SYSTEMD_STARTUP
-       getent group nqptp &>/dev/null || groupadd -r nqptp &>/dev/null
-       getent passwd nqptp &> /dev/null || useradd -r -M -g nqptp -s 
/usr/sbin/nologin nqptp &>/dev/null
-       [ -e $(DESTDIR)$(libdir)/systemd/system ] || mkdir -p 
$(DESTDIR)$(libdir)/systemd/system
+       [ -e $(DESTDIR)$(systemdsystemunitdir) ] || mkdir -p 
$(DESTDIR)$(systemdsystemunitdir)
 # don't replace a service file if it already exists...
-       [ -e $(DESTDIR)$(libdir)/systemd/system/nqptp.service ] || cp 
nqptp.service $(DESTDIR)$(libdir)/systemd/system
+       [ -e $(DESTDIR)$(systemdsystemunitdir)/nqptp.service ] || cp 
nqptp.service $(DESTDIR)$(systemdsystemunitdir)
 endif
 endif
 
@@ -39,4 +36,7 @@
 endif
 endif
 
- 
+if BUILD_FOR_OPENBSD
+# NQPTP starts as root on OpenBSD to access ports 319 and 320
+# and drops privileges to the user shairport is running as.
+endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/README.md new/nqptp-1.2.8/README.md
--- old/nqptp-1.2.4/README.md   2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/README.md   2026-05-13 16:33:47.000000000 +0200
@@ -22,12 +22,13 @@
 ```
 ### Remove Old Service Files
 #### Linux
-If you are updating from version `1.2.4d0` or earlier in Linux, remove the 
service file `nqptp.service` from the directory `/lib/systemd/system` (you'll 
need superuser privileges):
+If you are updating from version `1.2.4` or earlier in Linux, remove the 
service file `nqptp.service` from the directories `/lib/systemd/system` and 
`/usr/local/lib/systemd/system` (you'll need superuser privileges):
 ```
 # rm /lib/systemd/system/nqptp.service
+# rm /usr/local/lib/systemd/system/nqptp.service
 # systemctl daemon-reload
 ```
-Don't worry if you get a message stating that the file doesn't exist -- no 
harm done.
+Don't worry if you get a message stating that the files doesn't exist -- no 
harm done.
 
 #### FreeBSD
 At present, there is no need to remove the old startup script as (in FreeBSD 
only) it is always replaced during the `# make install` step.
@@ -42,6 +43,7 @@
 ```
 $ git clone https://github.com/mikebrady/nqptp.git
 $ cd nqptp
+$ autoreconf -fi # about a minute on a Raspberry Pi.
 $ ./configure --with-systemd-startup
 $ make
 # make install
@@ -108,7 +110,7 @@
 ## Notes
 The `nqptp` application requires exclusive access to ports 319 and 320.
 This means that it can not coexist with any other user of those ports, such as 
full PTP service daemons.
-In Linux, `nqptp` runs as a low-priviliged user but is given special access to 
ports 319 and 320 during installation using the `setcap` utility.
+In Linux, `nqptp` runs as a low-priviliged user but is given special access to 
ports 319 and 320 using systemd `AmbientCapabilities`.
 In FreeBSD, `nqptp` runs as `root` user.
 
 ## Programming Notes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/RELEASE_NOTES.md 
new/nqptp-1.2.8/RELEASE_NOTES.md
--- old/nqptp-1.2.4/RELEASE_NOTES.md    2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/RELEASE_NOTES.md    2026-05-13 16:33:47.000000000 +0200
@@ -1,10 +1,59 @@
+## Version 1.2.8
+* A new `man` file. Thanks again to [Chris Boot](https://github.com/bootc) for 
the [PR](https://github.com/mikebrady/nqptp/pull/48).
+
+## Version 1.2.7
+* With this update, `pkg-config` is used to determine the correct location for 
`systemdsystemunitdir`.
+* Additionally, `--with-systemdsystemunitdir`  `./configure...` option is 
added to allow the location to be over-ridden.
+
+**Note** If you are updating an existing installation, you'll need to delete 
the existing service file as directed in the 
[README](https://github.com/mikebrady/nqptp/blob/main/README.md#remove-old-service-files).
 
+
+Thanks to [Chris Boot](https://github.com/bootc) for the 
[PR](https://github.com/mikebrady/nqptp/pull/46).
+
+## Version 1.2.6 
+* This update should make synchronisation a little better and a little 
smoother.
+
+  **Note** If you are updating an existing installation, you'll need to delete 
the existing service file as directed in the 
[README](https://github.com/mikebrady/nqptp/blob/main/README.md#remove-old-service-files).
 You must also redo the `./configure --with-systemd-startup` step to generate 
the updated `systemd` service file.
+
+## Version: 1.2.5-dev-29-ga93ba70
+* Use a new method to get versioning information from `git describe`. It 
recognises when a repository gets 'dirty' immediately.
+
+## Version: 1.2.5-dev-27-gb59628b
+* Use Linux scheduling to give NQPTP slightly increased priority. This should 
make it more likely that NQPTP will be able to accurately time the arrival of 
timing packets and thus make synchronisation a little smoother. At startup, 
NQPTP will request FIFO scheduling and an associated priority. If it's not 
available, it will just carry on as before. The `systemd` service file has been 
updated to grant NQPTP limited permission to set scheduling and priority.
+  
+## Version: 1.2.5-dev-24-g494ff3f
+* Following a [suggestion](https://github.com/mikebrady/nqptp/issues/33) by 
[Jörn Nettingsmeier](https://github.com/nettings), use the `DynamicUser` 
facility provided by `systemd` to define the system user needed to run the 
NQPTP daemon. Many thanks to them. New installations will use this arrangement.
+  Optionally, if you wish to use it on an existing installation:
+  ```
+  # rm /usr/local/lib/systemd/system/nqptp.service
+  # systemctl daemon-reload
+  ```
+  before building and installing NQPTP.  
+
+## Version: 1.2.5-dev-18-gb8384c4
+* Documentation fix. Thanks to [Rudi Heitbaum](https://github.com/heitbaum) 
for a documentation fix in [PR 34](https://github.com/mikebrady/nqptp/pull/34).
+## Version: 1.2.5-dev-16-g32bfe78
+* OpenBSD compatibility, thanks to the work of [Klemens 
Nanni](https://github.com/klemensn) in [PR 
31](https://github.com/mikebrady/nqptp/pull/31). This work includes: using 
OpenBSD's `pledge(2)` facilities to harden the security of NQPTP, dropping 
priviliges as soon as possible, and running as the same user as the Shairport 
Sync application. (Note that at present on Linux, NQPTP runs as the user 
`nqptp` while Shairport Sync runs as the user `shairport-sync`. For 
consistency, this may change in future.)  
+## Version: 1.2.5-dev-5-g475d7a1
+* Fixup for FreeBSD compilation error -- change the order of some of the 
`#include` files.
+## Version: 1.2.5-dev-2-gb5321a8
+* Stop using `setcap` on the `nqptp` binary at install time and instead use 
systemd's AmbientCapabilities to give the `nqptp` daemon the capability to 
access ports 319 and 320. Many thanks to [Hs_Yeah](https://github.com/Hs-Yeah) 
for the [PR](https://github.com/mikebrady/nqptp/pull/26).
+* Improve some error messages.
+* Update a few documentation errors.
+* Fix some compilation errors on FreeBSD. Thanks to [Emanuel 
Haupt](https://github.com/ehaupt) who also discovered these errors and proposed 
a fix.
+
+When updating NQPTP on Linux, be sure to remove old service files as directed 
in the 
[README](https://github.com/mikebrady/nqptp/blob/main/README.md#remove-old-service-files).
+Note: Shairport Sync must be using Shared Memory Interface Version: `smi10`. 
Check by running:
+```
+$ shairport-sync -V
+```
+
 ## Version: 1.2.4
 This is an important security update. The Shared Memory Interface of the 
updated NQPTP is now 10, i.e. `smi10`:
 ```
 $ nqptp -V
 Version: 1.2.4. Shared Memory Interface Version: smi10.
 ```
-1. When updating NQPTP on Linux, be sure to remove the old service file as 
directed in the 
[README](https://github.com/mikebrady/nqptp/blob/main/README.md#remove-old-service-files).
+1. When updating NQPTP on Linux, be sure to remove old service files as 
directed in the 
[README](https://github.com/mikebrady/nqptp/blob/main/README.md#remove-old-service-files).
 2. You must update Shairport Sync to ensure that it's Shared Memory Interface 
version is also 10 in order to be compatible with this NQPTP update.
 3. Having completed both updates and installations, remember to restart NQPTP 
first and then restart Shairport Sync.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/check-gitversion 
new/nqptp-1.2.8/check-gitversion
--- old/nqptp-1.2.4/check-gitversion    1970-01-01 01:00:00.000000000 +0100
+++ new/nqptp-1.2.8/check-gitversion    2026-05-13 16:33:47.000000000 +0200
@@ -0,0 +1,37 @@
+#! /bin/sh
+# echo "This is the git version checker"
+test -f gitversion-stamp && BGD=`cat gitversion-stamp` || :
+# echo "existing gitversion-stamp is $BGD"
+GD=`git describe --tags --dirty --broken --always 2>/dev/null`
+if [ x"$GD" = x ] ; then
+  GD="NA"
+fi
+# echo "current git description is $GD"
+if [ x"$GD" != x"$BGD" ] ; then
+  echo "build: $GD" # optional -- displays git version if new or different
+  echo $GD > gitversion-stamp
+  echo "// Do not edit!" > gitversion.h
+       echo "// This file is automatically generated." >> gitversion.h
+       echo -n "  char git_version_string[] = \"" >> gitversion.h
+       ## the tr is because we need to remove the trailing newline
+       cat gitversion-stamp | tr -d '[[:space:]]' >> gitversion.h
+       echo "\";" >> gitversion.h
+fi
+
+# Usage. Below is what you would add to Makefile.am. When it runs, the
+# following two files are generated: 'gitversion-stamp' and 'gitversion.h'.
+
+# gitversion-stamp stores the most recently used git description.
+# gitversion.h is a C header file containing that git description as a string.
+
+# Put this script in the top level source folder and make sure it has execute 
permission.
+
+# These are the lines (remove the leading '#' on each) to add to the 
Makefile.am file:
+# ## Check if the git version information has changed and rebuild gitversion.h 
if so.
+# .PHONY: gitversion-check
+# gitversion-check: 
+#      $(top_srcdir)/check-gitversion
+
+# ## You may have to change from += to = below:
+# BUILT_SOURCES += gitversion-check
+# CLEANFILES += gitversion-stamp gitversion.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/configure.ac new/nqptp-1.2.8/configure.ac
--- old/nqptp-1.2.4/configure.ac        2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/configure.ac        2026-05-13 16:33:47.000000000 +0200
@@ -2,12 +2,15 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.68])
-AC_INIT([nqptp], [1.2.4], [[email protected]])
+AC_INIT([nqptp], [1.2.8], [[email protected]])
+: ${CFLAGS="-O3"}
+: ${CXXFLAGS="-O3"}
 AM_INIT_AUTOMAKE
 AC_CANONICAL_HOST
 
 build_linux=no
 build_freebsd=no
+build_openbsd=no
 
 # Detect the target system
 case "${host_os}" in
@@ -16,7 +19,10 @@
         ;;
     freebsd*)
         build_freebsd=yes
-        ;;    
+        ;;
+    openbsd*)
+        build_openbsd=yes
+        ;;
     *)
         AC_MSG_ERROR(["OS $host_os is not supported"])
         ;;
@@ -25,6 +31,7 @@
 # Pass the conditionals to automake
 AM_CONDITIONAL([BUILD_FOR_LINUX], [test "$build_linux" = "yes"])
 AM_CONDITIONAL([BUILD_FOR_FREEBSD], [test "$build_freebsd" = "yes"])
+AM_CONDITIONAL([BUILD_FOR_OPENBSD], [test "$build_openbsd" = "yes"])
 
 if test "x$build_linux" = "xyes" ; then
   AC_DEFINE([CONFIG_FOR_LINUX], 1, [Build for Linux.])
@@ -32,6 +39,9 @@
 if test "x$build_freebsd" = "xyes" ; then
   AC_DEFINE([CONFIG_FOR_FREEBSD], 1, [Build for FreeBSD.])
 fi
+if test "x$build_openbsd" = "xyes" ; then
+  AC_DEFINE([CONFIG_FOR_OPENBSD], 1, [Build for OpenBSD.])
+fi
 
 AC_CHECK_PROGS([GIT], [git])
 if test -n "$GIT" && test -e ".git/index" ; then
@@ -44,10 +54,16 @@
 
AC_ARG_WITH([systemd-startup],[AS_HELP_STRING([--with-systemd-startup],[install 
a systemd startup script during a make install])])
 AM_CONDITIONAL([INSTALL_SYSTEMD_STARTUP], [test "x$with_systemd_startup" = 
"xyes"])
 
-# Check to see if we should include the systemd stuff to define it as a service
+# Check to see if we should include the FreeBSD stuff to define it as a service
 
AC_ARG_WITH([freebsd-startup],[AS_HELP_STRING([--with-freebsd-startup],[install 
a FreeBSD startup script during a make install])])
 AM_CONDITIONAL([INSTALL_FREEBSD_STARTUP], [test "x$with_freebsd_startup" = 
"xyes"])
 
+# Determins where to install the systemd unit when requested
+AC_ARG_WITH([systemdsystemunitdir],
+  [AS_HELP_STRING([--with-systemdsystemunitdir=DIR],
+    [Directory for systemd service files @<:@auto@:>@])],
+  [with_systemdsystemunitdir=$withval],
+  [with_systemdsystemunitdir=auto])
 
 AC_CONFIG_SRCDIR([nqptp.c])
 AC_CONFIG_HEADERS([config.h])
@@ -55,10 +71,14 @@
 # Checks for programs.
 AC_PROG_CC
 AC_PROG_INSTALL
+PKG_PROG_PKG_CONFIG
 
 # Checks for libraries.
 AC_CHECK_LIB([pthread],[pthread_create], , AC_MSG_ERROR(pthread library 
needed))
-AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed for shared 
memory library))
+if test "x$build_openbsd" = "xno" ; then
+  # part of libc
+  AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed for shared 
memory library))
+fi
 
 # Checks for header files.
 AC_CHECK_HEADERS([arpa/inet.h inttypes.h netdb.h stdlib.h string.h 
sys/socket.h unistd.h])
@@ -71,5 +91,19 @@
 AC_FUNC_MALLOC
 AC_CHECK_FUNCS([clock_gettime inet_ntoa memset select socket strerror])
 
+# Configure the systemd unit location
+AS_IF([test "x$with_systemdsystemunitdir" = "xauto"],
+  [AS_IF([test "x$PKG_CONFIG" != "x"],
+    [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir 
systemd 2>/dev/null)],
+    [with_systemdsystemunitdir=])
+  AS_IF([test "x$with_systemdsystemunitdir" = "x"],
+    [with_systemdsystemunitdir='${prefix}/lib/systemd/system'])])
+
+AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+
+AS_IF([test "x$with_systemd_startup" = "xyes"],
+  [AC_MSG_NOTICE([systemd unit directory: $with_systemdsystemunitdir])])
+
+
 AC_CONFIG_FILES([Makefile nqptp.service])
 AC_OUTPUT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/debug.c new/nqptp-1.2.8/debug.c
--- old/nqptp-1.2.4/debug.c     2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/debug.c     2026-05-13 16:33:47.000000000 +0200
@@ -59,6 +59,10 @@
   debugger_show_file_and_line = show_file_and_line;
 }
 
+int debug_level() {
+  return debuglev;
+}
+
 char *generate_preliminary_string(char *buffer, size_t buffer_length, double 
tss, double tsl,
                                   const char *filename, const int linenumber, 
const char *prefix) {
   size_t space_remaining = buffer_length;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/debug.h new/nqptp-1.2.8/debug.h
--- old/nqptp-1.2.4/debug.h     2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/debug.h     2026-05-13 16:33:47.000000000 +0200
@@ -22,6 +22,7 @@
 
 // level 0 is no messages, level 3 is most messages
 void debug_init(int level, int show_elapsed_time, int show_relative_time, int 
show_file_and_line);
+int debug_level(); // get current debug level
 
 void _die(const char *filename, const int linenumber, const char *format, ...);
 void _warn(const char *filename, const int linenumber, const char *format, 
...);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/nqptp-utilities.c 
new/nqptp-1.2.8/nqptp-utilities.c
--- old/nqptp-1.2.4/nqptp-utilities.c   2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/nqptp-utilities.c   2026-05-13 16:33:47.000000000 +0200
@@ -28,12 +28,12 @@
 #include <linux/if_packet.h> // sockaddr_ll
 #endif
 
-#ifdef CONFIG_FOR_FREEBSD
+#if defined(CONFIG_FOR_FREEBSD) || defined(CONFIG_FOR_OPENBSD)
+#include <sys/types.h>
+#include <unistd.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
 #endif
 
 #include <netdb.h>  // getaddrinfo etc.
@@ -105,65 +105,63 @@
   }
   freeaddrinfo(info);
   if (sockets_opened == 0) {
-    if (port < 1024)
-      die("unable to listen on port %d. The error is: \"%s\". NQPTP must run 
as root to access "
-          "this port. Or is another PTP daemon -- possibly another instance on 
NQPTP -- running "
-          "already?",
-          port, strerror(errno));
-    else
-      die("unable to listen on port %d. The error is: \"%s\". "
-          "Is another instance on NQPTP running already?",
-          port, strerror(errno));
+    if (errno == EACCES) {
+      die("nqptp does not have permission to access port %u. It must (a) 
[Linux only] have been given CAP_NET_BIND_SERVICE capabilities using e.g. 
setcap or systemd's AmbientCapabilities, or (b) start as root.", port);
+    } else {
+      die("nqptp is unable to listen on port %u. The error is: %d, \"%s\".", 
port, errno, strerror(errno));
+    }
   }
 }
 
 void debug_print_buffer(int level, char *buf, size_t buf_len) {
-  // printf("Received %u bytes in a packet from %s:%d\n", buf_len, 
inet_ntoa(si_other.sin_addr),
-  // ntohs(si_other.sin_port));
-  char *obf =
-      malloc(buf_len * 4 + 1); // to be on the safe side -- 4 characters on 
average for each byte
-  if (obf != NULL) {
-    char *obfp = obf;
-    unsigned int obfc;
-    for (obfc = 0; obfc < buf_len; obfc++) {
-      snprintf(obfp, 3, "%02X", buf[obfc]);
-      obfp += 2;
-      if (obfc != buf_len - 1) {
-        if (obfc % 32 == 31) {
-          snprintf(obfp, 5, " || ");
-          obfp += 4;
-        } else if (obfc % 16 == 15) {
-          snprintf(obfp, 4, " | ");
-          obfp += 3;
-        } else if (obfc % 4 == 3) {
-          snprintf(obfp, 2, " ");
-          obfp += 1;
+  if (debug_level() >= level) {
+    // printf("Received %u bytes in a packet from %s:%d\n", buf_len, 
inet_ntoa(si_other.sin_addr),
+    // ntohs(si_other.sin_port));
+    char *obf =
+        malloc(buf_len * 4 + 1); // to be on the safe side -- 4 characters on 
average for each byte
+    if (obf != NULL) {
+      char *obfp = obf;
+      unsigned int obfc;
+      for (obfc = 0; obfc < buf_len; obfc++) {
+        snprintf(obfp, 3, "%02X", buf[obfc]);
+        obfp += 2;
+        if (obfc != buf_len - 1) {
+          if (obfc % 32 == 31) {
+            snprintf(obfp, 5, " || ");
+            obfp += 4;
+          } else if (obfc % 16 == 15) {
+            snprintf(obfp, 4, " | ");
+            obfp += 3;
+          } else if (obfc % 4 == 3) {
+            snprintf(obfp, 2, " ");
+            obfp += 1;
+          }
         }
+      };
+      *obfp = 0;
+      switch (buf[0]) {
+  
+      case 0x10:
+        debug(level, "SYNC: \"%s\".", obf);
+        break;
+      case 0x18:
+        debug(level, "FLUP: \"%s\".", obf);
+        break;
+      case 0x19:
+        debug(level, "DRSP: \"%s\".", obf);
+        break;
+      case 0x1B:
+        debug(level, "ANNC: \"%s\".", obf);
+        break;
+      case 0x1C:
+        debug(level, "SGNL: \"%s\".", obf);
+        break;
+      default:
+        debug(1, "XXXX  \"%s\".", obf); // output this at level 1
+        break;
       }
-    };
-    *obfp = 0;
-    switch (buf[0]) {
-
-    case 0x10:
-      debug(level, "SYNC: \"%s\".", obf);
-      break;
-    case 0x18:
-      debug(level, "FLUP: \"%s\".", obf);
-      break;
-    case 0x19:
-      debug(level, "DRSP: \"%s\".", obf);
-      break;
-    case 0x1B:
-      debug(level, "ANNC: \"%s\".", obf);
-      break;
-    case 0x1C:
-      debug(level, "SGNL: \"%s\".", obf);
-      break;
-    default:
-      debug(1, "XXXX  \"%s\".", obf); // output this at level 1
-      break;
+      free(obf);
     }
-    free(obf);
   }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/nqptp.8 new/nqptp-1.2.8/nqptp.8
--- old/nqptp-1.2.4/nqptp.8     1970-01-01 01:00:00.000000000 +0100
+++ new/nqptp-1.2.8/nqptp.8     2026-05-13 16:33:47.000000000 +0200
@@ -0,0 +1,89 @@
+.TH NQPTP 8 "May 7, 2026" "nqptp" "System Manager's Manual"
+.SH NAME
+nqptp \- Not Quite PTP: PTP-based timing daemon for Apple AirPlay 2
+.SH SYNOPSIS
+.B nqptp
+.RB [ \-V ]
+.RB [ \-v | \-vv | \-vvv ]
+.RB [ \-h ]
+.SH DESCRIPTION
+.B nqptp
+is a daemon that monitors timing data from PTP (Precision Time Protocol)
+clocks. It is designed exclusively as a companion daemon to
+.BR shairport-sync (1),
+which uses it to obtain the accurate timing information required for
+AirPlay 2 audio playback.
+.PP
+.B nqptp
+must be running before
+.B shairport-sync
+is started with AirPlay 2 support enabled. It communicates with
+.B shairport-sync
+via a shared memory interface and does not require any configuration
+file.
+.PP
+Under normal operation,
+.B nqptp
+runs silently in the background. It is typically started at boot time
+via a service manager such as
+.BR systemd (1).
+.SH OPTIONS
+.TP
+.B \-V
+Print the version number and exit.
+.TP
+.B \-v
+Enable verbose logging. Basic informational messages about timing
+sources and state changes are written to the system log.
+.TP
+.B \-vv
+Enable more verbose logging. Additional detail about PTP clock
+selection and timing computations is included.
+.TP
+.B \-vvv
+Enable very verbose logging. Full diagnostic output, including
+low-level PTP message handling. Intended for debugging only.
+.TP
+.B \-h
+Print a brief help summary and exit.
+.SH SIGNALS
+.TP
+.B SIGTERM
+Cleanly shut down the daemon, releasing the shared memory interface
+before exiting.
+.TP
+.B SIGINT
+Cleanly shut down the daemon, equivalent to
+.BR SIGTERM .
+.SH FILES
+.TP
+.I /dev/shm/nqptp
+Shared memory segment used to pass timing data to
+.BR shairport-sync (1).
+.SH NOTES
+.B nqptp
+listens on UDP port 319 and 320, the standard PTP event and general
+message ports. It therefore requires either
+.B CAP_NET_BIND_SERVICE
+or root privileges in order to bind these ports. When running under
+.BR systemd (1),
+the provided unit file grants the necessary capability without
+requiring the daemon to run as root.
+.PP
+Only one instance of
+.B nqptp
+should be run at a time on a given host.
+.SH SEE ALSO
+.BR shairport-sync (1),
+.BR ptp4l (8),
+.BR systemd (1)
+.SH BUGS
+Please report bugs at
+.IR https://github.com/mikebrady/nqptp/issues .
+.SH AUTHORS
+.B nqptp
+was written by Mike Brady.
+.PP
+This man page was originally written for the Debian package of
+.BR nqptp
+by Chris Boot <[email protected]>.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/nqptp.c new/nqptp-1.2.8/nqptp.c
--- old/nqptp-1.2.4/nqptp.c     2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/nqptp.c     2026-05-13 16:33:47.000000000 +0200
@@ -48,11 +48,17 @@
 #include <netdb.h>
 #include <sys/socket.h>
 
-#ifdef CONFIG_FOR_FREEBSD
+#if defined(CONFIG_FOR_FREEBSD) || defined(CONFIG_FOR_OPENBSD)
 #include <netinet/in.h>
 #include <sys/socket.h>
 #endif
 
+#ifdef CONFIG_FOR_OPENBSD
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+#endif
+
 #ifndef FIELD_SIZEOF
 #define FIELD_SIZEOF(t, f) (sizeof(((t *)0)->f))
 #endif
@@ -125,6 +131,11 @@
 }
 
 int main(int argc, char **argv) {
+#ifdef CONFIG_FOR_OPENBSD
+  if (pledge("stdio rpath tmppath inet dns id", NULL) == -1) {
+    die("pledge: %s", strerror(errno));
+  }
+#endif
 
   int debug_level = 0;
   int i;
@@ -174,9 +185,22 @@
 
   // debug(1, "size of a clock entry is %u bytes.", 
sizeof(clock_source_private_data));
   atexit(goodbye);
-
+  
+  
+  // try to set a real time scheduling policy with a priority of -6
+  int policy = SCHED_FIFO;
+  struct sched_param param;
+  param.sched_priority = 5;
+  int s = pthread_setschedparam(pthread_self(), policy, &param);
+  if (s != 0)
+    debug(1, "pthread_setschedparam failed:  %d -- \"%s\".", s, strerror(s));
+ 
   sockets_open_stuff.sockets_open = 0;
 
+  // open PTP sockets
+  open_sockets_at_port(NULL, 319, &sockets_open_stuff);
+  open_sockets_at_port(NULL, 320, &sockets_open_stuff);
+
   epoll_fd = -1;
 
   // control-c (SIGINT) cleanly
@@ -191,6 +215,26 @@
   act2.sa_handler = termHandler;
   sigaction(SIGTERM, &act2, NULL);
 
+#ifdef CONFIG_FOR_OPENBSD
+  // shm_open(3) prohibits sharing between different UIDs, so nqptp must run as
+  // the same user shairport-sync does.
+  struct passwd *pw;
+  const char *shairport_user = "_shairport";
+  pw = getpwnam(shairport_user);
+  if (pw == NULL) {
+    die("unknown user %s", shairport_user);
+  }
+  if (setgroups(1, &pw->pw_gid) == -1 ||
+      setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
+      setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) {
+    die("cannot drop privileges to %s", shairport_user);
+  }
+
+  if (pledge("stdio tmppath inet dns", NULL) == -1) {
+    die("pledge: %s", strerror(errno));
+  }
+#endif
+
   // open the SMI
 
   shm_fd = -1;
@@ -198,7 +242,7 @@
   mode_t oldumask = umask(0);
   shm_fd = shm_open(NQPTP_INTERFACE_NAME, O_RDWR | O_CREAT, 0644);
   if (shm_fd == -1) {
-    die("cannot open shared memory \"%s\".", NQPTP_INTERFACE_NAME);
+    die("nqptp cannot open the shared memory \"%s\" for writing. Is another 
copy of nqptp (e.g. an nqptp daemon) running already?", NQPTP_INTERFACE_NAME);
   }
   (void)umask(oldumask);
 
@@ -206,7 +250,7 @@
     die("failed to set size of shared memory \"%s\".", NQPTP_INTERFACE_NAME);
   }
 
-#ifdef CONFIG_FOR_FREEBSD
+#if defined(CONFIG_FOR_FREEBSD) || defined(CONFIG_FOR_OPENBSD)
   shared_memory = (struct shm_structure *)mmap(NULL, sizeof(struct 
shm_structure),
                                                PROT_READ | PROT_WRITE, 
MAP_SHARED, shm_fd, 0);
 #endif
@@ -233,10 +277,7 @@
 
   char buf[BUFLEN];
 
-  // open sockets 319 and 320
-
-  open_sockets_at_port(NULL, 319, &sockets_open_stuff);
-  open_sockets_at_port(NULL, 320, &sockets_open_stuff);
+  // open control socket
   open_sockets_at_port("localhost", NQPTP_CONTROL_PORT,
                        &sockets_open_stuff); // this for messages from the 
client
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nqptp-1.2.4/nqptp.service.in 
new/nqptp-1.2.8/nqptp.service.in
--- old/nqptp-1.2.4/nqptp.service.in    2023-09-16 19:51:55.000000000 +0200
+++ new/nqptp-1.2.8/nqptp.service.in    2026-05-13 16:33:47.000000000 +0200
@@ -6,8 +6,9 @@
 
 [Service]
 ExecStart=@prefix@/bin/nqptp
-User=nqptp
-Group=nqptp
+DynamicUser=yes
+LimitRTPRIO=6
+AmbientCapabilities=CAP_NET_BIND_SERVICE
 
 [Install]
 WantedBy=multi-user.target

Reply via email to