Architecture specific change in rpms/rust-curl.git
by githook-noreply@fedoraproject.org
The package rpms/rust-curl.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/rust-curl.git/commit/?id=a2b4ccf5....
Change:
-ExclusiveArch: %{rust_arches}
Thanks.
Full change:
============
commit a2b4ccf51d8b1a4e9efb01bead74bd3855cea28b
Author: Fabio Valentini <decathorpe(a)gmail.com>
Date: Thu Mar 2 14:45:22 2023 +0100
Drop unused features for statically linking cURL and OpenSSL
diff --git a/README.md b/README.md
deleted file mode 100644
index 1e85245..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# rust-curl
-
-The rust-curl package
\ No newline at end of file
diff --git a/curl-fix-metadata-auto.diff b/curl-fix-metadata-auto.diff
new file mode 100644
index 0000000..ff2bdba
--- /dev/null
+++ b/curl-fix-metadata-auto.diff
@@ -0,0 +1,19 @@
+--- curl-0.4.44/Cargo.toml 1970-01-01T00:00:01+00:00
++++ curl-0.4.44/Cargo.toml 2023-03-02T13:43:53.758003+00:00
+@@ -107,16 +107,6 @@
+ version = "0.9.43"
+ optional = true
+
+-[target."cfg(target_env = \"msvc\")".dependencies.schannel]
+-version = "0.1.13"
+-
+-[target."cfg(target_env = \"msvc\")".dependencies.winapi]
+-version = "0.3"
+-features = [
+- "libloaderapi",
+- "wincrypt",
+-]
+-
+ [badges.appveyor]
+ repository = "alexcrichton/curl-rust"
+
diff --git a/curl-fix-metadata.diff b/curl-fix-metadata.diff
index e1fea4a..56bc830 100644
--- a/curl-fix-metadata.diff
+++ b/curl-fix-metadata.diff
@@ -1,16 +1,14 @@
--- curl-0.4.44/Cargo.toml 1970-01-01T00:00:01+00:00
-+++ curl-0.4.44/Cargo.toml 2022-07-22T10:26:15.295988+00:00
-@@ -25,6 +25,9 @@
++++ curl-0.4.44/Cargo.toml 2023-03-02T13:44:31.215139+00:00
+@@ -25,6 +25,7 @@
]
license = "MIT"
repository = "https://github.com/alexcrichton/curl-rust"
-+exclude = [
-+ "/ci/",
-+]
++exclude = ["/ci/"]
[[example]]
name = "https"
-@@ -52,10 +55,6 @@
+@@ -52,10 +53,6 @@
name = "multi-dl"
path = "examples/multi-dl.rs"
required-features = ["ssl"]
@@ -21,20 +19,3 @@
[dependencies.curl-sys]
version = "0.4.56"
-@@ -107,16 +106,6 @@
- version = "0.9.43"
- optional = true
-
--[target."cfg(target_env = \"msvc\")".dependencies.schannel]
--version = "0.1.13"
--
--[target."cfg(target_env = \"msvc\")".dependencies.winapi]
--version = "0.3"
--features = [
-- "libloaderapi",
-- "wincrypt",
--]
--
- [badges.appveyor]
- repository = "alexcrichton/curl-rust"
-
diff --git a/rust-curl.spec b/rust-curl.spec
index 2e16c4f..12f4722 100644
--- a/rust-curl.spec
+++ b/rust-curl.spec
@@ -1,25 +1,23 @@
-# Generated by rust2rpm 21
+# Generated by rust2rpm 24
%bcond_without check
%global debug_package %{nil}
%global crate curl
-Name: rust-%{crate}
+Name: rust-curl
Version: 0.4.44
Release: %autorelease
Summary: Rust bindings to libcurl for making HTTP requests
-# Upstream license specification: MIT
License: MIT
URL: https://crates.io/crates/curl
Source: %{crates_source}
-# Initial patched metadata
-# * drop windows- and mac OS-specific dependencies
+# Automatically generated patch to strip foreign dependencies
+Patch: curl-fix-metadata-auto.diff
+# Manually created patch for downstream crate metadata changes
# * drop test binary that requires internet connectivity
# * exclude upstream CI files
-Patch0: curl-fix-metadata.diff
-
-ExclusiveArch: %{rust_arches}
+Patch: curl-fix-metadata.diff
BuildRequires: rust-packaging >= 21
@@ -150,30 +148,6 @@ use the "ssl" feature of the "%{crate}" crate.
%files -n %{name}+ssl-devel
%ghost %{crate_instdir}/Cargo.toml
-%package -n %{name}+static-curl-devel
-Summary: %{summary}
-BuildArch: noarch
-
-%description -n %{name}+static-curl-devel %{_description}
-
-This package contains library source intended for building other packages which
-use the "static-curl" feature of the "%{crate}" crate.
-
-%files -n %{name}+static-curl-devel
-%ghost %{crate_instdir}/Cargo.toml
-
-%package -n %{name}+static-ssl-devel
-Summary: %{summary}
-BuildArch: noarch
-
-%description -n %{name}+static-ssl-devel %{_description}
-
-This package contains library source intended for building other packages which
-use the "static-ssl" feature of the "%{crate}" crate.
-
-%files -n %{name}+static-ssl-devel
-%ghost %{crate_instdir}/Cargo.toml
-
%package -n %{name}+upkeep_7_62_0-devel
Summary: %{summary}
BuildArch: noarch
diff --git a/.rust2rpm.conf b/rust2rpm.conf
similarity index 77%
rename from .rust2rpm.conf
rename to rust2rpm.conf
index 9ffb0a3..7633176 100644
--- a/.rust2rpm.conf
+++ b/rust2rpm.conf
@@ -3,4 +3,6 @@ unwanted-features =
force-system-lib-on-osx
mesalink
rustls
+ static-curl
+ static-ssl
zlib-ng-compat
commit b3e18e10847b17d441f80618c3eadc8f4cc7506d
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Fri Jan 20 22:20:23 2023 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng(a)fedoraproject.org>
1 year, 2 months
Architecture specific change in rpms/rust-curl.git
by githook-noreply@fedoraproject.org
The package rpms/rust-curl.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/rust-curl.git/commit/?id=a2b4ccf5....
Change:
-ExclusiveArch: %{rust_arches}
Thanks.
Full change:
============
commit a2b4ccf51d8b1a4e9efb01bead74bd3855cea28b
Author: Fabio Valentini <decathorpe(a)gmail.com>
Date: Thu Mar 2 14:45:22 2023 +0100
Drop unused features for statically linking cURL and OpenSSL
diff --git a/README.md b/README.md
deleted file mode 100644
index 1e85245..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# rust-curl
-
-The rust-curl package
\ No newline at end of file
diff --git a/curl-fix-metadata-auto.diff b/curl-fix-metadata-auto.diff
new file mode 100644
index 0000000..ff2bdba
--- /dev/null
+++ b/curl-fix-metadata-auto.diff
@@ -0,0 +1,19 @@
+--- curl-0.4.44/Cargo.toml 1970-01-01T00:00:01+00:00
++++ curl-0.4.44/Cargo.toml 2023-03-02T13:43:53.758003+00:00
+@@ -107,16 +107,6 @@
+ version = "0.9.43"
+ optional = true
+
+-[target."cfg(target_env = \"msvc\")".dependencies.schannel]
+-version = "0.1.13"
+-
+-[target."cfg(target_env = \"msvc\")".dependencies.winapi]
+-version = "0.3"
+-features = [
+- "libloaderapi",
+- "wincrypt",
+-]
+-
+ [badges.appveyor]
+ repository = "alexcrichton/curl-rust"
+
diff --git a/curl-fix-metadata.diff b/curl-fix-metadata.diff
index e1fea4a..56bc830 100644
--- a/curl-fix-metadata.diff
+++ b/curl-fix-metadata.diff
@@ -1,16 +1,14 @@
--- curl-0.4.44/Cargo.toml 1970-01-01T00:00:01+00:00
-+++ curl-0.4.44/Cargo.toml 2022-07-22T10:26:15.295988+00:00
-@@ -25,6 +25,9 @@
++++ curl-0.4.44/Cargo.toml 2023-03-02T13:44:31.215139+00:00
+@@ -25,6 +25,7 @@
]
license = "MIT"
repository = "https://github.com/alexcrichton/curl-rust"
-+exclude = [
-+ "/ci/",
-+]
++exclude = ["/ci/"]
[[example]]
name = "https"
-@@ -52,10 +55,6 @@
+@@ -52,10 +53,6 @@
name = "multi-dl"
path = "examples/multi-dl.rs"
required-features = ["ssl"]
@@ -21,20 +19,3 @@
[dependencies.curl-sys]
version = "0.4.56"
-@@ -107,16 +106,6 @@
- version = "0.9.43"
- optional = true
-
--[target."cfg(target_env = \"msvc\")".dependencies.schannel]
--version = "0.1.13"
--
--[target."cfg(target_env = \"msvc\")".dependencies.winapi]
--version = "0.3"
--features = [
-- "libloaderapi",
-- "wincrypt",
--]
--
- [badges.appveyor]
- repository = "alexcrichton/curl-rust"
-
diff --git a/rust-curl.spec b/rust-curl.spec
index 2e16c4f..12f4722 100644
--- a/rust-curl.spec
+++ b/rust-curl.spec
@@ -1,25 +1,23 @@
-# Generated by rust2rpm 21
+# Generated by rust2rpm 24
%bcond_without check
%global debug_package %{nil}
%global crate curl
-Name: rust-%{crate}
+Name: rust-curl
Version: 0.4.44
Release: %autorelease
Summary: Rust bindings to libcurl for making HTTP requests
-# Upstream license specification: MIT
License: MIT
URL: https://crates.io/crates/curl
Source: %{crates_source}
-# Initial patched metadata
-# * drop windows- and mac OS-specific dependencies
+# Automatically generated patch to strip foreign dependencies
+Patch: curl-fix-metadata-auto.diff
+# Manually created patch for downstream crate metadata changes
# * drop test binary that requires internet connectivity
# * exclude upstream CI files
-Patch0: curl-fix-metadata.diff
-
-ExclusiveArch: %{rust_arches}
+Patch: curl-fix-metadata.diff
BuildRequires: rust-packaging >= 21
@@ -150,30 +148,6 @@ use the "ssl" feature of the "%{crate}" crate.
%files -n %{name}+ssl-devel
%ghost %{crate_instdir}/Cargo.toml
-%package -n %{name}+static-curl-devel
-Summary: %{summary}
-BuildArch: noarch
-
-%description -n %{name}+static-curl-devel %{_description}
-
-This package contains library source intended for building other packages which
-use the "static-curl" feature of the "%{crate}" crate.
-
-%files -n %{name}+static-curl-devel
-%ghost %{crate_instdir}/Cargo.toml
-
-%package -n %{name}+static-ssl-devel
-Summary: %{summary}
-BuildArch: noarch
-
-%description -n %{name}+static-ssl-devel %{_description}
-
-This package contains library source intended for building other packages which
-use the "static-ssl" feature of the "%{crate}" crate.
-
-%files -n %{name}+static-ssl-devel
-%ghost %{crate_instdir}/Cargo.toml
-
%package -n %{name}+upkeep_7_62_0-devel
Summary: %{summary}
BuildArch: noarch
diff --git a/.rust2rpm.conf b/rust2rpm.conf
similarity index 77%
rename from .rust2rpm.conf
rename to rust2rpm.conf
index 9ffb0a3..7633176 100644
--- a/.rust2rpm.conf
+++ b/rust2rpm.conf
@@ -3,4 +3,6 @@ unwanted-features =
force-system-lib-on-osx
mesalink
rustls
+ static-curl
+ static-ssl
zlib-ng-compat
1 year, 2 months
Architecture specific change in rpms/hyperhdr.git
by githook-noreply@fedoraproject.org
The package rpms/hyperhdr.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/hyperhdr.git/commit/?id=ce0173c1f....
Change:
+ExcludeArch: %{ix86}
Thanks.
Full change:
============
commit 2810b275f0163a90bc0b0eabccdbc1a3f80defdc
Author: Vasiliy Glazov <vascom2(a)gmail.com>
Date: Thu Mar 2 16:22:22 2023 +0300
Unbundle mdns.
diff --git a/hyperhdr.spec b/hyperhdr.spec
index d8c4e66..a2cd766 100644
--- a/hyperhdr.spec
+++ b/hyperhdr.spec
@@ -3,10 +3,9 @@ Version: 19.0.0.0
Release: 2%{?dist}
Summary: Ambient lighting
-License: MIT AND LicenseRef-Fedora-Public-Domain AND Apache-2.0 AND BSL-1.0 AND BSD-3-Clause
+License: MIT AND Apache-2.0 AND BSL-1.0 AND BSD-3-Clause
URL: https://github.com/awawa-dev/HyperHDR
Source0: %{url}/archive/refs/tags/v%{version}/%{name}-%{version}.tar.gz
-Source1: https://raw.githubusercontent.com/mjansson/mdns/1.4.2/mdns.h
Patch0: fix.patch
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
@@ -26,12 +25,11 @@ BuildRequires: cmake(flatbuffers)
BuildRequires: flatbuffers-compiler
BuildRequires: systemd-rpm-macros
BuildRequires: desktop-file-utils
+BuildRequires: cmake(mdns)
Requires: hicolor-icon-theme
Requires: %{name}-common
-Provides: bundled(mdns) = 1.4.2
-
%description
Open source ambient lighting implementation for television sets based on the
video and audio streams analysis, using performance improvements especially
@@ -50,11 +48,12 @@ The %{name}-common package contains LUT files for
%autosetup -p1 -n HyperHDR-%{version}
mkdir dependencies/bonjour
-cp %{SOURCE1} dependencies/bonjour/
+ln -svf %{_includedir}/mdns.h ./dependencies/bonjour/mdns.h
sed -i -e 's|file(DOWNLOAD "https://raw.githubusercontent.com/mjansson/mdns/${MJANSSON_MDNS_VERSION}/..."||' \
-e 's|"${CMAKE_SOURCE_DIR}/dependencies/bonjour/mdns.h"||' \
-e 's|STATUS MJANSSON_MDNS_STATUS_H)||' CMakeLists.txt
+%build
%cmake -G Ninja \
-DCMAKE_CXX_STANDARD=17 \
-DUSE_SYSTEM_FLATBUFFERS_LIBS:BOOL=ON \
@@ -63,10 +62,8 @@ sed -i -e 's|file(DOWNLOAD "https://raw.githubusercontent.com/mjansson/mdns/${M
-DBUILD_SHARED_LIBS:BOOL=OFF \
-DPLATFORM=linux
-%build
%cmake_build
-
%install
%cmake_install
mkdir -p %{buildroot}%{_datadir}/%{name}/lut/
diff --git a/mdns.h b/mdns.h
deleted file mode 100644
index 4b3b03d..0000000
--- a/mdns.h
+++ /dev/null
@@ -1,1614 +0,0 @@
-/* mdns.h - mDNS/DNS-SD library - Public Domain - 2017 Mattias Jansson
- *
- * This library provides a cross-platform mDNS and DNS-SD library in C.
- * The implementation is based on RFC 6762 and RFC 6763.
- *
- * The latest source code is always available at
- *
- * https://github.com/mjansson/mdns
- *
- * This library is put in the public domain; you can redistribute it and/or modify it without any
- * restrictions.
- *
- */
-
-#pragma once
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <fcntl.h>
-#ifdef _WIN32
-#include <Winsock2.h>
-#include <Ws2tcpip.h>
-#define strncasecmp _strnicmp
-#else
-#include <unistd.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MDNS_INVALID_POS ((size_t)-1)
-
-#define MDNS_STRING_CONST(s) (s), (sizeof((s)) - 1)
-#define MDNS_STRING_ARGS(s) s.str, s.length
-#define MDNS_STRING_FORMAT(s) (int)((s).length), s.str
-
-#define MDNS_POINTER_OFFSET(p, ofs) ((void*)((char*)(p) + (ptrdiff_t)(ofs)))
-#define MDNS_POINTER_OFFSET_CONST(p, ofs) ((const void*)((const char*)(p) + (ptrdiff_t)(ofs)))
-#define MDNS_POINTER_DIFF(a, b) ((size_t)((const char*)(a) - (const char*)(b)))
-
-#define MDNS_PORT 5353
-#define MDNS_UNICAST_RESPONSE 0x8000U
-#define MDNS_CACHE_FLUSH 0x8000U
-#define MDNS_MAX_SUBSTRINGS 64
-
-enum mdns_record_type {
- MDNS_RECORDTYPE_IGNORE = 0,
- // Address
- MDNS_RECORDTYPE_A = 1,
- // Domain Name pointer
- MDNS_RECORDTYPE_PTR = 12,
- // Arbitrary text string
- MDNS_RECORDTYPE_TXT = 16,
- // IP6 Address [Thomson]
- MDNS_RECORDTYPE_AAAA = 28,
- // Server Selection [RFC2782]
- MDNS_RECORDTYPE_SRV = 33,
- // Any available records
- MDNS_RECORDTYPE_ANY = 255
-};
-
-enum mdns_entry_type {
- MDNS_ENTRYTYPE_QUESTION = 0,
- MDNS_ENTRYTYPE_ANSWER = 1,
- MDNS_ENTRYTYPE_AUTHORITY = 2,
- MDNS_ENTRYTYPE_ADDITIONAL = 3
-};
-
-enum mdns_class { MDNS_CLASS_IN = 1, MDNS_CLASS_ANY = 255 };
-
-typedef enum mdns_record_type mdns_record_type_t;
-typedef enum mdns_entry_type mdns_entry_type_t;
-typedef enum mdns_class mdns_class_t;
-
-typedef int (*mdns_record_callback_fn)(int sock, const struct sockaddr* from, size_t addrlen,
- mdns_entry_type_t entry, uint16_t query_id, uint16_t rtype,
- uint16_t rclass, uint32_t ttl, const void* data, size_t size,
- size_t name_offset, size_t name_length, size_t record_offset,
- size_t record_length, void* user_data);
-
-typedef struct mdns_string_t mdns_string_t;
-typedef struct mdns_string_pair_t mdns_string_pair_t;
-typedef struct mdns_string_table_item_t mdns_string_table_item_t;
-typedef struct mdns_string_table_t mdns_string_table_t;
-typedef struct mdns_record_t mdns_record_t;
-typedef struct mdns_record_srv_t mdns_record_srv_t;
-typedef struct mdns_record_ptr_t mdns_record_ptr_t;
-typedef struct mdns_record_a_t mdns_record_a_t;
-typedef struct mdns_record_aaaa_t mdns_record_aaaa_t;
-typedef struct mdns_record_txt_t mdns_record_txt_t;
-typedef struct mdns_query_t mdns_query_t;
-
-#ifdef _WIN32
-typedef int mdns_size_t;
-typedef int mdns_ssize_t;
-#else
-typedef size_t mdns_size_t;
-typedef ssize_t mdns_ssize_t;
-#endif
-
-struct mdns_string_t {
- const char* str;
- size_t length;
-};
-
-struct mdns_string_pair_t {
- size_t offset;
- size_t length;
- int ref;
-};
-
-struct mdns_string_table_t {
- size_t offset[16];
- size_t count;
- size_t next;
-};
-
-struct mdns_record_srv_t {
- uint16_t priority;
- uint16_t weight;
- uint16_t port;
- mdns_string_t name;
-};
-
-struct mdns_record_ptr_t {
- mdns_string_t name;
-};
-
-struct mdns_record_a_t {
- struct sockaddr_in addr;
-};
-
-struct mdns_record_aaaa_t {
- struct sockaddr_in6 addr;
-};
-
-struct mdns_record_txt_t {
- mdns_string_t key;
- mdns_string_t value;
-};
-
-struct mdns_record_t {
- mdns_string_t name;
- mdns_record_type_t type;
- union mdns_record_data {
- mdns_record_ptr_t ptr;
- mdns_record_srv_t srv;
- mdns_record_a_t a;
- mdns_record_aaaa_t aaaa;
- mdns_record_txt_t txt;
- } data;
- uint16_t rclass;
- uint32_t ttl;
-};
-
-struct mdns_header_t {
- uint16_t query_id;
- uint16_t flags;
- uint16_t questions;
- uint16_t answer_rrs;
- uint16_t authority_rrs;
- uint16_t additional_rrs;
-};
-
-struct mdns_query_t {
- mdns_record_type_t type;
- const char* name;
- size_t length;
-};
-
-// mDNS/DNS-SD public API
-
-//! Open and setup a IPv4 socket for mDNS/DNS-SD. To bind the socket to a specific interface, pass
-//! in the appropriate socket address in saddr, otherwise pass a null pointer for INADDR_ANY. To
-//! send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
-//! random user level ephemeral port. To run discovery service listening for incoming discoveries
-//! and queries, you must set MDNS_PORT as port.
-static inline int
-mdns_socket_open_ipv4(const struct sockaddr_in* saddr);
-
-//! Setup an already opened IPv4 socket for mDNS/DNS-SD. To bind the socket to a specific interface,
-//! pass in the appropriate socket address in saddr, otherwise pass a null pointer for INADDR_ANY.
-//! To send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
-//! random user level ephemeral port. To run discovery service listening for incoming discoveries
-//! and queries, you must set MDNS_PORT as port.
-static inline int
-mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr);
-
-//! Open and setup a IPv6 socket for mDNS/DNS-SD. To bind the socket to a specific interface, pass
-//! in the appropriate socket address in saddr, otherwise pass a null pointer for in6addr_any. To
-//! send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
-//! random user level ephemeral port. To run discovery service listening for incoming discoveries
-//! and queries, you must set MDNS_PORT as port.
-static inline int
-mdns_socket_open_ipv6(const struct sockaddr_in6* saddr);
-
-//! Setup an already opened IPv6 socket for mDNS/DNS-SD. To bind the socket to a specific interface,
-//! pass in the appropriate socket address in saddr, otherwise pass a null pointer for in6addr_any.
-//! To send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
-//! random user level ephemeral port. To run discovery service listening for incoming discoveries
-//! and queries, you must set MDNS_PORT as port.
-static inline int
-mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr);
-
-//! Close a socket opened with mdns_socket_open_ipv4 and mdns_socket_open_ipv6.
-static inline void
-mdns_socket_close(int sock);
-
-//! Listen for incoming multicast DNS-SD and mDNS query requests. The socket should have been opened
-//! on port MDNS_PORT using one of the mdns open or setup socket functions. Buffer must be 32 bit
-//! aligned. Parsing is stopped when callback function returns non-zero. Returns the number of
-//! queries parsed.
-static inline size_t
-mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
- void* user_data);
-
-//! Send a multicast DNS-SD reqeuest on the given socket to discover available services. Returns 0
-//! on success, or <0 if error.
-static inline int
-mdns_discovery_send(int sock);
-
-//! Recieve unicast responses to a DNS-SD sent with mdns_discovery_send. Any data will be piped to
-//! the given callback for parsing. Buffer must be 32 bit aligned. Parsing is stopped when callback
-//! function returns non-zero. Returns the number of responses parsed.
-static inline size_t
-mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
- void* user_data);
-
-//! Send a multicast mDNS query on the given socket for the given service name. The supplied buffer
-//! will be used to build the query packet and must be 32 bit aligned. The query ID can be set to
-//! non-zero to filter responses, however the RFC states that the query ID SHOULD be set to 0 for
-//! multicast queries. The query will request a unicast response if the socket is bound to an
-//! ephemeral port, or a multicast response if the socket is bound to mDNS port 5353. Returns the
-//! used query ID, or <0 if error.
-static inline int
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
- size_t capacity, uint16_t query_id);
-
-//! Send a multicast mDNS query on the given socket for the given service names. The supplied buffer
-//! will be used to build the query packet and must be 32 bit aligned. The query ID can be set to
-//! non-zero to filter responses, however the RFC states that the query ID SHOULD be set to 0 for
-//! multicast queries. Each additional service name query consists of a triplet - a record type
-//! (mdns_record_type_t), a name string pointer (const char*) and a name length (size_t). The list
-//! of variable arguments should be terminated with a record type of 0. The query will request a
-//! unicast response if the socket is bound to an ephemeral port, or a multicast response if the
-//! socket is bound to mDNS port 5353. Returns the used query ID, or <0 if error.
-static inline int
-mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* buffer,
- size_t capacity, uint16_t query_id);
-
-//! Receive unicast responses to a mDNS query sent with mdns_discovery_recv, optionally filtering
-//! out any responses not matching the given query ID. Set the query ID to 0 to parse all responses,
-//! even if it is not matching the query ID set in a specific query. Any data will be piped to the
-//! given callback for parsing. Buffer must be 32 bit aligned. Parsing is stopped when callback
-//! function returns non-zero. Returns the number of responses parsed.
-static inline size_t
-mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
- void* user_data, int query_id);
-
-//! Send a variable unicast mDNS query answer to any question with variable number of records to the
-//! given address. Use the top bit of the query class field (MDNS_UNICAST_RESPONSE) in the query
-//! recieved to determine if the answer should be sent unicast (bit set) or multicast (bit not set).
-//! Buffer must be 32 bit aligned. The record type and name should match the data from the query
-//! recieved. Returns 0 if success, or <0 if error.
-static inline int
-mdns_query_answer_unicast(int sock, const void* address, size_t address_size, void* buffer,
- size_t capacity, uint16_t query_id, mdns_record_type_t record_type,
- const char* name, size_t name_length, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count);
-
-//! Send a variable multicast mDNS query answer to any question with variable number of records. Use
-//! the top bit of the query class field (MDNS_UNICAST_RESPONSE) in the query recieved to determine
-//! if the answer should be sent unicast (bit set) or multicast (bit not set). Buffer must be 32 bit
-//! aligned. Returns 0 if success, or <0 if error.
-static inline int
-mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count);
-
-//! Send a variable multicast mDNS announcement (as an unsolicited answer) with variable number of
-//! records.Buffer must be 32 bit aligned. Returns 0 if success, or <0 if error. Use this on service
-//! startup to announce your instance to the local network.
-static inline int
-mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count);
-
-//! Send a variable multicast mDNS announcement. Use this on service end for removing the resource
-//! from the local network. The records must be identical to the according announcement.
-static inline int
-mdns_goodbye_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count);
-
-// Parse records functions
-
-//! Parse a PTR record, returns the name in the record
-static inline mdns_string_t
-mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity);
-
-//! Parse a SRV record, returns the priority, weight, port and name in the record
-static inline mdns_record_srv_t
-mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity);
-
-//! Parse an A record, returns the IPv4 address in the record
-static inline struct sockaddr_in*
-mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in* addr);
-
-//! Parse an AAAA record, returns the IPv6 address in the record
-static inline struct sockaddr_in6*
-mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in6* addr);
-
-//! Parse a TXT record, returns the number of key=value records parsed and stores the key-value
-//! pairs in the supplied buffer
-static inline size_t
-mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
- mdns_record_txt_t* records, size_t capacity);
-
-// Internal functions
-
-static inline mdns_string_t
-mdns_string_extract(const void* buffer, size_t size, size_t* offset, char* str, size_t capacity);
-
-static inline int
-mdns_string_skip(const void* buffer, size_t size, size_t* offset);
-
-static inline size_t
-mdns_string_find(const char* str, size_t length, char c, size_t offset);
-
-//! Compare if two strings are equal. If the strings are equal it returns >0 and the offset variables are
-//! updated to the end of the corresponding strings. If the strings are not equal it returns 0 and
-//! the offset variables are NOT updated.
-static inline int
-mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs, const void* buffer_rhs,
- size_t size_rhs, size_t* ofs_rhs);
-
-static inline void*
-mdns_string_make(void* buffer, size_t capacity, void* data, const char* name, size_t length,
- mdns_string_table_t* string_table);
-
-static inline size_t
-mdns_string_table_find(mdns_string_table_t* string_table, const void* buffer, size_t capacity,
- const char* str, size_t first_length, size_t total_length);
-
-// Implementations
-
-static inline uint16_t
-mdns_ntohs(const void* data) {
- uint16_t aligned;
- memcpy(&aligned, data, sizeof(uint16_t));
- return ntohs(aligned);
-}
-
-static inline uint32_t
-mdns_ntohl(const void* data) {
- uint32_t aligned;
- memcpy(&aligned, data, sizeof(uint32_t));
- return ntohl(aligned);
-}
-
-static inline void*
-mdns_htons(void* data, uint16_t val) {
- val = htons(val);
- memcpy(data, &val, sizeof(uint16_t));
- return MDNS_POINTER_OFFSET(data, sizeof(uint16_t));
-}
-
-static inline void*
-mdns_htonl(void* data, uint32_t val) {
- val = htonl(val);
- memcpy(data, &val, sizeof(uint32_t));
- return MDNS_POINTER_OFFSET(data, sizeof(uint32_t));
-}
-
-static inline int
-mdns_socket_open_ipv4(const struct sockaddr_in* saddr) {
- int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0)
- return -1;
- if (mdns_socket_setup_ipv4(sock, saddr)) {
- mdns_socket_close(sock);
- return -1;
- }
- return sock;
-}
-
-static inline int
-mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr) {
- unsigned char ttl = 1;
- unsigned char loopback = 1;
- unsigned int reuseaddr = 1;
- struct ip_mreq req;
-
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
-#ifdef SO_REUSEPORT
- setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseaddr, sizeof(reuseaddr));
-#endif
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl));
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback));
-
- memset(&req, 0, sizeof(req));
- req.imr_multiaddr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
- if (saddr)
- req.imr_interface = saddr->sin_addr;
- if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req)))
- return -1;
-
- struct sockaddr_in sock_addr;
- if (!saddr) {
- memset(&sock_addr, 0, sizeof(struct sockaddr_in));
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_addr.s_addr = INADDR_ANY;
-#ifdef __APPLE__
- sock_addr.sin_len = sizeof(struct sockaddr_in);
-#endif
- } else {
- memcpy(&sock_addr, saddr, sizeof(struct sockaddr_in));
- setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&sock_addr.sin_addr,
- sizeof(sock_addr.sin_addr));
-#ifndef _WIN32
- sock_addr.sin_addr.s_addr = INADDR_ANY;
-#endif
- }
-
- if (bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in)))
- return -1;
-
-#ifdef _WIN32
- unsigned long param = 1;
- ioctlsocket(sock, FIONBIO, ¶m);
-#else
- const int flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-#endif
-
- return 0;
-}
-
-static inline int
-mdns_socket_open_ipv6(const struct sockaddr_in6* saddr) {
- int sock = (int)socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0)
- return -1;
- if (mdns_socket_setup_ipv6(sock, saddr)) {
- mdns_socket_close(sock);
- return -1;
- }
- return sock;
-}
-
-static inline int
-mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr) {
- int hops = 1;
- unsigned int loopback = 1;
- unsigned int reuseaddr = 1;
- struct ipv6_mreq req;
-
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
-#ifdef SO_REUSEPORT
- setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseaddr, sizeof(reuseaddr));
-#endif
- setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&hops, sizeof(hops));
- setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback));
-
- memset(&req, 0, sizeof(req));
- req.ipv6mr_multiaddr.s6_addr[0] = 0xFF;
- req.ipv6mr_multiaddr.s6_addr[1] = 0x02;
- req.ipv6mr_multiaddr.s6_addr[15] = 0xFB;
- if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&req, sizeof(req)))
- return -1;
-
- struct sockaddr_in6 sock_addr;
- if (!saddr) {
- memset(&sock_addr, 0, sizeof(struct sockaddr_in6));
- sock_addr.sin6_family = AF_INET6;
- sock_addr.sin6_addr = in6addr_any;
-#ifdef __APPLE__
- sock_addr.sin6_len = sizeof(struct sockaddr_in6);
-#endif
- } else {
- memcpy(&sock_addr, saddr, sizeof(struct sockaddr_in6));
- unsigned int ifindex = 0;
- setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&ifindex, sizeof(ifindex));
-#ifndef _WIN32
- sock_addr.sin6_addr = in6addr_any;
-#endif
- }
-
- if (bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in6)))
- return -1;
-
-#ifdef _WIN32
- unsigned long param = 1;
- ioctlsocket(sock, FIONBIO, ¶m);
-#else
- const int flags = fcntl(sock, F_GETFL, 0);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-#endif
-
- return 0;
-}
-
-static inline void
-mdns_socket_close(int sock) {
-#ifdef _WIN32
- closesocket(sock);
-#else
- close(sock);
-#endif
-}
-
-static inline int
-mdns_is_string_ref(uint8_t val) {
- return (0xC0 == (val & 0xC0));
-}
-
-static inline mdns_string_pair_t
-mdns_get_next_substring(const void* rawdata, size_t size, size_t offset) {
- const uint8_t* buffer = (const uint8_t*)rawdata;
- mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0};
- if (offset >= size)
- return pair;
- if (!buffer[offset]) {
- pair.offset = offset;
- return pair;
- }
- int recursion = 0;
- while (mdns_is_string_ref(buffer[offset])) {
- if (size < offset + 2)
- return pair;
-
- offset = mdns_ntohs(MDNS_POINTER_OFFSET(buffer, offset)) & 0x3fff;
- if (offset >= size)
- return pair;
-
- pair.ref = 1;
- if (++recursion > 16)
- return pair;
- }
-
- size_t length = (size_t)buffer[offset++];
- if (size < offset + length)
- return pair;
-
- pair.offset = offset;
- pair.length = length;
-
- return pair;
-}
-
-static inline int
-mdns_string_skip(const void* buffer, size_t size, size_t* offset) {
- size_t cur = *offset;
- mdns_string_pair_t substr;
- unsigned int counter = 0;
- do {
- substr = mdns_get_next_substring(buffer, size, cur);
- if ((substr.offset == MDNS_INVALID_POS) || (counter++ > MDNS_MAX_SUBSTRINGS))
- return 0;
- if (substr.ref) {
- *offset = cur + 2;
- return 1;
- }
- cur = substr.offset + substr.length;
- } while (substr.length);
-
- *offset = cur + 1;
- return 1;
-}
-
-static inline int
-mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs, const void* buffer_rhs,
- size_t size_rhs, size_t* ofs_rhs) {
- size_t lhs_cur = *ofs_lhs;
- size_t rhs_cur = *ofs_rhs;
- size_t lhs_end = MDNS_INVALID_POS;
- size_t rhs_end = MDNS_INVALID_POS;
- mdns_string_pair_t lhs_substr;
- mdns_string_pair_t rhs_substr;
- unsigned int counter = 0;
- do {
- lhs_substr = mdns_get_next_substring(buffer_lhs, size_lhs, lhs_cur);
- rhs_substr = mdns_get_next_substring(buffer_rhs, size_rhs, rhs_cur);
- if ((lhs_substr.offset == MDNS_INVALID_POS) || (rhs_substr.offset == MDNS_INVALID_POS) ||
- (counter++ > MDNS_MAX_SUBSTRINGS))
- return 0;
- if (lhs_substr.length != rhs_substr.length)
- return 0;
- if (strncasecmp((const char*)MDNS_POINTER_OFFSET_CONST(buffer_rhs, rhs_substr.offset),
- (const char*)MDNS_POINTER_OFFSET_CONST(buffer_lhs, lhs_substr.offset),
- rhs_substr.length))
- return 0;
- if (lhs_substr.ref && (lhs_end == MDNS_INVALID_POS))
- lhs_end = lhs_cur + 2;
- if (rhs_substr.ref && (rhs_end == MDNS_INVALID_POS))
- rhs_end = rhs_cur + 2;
- lhs_cur = lhs_substr.offset + lhs_substr.length;
- rhs_cur = rhs_substr.offset + rhs_substr.length;
- } while (lhs_substr.length);
-
- if (lhs_end == MDNS_INVALID_POS)
- lhs_end = lhs_cur + 1;
- *ofs_lhs = lhs_end;
-
- if (rhs_end == MDNS_INVALID_POS)
- rhs_end = rhs_cur + 1;
- *ofs_rhs = rhs_end;
-
- return 1;
-}
-
-static inline mdns_string_t
-mdns_string_extract(const void* buffer, size_t size, size_t* offset, char* str, size_t capacity) {
- size_t cur = *offset;
- size_t end = MDNS_INVALID_POS;
- mdns_string_pair_t substr;
- mdns_string_t result;
- result.str = str;
- result.length = 0;
- char* dst = str;
- unsigned int counter = 0;
- size_t remain = capacity;
- do {
- substr = mdns_get_next_substring(buffer, size, cur);
- if ((substr.offset == MDNS_INVALID_POS) || (counter++ > MDNS_MAX_SUBSTRINGS))
- return result;
- if (substr.ref && (end == MDNS_INVALID_POS))
- end = cur + 2;
- if (substr.length) {
- size_t to_copy = (substr.length < remain) ? substr.length : remain;
- memcpy(dst, (const char*)buffer + substr.offset, to_copy);
- dst += to_copy;
- remain -= to_copy;
- if (remain) {
- *dst++ = '.';
- --remain;
- }
- }
- cur = substr.offset + substr.length;
- } while (substr.length);
-
- if (end == MDNS_INVALID_POS)
- end = cur + 1;
- *offset = end;
-
- result.length = capacity - remain;
- return result;
-}
-
-static inline size_t
-mdns_string_table_find(mdns_string_table_t* string_table, const void* buffer, size_t capacity,
- const char* str, size_t first_length, size_t total_length) {
- if (!string_table)
- return MDNS_INVALID_POS;
-
- for (size_t istr = 0; istr < string_table->count; ++istr) {
- if (string_table->offset[istr] >= capacity)
- continue;
- size_t offset = 0;
- mdns_string_pair_t sub_string =
- mdns_get_next_substring(buffer, capacity, string_table->offset[istr]);
- if (!sub_string.length || (sub_string.length != first_length))
- continue;
- if (memcmp(str, MDNS_POINTER_OFFSET(buffer, sub_string.offset), sub_string.length))
- continue;
-
- // Initial substring matches, now match all remaining substrings
- offset += first_length + 1;
- while (offset < total_length) {
- size_t dot_pos = mdns_string_find(str, total_length, '.', offset);
- if (dot_pos == MDNS_INVALID_POS)
- dot_pos = total_length;
- size_t current_length = dot_pos - offset;
-
- sub_string =
- mdns_get_next_substring(buffer, capacity, sub_string.offset + sub_string.length);
- if (!sub_string.length || (sub_string.length != current_length))
- break;
- if (memcmp(str + offset, MDNS_POINTER_OFFSET(buffer, sub_string.offset),
- sub_string.length))
- break;
-
- offset = dot_pos + 1;
- }
-
- // Return reference offset if entire string matches
- if (offset >= total_length)
- return string_table->offset[istr];
- }
-
- return MDNS_INVALID_POS;
-}
-
-static inline void
-mdns_string_table_add(mdns_string_table_t* string_table, size_t offset) {
- if (!string_table)
- return;
-
- string_table->offset[string_table->next] = offset;
-
- size_t table_capacity = sizeof(string_table->offset) / sizeof(string_table->offset[0]);
- if (++string_table->count > table_capacity)
- string_table->count = table_capacity;
- if (++string_table->next >= table_capacity)
- string_table->next = 0;
-}
-
-static inline size_t
-mdns_string_find(const char* str, size_t length, char c, size_t offset) {
- const void* found;
- if (offset >= length)
- return MDNS_INVALID_POS;
- found = memchr(str + offset, c, length - offset);
- if (found)
- return (size_t)MDNS_POINTER_DIFF(found, str);
- return MDNS_INVALID_POS;
-}
-
-static inline void*
-mdns_string_make_ref(void* data, size_t capacity, size_t ref_offset) {
- if (capacity < 2)
- return 0;
- return mdns_htons(data, 0xC000 | (uint16_t)ref_offset);
-}
-
-static inline void*
-mdns_string_make(void* buffer, size_t capacity, void* data, const char* name, size_t length,
- mdns_string_table_t* string_table) {
- size_t last_pos = 0;
- size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
- if (name[length - 1] == '.')
- --length;
- while (last_pos < length) {
- size_t pos = mdns_string_find(name, length, '.', last_pos);
- size_t sub_length = ((pos != MDNS_INVALID_POS) ? pos : length) - last_pos;
- size_t total_length = length - last_pos;
-
- size_t ref_offset =
- mdns_string_table_find(string_table, buffer, capacity,
- (char*)MDNS_POINTER_OFFSET(name, last_pos), sub_length,
- total_length);
- if (ref_offset != MDNS_INVALID_POS)
- return mdns_string_make_ref(data, remain, ref_offset);
-
- if (remain <= (sub_length + 1))
- return 0;
-
- *(unsigned char*)data = (unsigned char)sub_length;
- memcpy(MDNS_POINTER_OFFSET(data, 1), name + last_pos, sub_length);
- mdns_string_table_add(string_table, MDNS_POINTER_DIFF(data, buffer));
-
- data = MDNS_POINTER_OFFSET(data, sub_length + 1);
- last_pos = ((pos != MDNS_INVALID_POS) ? pos + 1 : length);
- remain = capacity - MDNS_POINTER_DIFF(data, buffer);
- }
-
- if (!remain)
- return 0;
-
- *(unsigned char*)data = 0;
- return MDNS_POINTER_OFFSET(data, 1);
-}
-
-static inline size_t
-mdns_records_parse(int sock, const struct sockaddr* from, size_t addrlen, const void* buffer,
- size_t size, size_t* offset, mdns_entry_type_t type, uint16_t query_id,
- size_t records, mdns_record_callback_fn callback, void* user_data) {
- size_t parsed = 0;
- for (size_t i = 0; i < records; ++i) {
- size_t name_offset = *offset;
- mdns_string_skip(buffer, size, offset);
- if (((*offset) + 10) > size)
- return parsed;
- size_t name_length = (*offset) - name_offset;
- const uint16_t* data = (const uint16_t*)MDNS_POINTER_OFFSET(buffer, *offset);
-
- uint16_t rtype = mdns_ntohs(data++);
- uint16_t rclass = mdns_ntohs(data++);
- uint32_t ttl = mdns_ntohl(data);
- data += 2;
- uint16_t length = mdns_ntohs(data++);
-
- *offset += 10;
-
- if (length <= (size - (*offset))) {
- ++parsed;
- if (callback &&
- callback(sock, from, addrlen, type, query_id, rtype, rclass, ttl, buffer, size,
- name_offset, name_length, *offset, length, user_data))
- break;
- }
-
- *offset += length;
- }
- return parsed;
-}
-
-static inline int
-mdns_unicast_send(int sock, const void* address, size_t address_size, const void* buffer,
- size_t size) {
- if (sendto(sock, (const char*)buffer, (mdns_size_t)size, 0, (const struct sockaddr*)address,
- (socklen_t)address_size) < 0)
- return -1;
- return 0;
-}
-
-static inline int
-mdns_multicast_send(int sock, const void* buffer, size_t size) {
- struct sockaddr_storage addr_storage;
- struct sockaddr_in addr;
- struct sockaddr_in6 addr6;
- struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
- socklen_t saddrlen = sizeof(struct sockaddr_storage);
- if (getsockname(sock, saddr, &saddrlen))
- return -1;
- if (saddr->sa_family == AF_INET6) {
- memset(&addr6, 0, sizeof(addr6));
- addr6.sin6_family = AF_INET6;
-#ifdef __APPLE__
- addr6.sin6_len = sizeof(addr6);
-#endif
- addr6.sin6_addr.s6_addr[0] = 0xFF;
- addr6.sin6_addr.s6_addr[1] = 0x02;
- addr6.sin6_addr.s6_addr[15] = 0xFB;
- addr6.sin6_port = htons((unsigned short)MDNS_PORT);
- saddr = (struct sockaddr*)&addr6;
- saddrlen = sizeof(addr6);
- } else {
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
-#ifdef __APPLE__
- addr.sin_len = sizeof(addr);
-#endif
- addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
- addr.sin_port = htons((unsigned short)MDNS_PORT);
- saddr = (struct sockaddr*)&addr;
- saddrlen = sizeof(addr);
- }
-
- if (sendto(sock, (const char*)buffer, (mdns_size_t)size, 0, saddr, saddrlen) < 0)
- return -1;
- return 0;
-}
-
-static const uint8_t mdns_services_query[] = {
- // Query ID
- 0x00, 0x00,
- // Flags
- 0x00, 0x00,
- // 1 question
- 0x00, 0x01,
- // No answer, authority or additional RRs
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // _services._dns-sd._udp.local.
- 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', 0x07, '_', 'd', 'n', 's', '-', 's', 'd',
- 0x04, '_', 'u', 'd', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
- // PTR record
- 0x00, MDNS_RECORDTYPE_PTR,
- // QU (unicast response) and class IN
- 0x80, MDNS_CLASS_IN};
-
-static inline int
-mdns_discovery_send(int sock) {
- return mdns_multicast_send(sock, mdns_services_query, sizeof(mdns_services_query));
-}
-
-static inline size_t
-mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
- void* user_data) {
- struct sockaddr_in6 addr;
- struct sockaddr* saddr = (struct sockaddr*)&addr;
- socklen_t addrlen = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
-#ifdef __APPLE__
- saddr->sa_len = sizeof(addr);
-#endif
- mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
- if (ret <= 0)
- return 0;
-
- size_t data_size = (size_t)ret;
- size_t records = 0;
- const uint16_t* data = (uint16_t*)buffer;
-
- uint16_t query_id = mdns_ntohs(data++);
- uint16_t flags = mdns_ntohs(data++);
- uint16_t questions = mdns_ntohs(data++);
- uint16_t answer_rrs = mdns_ntohs(data++);
- uint16_t authority_rrs = mdns_ntohs(data++);
- uint16_t additional_rrs = mdns_ntohs(data++);
-
- // According to RFC 6762 the query ID MUST match the sent query ID (which is 0 in our case)
- if (query_id || (flags != 0x8400))
- return 0; // Not a reply to our question
-
- // It seems some implementations do not fill the correct questions field,
- // so ignore this check for now and only validate answer string
- // if (questions != 1)
- // return 0;
-
- int i;
- for (i = 0; i < questions; ++i) {
- size_t offset = MDNS_POINTER_DIFF(data, buffer);
- size_t verify_offset = 12;
- // Verify it's our question, _services._dns-sd._udp.local.
- if (!mdns_string_equal(buffer, data_size, &offset, mdns_services_query,
- sizeof(mdns_services_query), &verify_offset))
- return 0;
- data = (const uint16_t*)MDNS_POINTER_OFFSET(buffer, offset);
-
- uint16_t rtype = mdns_ntohs(data++);
- uint16_t rclass = mdns_ntohs(data++);
-
- // Make sure we get a reply based on our PTR question for class IN
- if ((rtype != MDNS_RECORDTYPE_PTR) || ((rclass & 0x7FFF) != MDNS_CLASS_IN))
- return 0;
- }
-
- for (i = 0; i < answer_rrs; ++i) {
- size_t offset = MDNS_POINTER_DIFF(data, buffer);
- size_t verify_offset = 12;
- // Verify it's an answer to our question, _services._dns-sd._udp.local.
- size_t name_offset = offset;
- int is_answer = mdns_string_equal(buffer, data_size, &offset, mdns_services_query,
- sizeof(mdns_services_query), &verify_offset);
- if (!is_answer && !mdns_string_skip(buffer, data_size, &offset))
- break;
- size_t name_length = offset - name_offset;
- if ((offset + 10) > data_size)
- return records;
- data = (const uint16_t*)MDNS_POINTER_OFFSET(buffer, offset);
-
- uint16_t rtype = mdns_ntohs(data++);
- uint16_t rclass = mdns_ntohs(data++);
- uint32_t ttl = mdns_ntohl(data);
- data += 2;
- uint16_t length = mdns_ntohs(data++);
- if (length > (data_size - offset))
- return 0;
-
- if (is_answer) {
- ++records;
- offset = MDNS_POINTER_DIFF(data, buffer);
- if (callback &&
- callback(sock, saddr, addrlen, MDNS_ENTRYTYPE_ANSWER, query_id, rtype, rclass, ttl,
- buffer, data_size, name_offset, name_length, offset, length, user_data))
- return records;
- }
- data = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(data, length);
- }
-
- size_t total_records = records;
- size_t offset = MDNS_POINTER_DIFF(data, buffer);
- records =
- mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_AUTHORITY, query_id, authority_rrs, callback, user_data);
- total_records += records;
- if (records != authority_rrs)
- return total_records;
-
- records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ADDITIONAL, query_id, additional_rrs, callback,
- user_data);
- total_records += records;
- if (records != additional_rrs)
- return total_records;
-
- return total_records;
-}
-
-static inline size_t
-mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
- void* user_data) {
- struct sockaddr_in6 addr;
- struct sockaddr* saddr = (struct sockaddr*)&addr;
- socklen_t addrlen = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
-#ifdef __APPLE__
- saddr->sa_len = sizeof(addr);
-#endif
- mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
- if (ret <= 0)
- return 0;
-
- size_t data_size = (size_t)ret;
- const uint16_t* data = (const uint16_t*)buffer;
-
- uint16_t query_id = mdns_ntohs(data++);
- uint16_t flags = mdns_ntohs(data++);
- uint16_t questions = mdns_ntohs(data++);
- uint16_t answer_rrs = mdns_ntohs(data++);
- uint16_t authority_rrs = mdns_ntohs(data++);
- uint16_t additional_rrs = mdns_ntohs(data++);
-
- size_t records;
- size_t total_records = 0;
- for (int iquestion = 0; iquestion < questions; ++iquestion) {
- size_t question_offset = MDNS_POINTER_DIFF(data, buffer);
- size_t offset = question_offset;
- size_t verify_offset = 12;
- int dns_sd = 0;
- if (mdns_string_equal(buffer, data_size, &offset, mdns_services_query,
- sizeof(mdns_services_query), &verify_offset)) {
- dns_sd = 1;
- } else if (!mdns_string_skip(buffer, data_size, &offset)) {
- break;
- }
- size_t length = offset - question_offset;
- data = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(buffer, offset);
-
- uint16_t rtype = mdns_ntohs(data++);
- uint16_t rclass = mdns_ntohs(data++);
- uint16_t class_without_flushbit = rclass & ~MDNS_CACHE_FLUSH;
-
- // Make sure we get a question of class IN or ANY
- if (!((class_without_flushbit == MDNS_CLASS_IN) ||
- (class_without_flushbit == MDNS_CLASS_ANY))) {
- break;
- }
-
- if (dns_sd && flags)
- continue;
-
- ++total_records;
- if (callback && callback(sock, saddr, addrlen, MDNS_ENTRYTYPE_QUESTION, query_id, rtype,
- rclass, 0, buffer, data_size, question_offset, length,
- question_offset, length, user_data))
- return total_records;
- }
-
- size_t offset = MDNS_POINTER_DIFF(data, buffer);
- records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ANSWER, query_id, answer_rrs, callback, user_data);
- total_records += records;
- if (records != answer_rrs)
- return total_records;
-
- records =
- mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_AUTHORITY, query_id, authority_rrs, callback, user_data);
- total_records += records;
- if (records != authority_rrs)
- return total_records;
-
- records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ADDITIONAL, query_id, additional_rrs, callback,
- user_data);
-
- return total_records;
-}
-
-static inline int
-mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
- size_t capacity, uint16_t query_id) {
- mdns_query_t query;
- query.type = type;
- query.name = name;
- query.length = length;
- return mdns_multiquery_send(sock, &query, 1, buffer, capacity, query_id);
-}
-
-static inline int
-mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* buffer, size_t capacity,
- uint16_t query_id) {
- if (!count || (capacity < (sizeof(struct mdns_header_t) + (6 * count))))
- return -1;
-
- // Ask for a unicast response since it's a one-shot query
- uint16_t rclass = MDNS_CLASS_IN | MDNS_UNICAST_RESPONSE;
-
- struct sockaddr_storage addr_storage;
- struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
- socklen_t saddrlen = sizeof(addr_storage);
- if (getsockname(sock, saddr, &saddrlen) == 0) {
- if ((saddr->sa_family == AF_INET) &&
- (ntohs(((struct sockaddr_in*)saddr)->sin_port) == MDNS_PORT))
- rclass &= ~MDNS_UNICAST_RESPONSE;
- else if ((saddr->sa_family == AF_INET6) &&
- (ntohs(((struct sockaddr_in6*)saddr)->sin6_port) == MDNS_PORT))
- rclass &= ~MDNS_UNICAST_RESPONSE;
- }
-
- struct mdns_header_t* header = (struct mdns_header_t*)buffer;
- // Query ID
- header->query_id = htons((unsigned short)query_id);
- // Flags
- header->flags = 0;
- // Questions
- header->questions = htons((unsigned short)count);
- // No answer, authority or additional RRs
- header->answer_rrs = 0;
- header->authority_rrs = 0;
- header->additional_rrs = 0;
- // Fill in questions
- void* data = MDNS_POINTER_OFFSET(buffer, sizeof(struct mdns_header_t));
- for (size_t iq = 0; iq < count; ++iq) {
- // Name string
- data = mdns_string_make(buffer, capacity, data, query[iq].name, query[iq].length, 0);
- if (!data)
- return -1;
- // Record type
- data = mdns_htons(data, query[iq].type);
- //! Optional unicast response based on local port, class IN
- data = mdns_htons(data, rclass);
- }
-
- size_t tosend = MDNS_POINTER_DIFF(data, buffer);
- if (mdns_multicast_send(sock, buffer, (size_t)tosend))
- return -1;
- return query_id;
-}
-
-static inline size_t
-mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
- void* user_data, int only_query_id) {
- struct sockaddr_in6 addr;
- struct sockaddr* saddr = (struct sockaddr*)&addr;
- socklen_t addrlen = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
-#ifdef __APPLE__
- saddr->sa_len = sizeof(addr);
-#endif
- mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
- if (ret <= 0)
- return 0;
-
- size_t data_size = (size_t)ret;
- const uint16_t* data = (const uint16_t*)buffer;
-
- uint16_t query_id = mdns_ntohs(data++);
- uint16_t flags = mdns_ntohs(data++);
- uint16_t questions = mdns_ntohs(data++);
- uint16_t answer_rrs = mdns_ntohs(data++);
- uint16_t authority_rrs = mdns_ntohs(data++);
- uint16_t additional_rrs = mdns_ntohs(data++);
- (void)sizeof(flags);
-
- if ((only_query_id > 0) && (query_id != only_query_id))
- return 0; // Not a reply to the wanted one-shot query
-
- if (questions > 1)
- return 0;
-
- // Skip questions part
- int i;
- for (i = 0; i < questions; ++i) {
- size_t offset = MDNS_POINTER_DIFF(data, buffer);
- if (!mdns_string_skip(buffer, data_size, &offset))
- return 0;
- data = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(buffer, offset);
- // Record type and class not used, skip
- // uint16_t rtype = mdns_ntohs(data++);
- // uint16_t rclass = mdns_ntohs(data++);
- data += 2;
- }
-
- size_t records = 0;
- size_t total_records = 0;
- size_t offset = MDNS_POINTER_DIFF(data, buffer);
- records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ANSWER, query_id, answer_rrs, callback, user_data);
- total_records += records;
- if (records != answer_rrs)
- return total_records;
-
- records =
- mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_AUTHORITY, query_id, authority_rrs, callback, user_data);
- total_records += records;
- if (records != authority_rrs)
- return total_records;
-
- records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
- MDNS_ENTRYTYPE_ADDITIONAL, query_id, additional_rrs, callback,
- user_data);
- total_records += records;
- if (records != additional_rrs)
- return total_records;
-
- return total_records;
-}
-
-static inline void*
-mdns_answer_add_question_unicast(void* buffer, size_t capacity, void* data,
- mdns_record_type_t record_type, const char* name,
- size_t name_length, mdns_string_table_t* string_table) {
- data = mdns_string_make(buffer, capacity, data, name, name_length, string_table);
- if (!data)
- return 0;
- size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
- if (remain < 4)
- return 0;
-
- data = mdns_htons(data, record_type);
- data = mdns_htons(data, MDNS_UNICAST_RESPONSE | MDNS_CLASS_IN);
-
- return data;
-}
-
-static inline void*
-mdns_answer_add_record_header(void* buffer, size_t capacity, void* data, mdns_record_t record,
- mdns_string_table_t* string_table) {
- data = mdns_string_make(buffer, capacity, data, record.name.str, record.name.length, string_table);
- if (!data)
- return 0;
- size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
- if (remain < 10)
- return 0;
-
- data = mdns_htons(data, record.type);
- data = mdns_htons(data, record.rclass);
- data = mdns_htonl(data, record.ttl);
- data = mdns_htons(data, 0); // Length, to be filled later
- return data;
-}
-
-static inline void*
-mdns_answer_add_record(void* buffer, size_t capacity, void* data, mdns_record_t record,
- mdns_string_table_t* string_table) {
- // TXT records will be coalesced into one record later
- if (!data || (record.type == MDNS_RECORDTYPE_TXT))
- return data;
-
- data = mdns_answer_add_record_header(buffer, capacity, data, record, string_table);
- if (!data)
- return 0;
-
- // Pointer to length of record to be filled at end
- void* record_length = MDNS_POINTER_OFFSET(data, -2);
- void* record_data = data;
-
- size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
- switch (record.type) {
- case MDNS_RECORDTYPE_PTR:
- data = mdns_string_make(buffer, capacity, data, record.data.ptr.name.str,
- record.data.ptr.name.length, string_table);
- break;
-
- case MDNS_RECORDTYPE_SRV:
- if (remain <= 6)
- return 0;
- data = mdns_htons(data, record.data.srv.priority);
- data = mdns_htons(data, record.data.srv.weight);
- data = mdns_htons(data, record.data.srv.port);
- data = mdns_string_make(buffer, capacity, data, record.data.srv.name.str,
- record.data.srv.name.length, string_table);
- break;
-
- case MDNS_RECORDTYPE_A:
- if (remain < 4)
- return 0;
- memcpy(data, &record.data.a.addr.sin_addr.s_addr, 4);
- data = MDNS_POINTER_OFFSET(data, 4);
- break;
-
- case MDNS_RECORDTYPE_AAAA:
- if (remain < 16)
- return 0;
- memcpy(data, &record.data.aaaa.addr.sin6_addr, 16); // ipv6 address
- data = MDNS_POINTER_OFFSET(data, 16);
- break;
-
- default:
- break;
- }
-
- if (!data)
- return 0;
-
- // Fill record length
- mdns_htons(record_length, (uint16_t)MDNS_POINTER_DIFF(data, record_data));
- return data;
-}
-
-static inline void
-mdns_record_update_rclass_ttl(mdns_record_t* record, uint16_t rclass, uint32_t ttl) {
- if (!record->rclass)
- record->rclass = rclass;
- if (!record->ttl || !ttl)
- record->ttl = ttl;
- record->rclass &= (uint16_t)(MDNS_CLASS_IN | MDNS_CACHE_FLUSH);
- // Never flush PTR record
- if (record->type == MDNS_RECORDTYPE_PTR)
- record->rclass &= ~(uint16_t)MDNS_CACHE_FLUSH;
-}
-
-static inline void*
-mdns_answer_add_txt_record(void* buffer, size_t capacity, void* data, const mdns_record_t* records,
- size_t record_count, uint16_t rclass, uint32_t ttl,
- mdns_string_table_t* string_table) {
- // Pointer to length of record to be filled at end
- void* record_length = 0;
- void* record_data = 0;
-
- size_t remain = 0;
- for (size_t irec = 0; data && (irec < record_count); ++irec) {
- if (records[irec].type != MDNS_RECORDTYPE_TXT)
- continue;
-
- mdns_record_t record = records[irec];
- mdns_record_update_rclass_ttl(&record, rclass, ttl);
- if (!record_data) {
- data = mdns_answer_add_record_header(buffer, capacity, data, record, string_table);
- if (!data)
- return data;
- record_length = MDNS_POINTER_OFFSET(data, -2);
- record_data = data;
- }
-
- // TXT strings are unlikely to be shared, just make then raw. Also need one byte for
- // termination, thus the <= check
- size_t string_length = record.data.txt.key.length + record.data.txt.value.length + 1;
- if (!data)
- return 0;
- remain = capacity - MDNS_POINTER_DIFF(data, buffer);
- if ((remain <= string_length) || (string_length > 0x3FFF))
- return 0;
-
- unsigned char* strdata = (unsigned char*)data;
- *strdata++ = (unsigned char)string_length;
- memcpy(strdata, record.data.txt.key.str, record.data.txt.key.length);
- strdata += record.data.txt.key.length;
- *strdata++ = '=';
- memcpy(strdata, record.data.txt.value.str, record.data.txt.value.length);
- strdata += record.data.txt.value.length;
-
- data = strdata;
- }
-
- // Fill record length
- if (record_data)
- mdns_htons(record_length, (uint16_t)MDNS_POINTER_DIFF(data, record_data));
-
- return data;
-}
-
-static inline uint16_t
-mdns_answer_get_record_count(const mdns_record_t* records, size_t record_count) {
- // TXT records will be coalesced into one record
- uint16_t total_count = 0;
- uint16_t txt_record = 0;
- for (size_t irec = 0; irec < record_count; ++irec) {
- if (records[irec].type == MDNS_RECORDTYPE_TXT)
- txt_record = 1;
- else
- ++total_count;
- }
- return total_count + txt_record;
-}
-
-static inline int
-mdns_query_answer_unicast(int sock, const void* address, size_t address_size, void* buffer,
- size_t capacity, uint16_t query_id, mdns_record_type_t record_type,
- const char* name, size_t name_length, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count) {
- if (capacity < (sizeof(struct mdns_header_t) + 32 + 4))
- return -1;
-
- // According to RFC 6762:
- // The cache-flush bit MUST NOT be set in any resource records in a response message
- // sent in legacy unicast responses to UDP ports other than 5353.
- uint16_t rclass = MDNS_CLASS_IN;
- uint32_t ttl = 10;
-
- // Basic answer structure
- struct mdns_header_t* header = (struct mdns_header_t*)buffer;
- header->query_id = htons(query_id);
- header->flags = htons(0x8400);
- header->questions = htons(1);
- header->answer_rrs = htons(1);
- header->authority_rrs = htons(mdns_answer_get_record_count(authority, authority_count));
- header->additional_rrs = htons(mdns_answer_get_record_count(additional, additional_count));
-
- mdns_string_table_t string_table = {{0}, 0, 0};
- void* data = MDNS_POINTER_OFFSET(buffer, sizeof(struct mdns_header_t));
-
- // Fill in question
- data = mdns_answer_add_question_unicast(buffer, capacity, data, record_type, name, name_length,
- &string_table);
-
- // Fill in answer
- answer.rclass = rclass;
- answer.ttl = ttl;
- data = mdns_answer_add_record(buffer, capacity, data, answer, &string_table);
-
- // Fill in authority records
- for (size_t irec = 0; data && (irec < authority_count); ++irec) {
- mdns_record_t record = authority[irec];
- record.rclass = rclass;
- if (!record.ttl)
- record.ttl = ttl;
- data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
- }
- data = mdns_answer_add_txt_record(buffer, capacity, data, authority, authority_count,
- rclass, ttl, &string_table);
-
- // Fill in additional records
- for (size_t irec = 0; data && (irec < additional_count); ++irec) {
- mdns_record_t record = additional[irec];
- record.rclass = rclass;
- if (!record.ttl)
- record.ttl = ttl;
- data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
- }
- data = mdns_answer_add_txt_record(buffer, capacity, data, additional, additional_count,
- rclass, ttl, &string_table);
- if (!data)
- return -1;
-
- size_t tosend = MDNS_POINTER_DIFF(data, buffer);
- return mdns_unicast_send(sock, address, address_size, buffer, tosend);
-}
-
-static inline int
-mdns_answer_multicast_rclass_ttl(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count,
- uint16_t rclass, uint32_t ttl) {
- if (capacity < (sizeof(struct mdns_header_t) + 32 + 4))
- return -1;
-
- // Basic answer structure
- struct mdns_header_t* header = (struct mdns_header_t*)buffer;
- header->query_id = 0;
- header->flags = htons(0x8400);
- header->questions = 0;
- header->answer_rrs = htons(1);
- header->authority_rrs = htons(mdns_answer_get_record_count(authority, authority_count));
- header->additional_rrs = htons(mdns_answer_get_record_count(additional, additional_count));
-
- mdns_string_table_t string_table = {{0}, 0, 0};
- void* data = MDNS_POINTER_OFFSET(buffer, sizeof(struct mdns_header_t));
-
- // Fill in answer
- mdns_record_t record = answer;
- mdns_record_update_rclass_ttl(&record, rclass, ttl);
- data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
-
- // Fill in authority records
- for (size_t irec = 0; data && (irec < authority_count); ++irec) {
- record = authority[irec];
- mdns_record_update_rclass_ttl(&record, rclass, ttl);
- data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
- }
- data = mdns_answer_add_txt_record(buffer, capacity, data, authority, authority_count,
- rclass, ttl, &string_table);
-
- // Fill in additional records
- for (size_t irec = 0; data && (irec < additional_count); ++irec) {
- record = additional[irec];
- mdns_record_update_rclass_ttl(&record, rclass, ttl);
- data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
- }
- data = mdns_answer_add_txt_record(buffer, capacity, data, additional, additional_count,
- rclass, ttl, &string_table);
- if (!data)
- return -1;
-
- size_t tosend = MDNS_POINTER_DIFF(data, buffer);
- return mdns_multicast_send(sock, buffer, tosend);
-}
-
-static inline int
-mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count) {
- return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
- authority_count, additional, additional_count,
- MDNS_CLASS_IN, 60);
-}
-
-static inline int
-mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count) {
- return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
- authority_count, additional, additional_count,
- MDNS_CLASS_IN | MDNS_CACHE_FLUSH, 60);
-}
-
-static inline int
-mdns_goodbye_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
- const mdns_record_t* authority, size_t authority_count,
- const mdns_record_t* additional, size_t additional_count) {
- // Goodbye should have ttl of 0
- return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
- authority_count, additional, additional_count,
- MDNS_CLASS_IN, 0);
-}
-
-static inline mdns_string_t
-mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity) {
- // PTR record is just a string
- if ((size >= offset + length) && (length >= 2))
- return mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
- mdns_string_t empty = {0, 0};
- return empty;
-}
-
-static inline mdns_record_srv_t
-mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
- char* strbuffer, size_t capacity) {
- mdns_record_srv_t srv;
- memset(&srv, 0, sizeof(mdns_record_srv_t));
- // Read the service priority, weight, port number and the discovery name
- // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
- // 2 bytes network-order unsigned priority
- // 2 bytes network-order unsigned weight
- // 2 bytes network-order unsigned port
- // string: discovery (domain) name, minimum 2 bytes when compressed
- if ((size >= offset + length) && (length >= 8)) {
- const uint16_t* recorddata = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(buffer, offset);
- srv.priority = mdns_ntohs(recorddata++);
- srv.weight = mdns_ntohs(recorddata++);
- srv.port = mdns_ntohs(recorddata++);
- offset += 6;
- srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
- }
- return srv;
-}
-
-static inline struct sockaddr_in*
-mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in* addr) {
- memset(addr, 0, sizeof(struct sockaddr_in));
- addr->sin_family = AF_INET;
-#ifdef __APPLE__
- addr->sin_len = sizeof(struct sockaddr_in);
-#endif
- if ((size >= offset + length) && (length == 4))
- memcpy(&addr->sin_addr.s_addr, MDNS_POINTER_OFFSET(buffer, offset), 4);
- return addr;
-}
-
-static inline struct sockaddr_in6*
-mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
- struct sockaddr_in6* addr) {
- memset(addr, 0, sizeof(struct sockaddr_in6));
- addr->sin6_family = AF_INET6;
-#ifdef __APPLE__
- addr->sin6_len = sizeof(struct sockaddr_in6);
-#endif
- if ((size >= offset + length) && (length == 16))
- memcpy(&addr->sin6_addr, MDNS_POINTER_OFFSET(buffer, offset), 16);
- return addr;
-}
-
-static inline size_t
-mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
- mdns_record_txt_t* records, size_t capacity) {
- size_t parsed = 0;
- const char* strdata;
- size_t end = offset + length;
-
- if (size < end)
- end = size;
-
- while ((offset < end) && (parsed < capacity)) {
- strdata = (const char*)MDNS_POINTER_OFFSET(buffer, offset);
- size_t sublength = *(const unsigned char*)strdata;
-
- ++strdata;
- offset += sublength + 1;
-
- size_t separator = 0;
- for (size_t c = 0; c < sublength; ++c) {
- // DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E]
- if ((strdata[c] < 0x20) || (strdata[c] > 0x7E))
- break;
- if (strdata[c] == '=') {
- separator = c;
- break;
- }
- }
-
- if (!separator)
- continue;
-
- if (separator < sublength) {
- records[parsed].key.str = strdata;
- records[parsed].key.length = separator;
- records[parsed].value.str = strdata + separator + 1;
- records[parsed].value.length = sublength - (separator + 1);
- } else {
- records[parsed].key.str = strdata;
- records[parsed].key.length = sublength;
- }
-
- ++parsed;
- }
-
- return parsed;
-}
-
-#ifdef _WIN32
-#undef strncasecmp
-#endif
-
-#ifdef __cplusplus
-}
-#endif
commit ae276b5cf0611c26e8d07e30b1e20c3a26d65fdd
Author: Vasiliy Glazov <vascom2(a)gmail.com>
Date: Thu Mar 2 15:59:15 2023 +0300
Fix require LUT files.
diff --git a/hyperhdr.spec b/hyperhdr.spec
index e959b7c..d8c4e66 100644
--- a/hyperhdr.spec
+++ b/hyperhdr.spec
@@ -28,6 +28,7 @@ BuildRequires: systemd-rpm-macros
BuildRequires: desktop-file-utils
Requires: hicolor-icon-theme
+Requires: %{name}-common
Provides: bundled(mdns) = 1.4.2
commit ce0173c1f4a80326bbd7e6f7d53c6fd97c5e3e36
Author: Vasiliy Glazov <vascom2(a)gmail.com>
Date: Thu Mar 2 15:51:50 2023 +0300
Initial commit.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..db649b2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/hyperhdr-19.0.0.0.tar.gz
diff --git a/fix.patch b/fix.patch
new file mode 100644
index 0000000..2b97587
--- /dev/null
+++ b/fix.patch
@@ -0,0 +1,393 @@
+diff -uNdr HyperHDR-19.0.0.0_orig/cmake/debian/service/hyperhdr.systemd HyperHDR-19.0.0.0_new/cmake/debian/service/hyperhdr.systemd
+--- HyperHDR-19.0.0.0_orig/cmake/debian/service/hyperhdr.systemd 2023-02-12 20:20:03.000000000 +0300
++++ HyperHDR-19.0.0.0_new/cmake/debian/service/hyperhdr.systemd 2023-03-02 10:57:51.400963373 +0300
+@@ -1,15 +1,16 @@
+ [Unit]
+-Description=HyperHdr ambient light systemd service for user %i
++Description=HyperHdr ambient light systemd service
+ After=network.target
+
+ [Service]
+ ExecStart=/usr/bin/hyperhdr
+-WorkingDirectory=/usr/share/hyperhdr/bin
+-User=%i
+ TimeoutStopSec=5
+ KillMode=mixed
+ Restart=on-failure
+ RestartSec=2
++NoNewPrivileges=yes
++ProtectControlGroups=yes
++RestrictNamespaces=yes
+
+ [Install]
+-WantedBy=multi-user.target
++WantedBy=default.target
+diff -uNdr HyperHDR-19.0.0.0_orig/cmake/Dependencies.cmake HyperHDR-19.0.0.0_new/cmake/Dependencies.cmake
+--- HyperHDR-19.0.0.0_orig/cmake/Dependencies.cmake 2023-02-12 20:20:03.000000000 +0300
++++ HyperHDR-19.0.0.0_new/cmake/Dependencies.cmake 2023-03-02 11:12:49.854396460 +0300
+@@ -234,10 +234,10 @@
+ if (LIBSMARTX11)
+ SET(resolved_file ${LIBSMARTX11})
+ get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
++ gp_append_unique(PREREQUISITE_LIBSZ ${resolved_file})
+ message(STATUS "Adding smartX11: ${resolved_file}")
+ get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
++ gp_append_unique(PREREQUISITE_LIBSZ ${file_canonical})
+ message(STATUS "Added smartX11(2): ${file_canonical}")
+ endif()
+
+@@ -250,10 +250,10 @@
+ if (LIBSMARTPIPEWIRE)
+ SET(resolved_file ${LIBSMARTPIPEWIRE})
+ get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
++ gp_append_unique(PREREQUISITE_LIBSZ ${resolved_file})
+ message(STATUS "Adding smartPipewire: ${resolved_file}")
+ get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
++ gp_append_unique(PREREQUISITE_LIBSZ ${file_canonical})
+ message(STATUS "Added smartPipewire(2): ${file_canonical}")
+ endif()
+
+@@ -266,16 +266,16 @@
+ if (LIBSMARTCEC)
+ SET(resolved_file ${LIBSMARTCEC})
+ get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
++ gp_append_unique(PREREQUISITE_LIBSZ ${resolved_file})
+ message(STATUS "Adding CEC: ${resolved_file}")
+ set(resolved_file "${resolved_file}.6")
+ if(EXISTS ${resolved_file})
+ get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
++ gp_append_unique(PREREQUISITE_LIBSZ ${resolved_file})
+ message(STATUS "Adding CEC(2): ${resolved_file}")
+ endif()
+ get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
++ gp_append_unique(PREREQUISITE_LIBSZ ${file_canonical})
+ message(STATUS "Added CEC(3): ${file_canonical}")
+ endif()
+
+@@ -328,143 +328,18 @@
+ message(STATUS "Added CEC support: ${file_canonical}")
+ endif()
+
+- if ( GLD )
+- SET(resolved_file ${GLD})
+- message(STATUS "Adding GLD: ${resolved_file}")
+- get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
+- message(STATUS "Added GLD: ${resolved_file}")
+- set(resolved_file0 "${resolved_file}.0")
+- if(EXISTS ${resolved_file0})
+- message(STATUS "Adding GLD0: ${resolved_file0}")
+- get_filename_component(resolved_file0 ${resolved_file0} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file0})
+- message(STATUS "Added GLD0: ${resolved_file0}")
+- endif()
+- get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
+- message(STATUS "Added GLD: ${file_canonical}")
+- endif()
+-
+-
+- find_library(LIB_XCB
+- NAMES libxcb libxcb.so
+- )
+-
+- if(LIB_XCB)
+- message(STATUS "libXCB found ${LIB_XCB}")
+- SET(resolved_file ${LIB_XCB})
+- message(STATUS "Adding libXCB: ${resolved_file}")
+- get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
+- message(STATUS "Added libXCB: ${resolved_file}")
+- set(resolved_file1 "${resolved_file}.1")
+- if(EXISTS ${resolved_file1})
+- message(STATUS "Adding libXCB1: ${resolved_file1}")
+- get_filename_component(resolved_file1 ${resolved_file1} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file1})
+- message(STATUS "Added libXCB1: ${resolved_file1}")
+- endif()
+- get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
+- message(STATUS "Added: ${file_canonical}")
+- else()
+- message(STATUS "libXCB not found")
+- endif()
+-
+- find_library(LIB_GLX
+- NAMES libGLX libGLX.so
+- )
+-
+- if(LIB_GLX)
+- message(STATUS "libGLX found ${LIB_GLX}")
+- SET(resolved_file ${LIB_GLX})
+- message(STATUS "Adding LIB_GLX: ${resolved_file}")
+- get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
+- message(STATUS "Added LIB_GLX: ${resolved_file}")
+- set(resolved_file0 "${resolved_file}.0")
+- if(EXISTS ${resolved_file0})
+- message(STATUS "Adding LIB_GLX0: ${resolved_file0}")
+- get_filename_component(resolved_file0 ${resolved_file0} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file0})
+- message(STATUS "Added LIB_GLX0: ${resolved_file0}")
+- endif()
+- get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
+- message(STATUS "Added: ${file_canonical}")
+- else()
+- message(STATUS "libGLX not found")
+- endif()
+
+- # Copy Qt plugins to 'share/hyperhdr/lib'
+- if(QT_PLUGINS_DIR)
+- foreach(PLUGIN "platforms" "sqldrivers" "imageformats")
+- if(EXISTS ${QT_PLUGINS_DIR}/${PLUGIN})
+- file(GLOB files "${QT_PLUGINS_DIR}/${PLUGIN}/*")
+- foreach(file ${files})
+- if (NOT CMAKE_CROSSCOMPILING)
+- get_prerequisites(${file} PLUGINS 0 1 "" "")
+- endif()
+-
+- foreach(DEPENDENCY ${PLUGINS})
+- get_filename_component(resolved ${DEPENDENCY} NAME_WE)
+-
+- foreach(myitem ${SYSTEM_LIBS_SKIP})
+- #message(STATUS "Checking ${myitem}")
+- string(FIND ${myitem} ${resolved} _index)
+- if (${_index} GREATER -1)
+- #message(STATUS "${myitem} = ${resolved}")
+- break()
+- endif()
+- endforeach()
+-
+- if (${_index} GREATER -1)
+- #message(STATUS "QT skipped: ${resolved}")
+- continue() # Skip system libraries
+- else()
+- #message(STATUS "QT included: ${resolved}")
+- gp_resolve_item("${file}" "${DEPENDENCY}" "" "" resolved_file)
+- get_filename_component(resolved_file ${resolved_file} ABSOLUTE)
+- gp_append_unique(PREREQUISITE_LIBS ${resolved_file})
+- get_filename_component(file_canonical ${resolved_file} REALPATH)
+- gp_append_unique(PREREQUISITE_LIBS ${file_canonical})
+- #message(STATUS "QT added: ${resolved_file}")
+- endif()
+- endforeach()
+-
+- install(
+- FILES ${file}
+- DESTINATION "share/hyperhdr/lib/${PLUGIN}"
+- COMPONENT "HyperHDR"
+- )
+- endforeach()
+- endif()
+- endforeach()
+- endif(QT_PLUGINS_DIR)
+-
+- # Create a qt.conf file in 'share/hyperhdr/bin' to override hard-coded search paths in Qt plugins
+- file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=../lib/\n")
+- install(
+- FILES "${CMAKE_BINARY_DIR}/qt.conf"
+- DESTINATION "share/hyperhdr/bin"
+- COMPONENT "HyperHDR"
+- )
+-
+- # Copy dependencies to 'share/hyperhdr/lib'
+- foreach(PREREQUISITE_LIB ${PREREQUISITE_LIBS})
+- message("Installing: " ${PREREQUISITE_LIB})
++ # Copy dependencies to ''
++ foreach(PREREQUISITE_LIB ${PREREQUISITE_LIBSZ})
++ message("Installing: " ${PREREQUISITE_LIBZ})
+ install(
+- FILES ${PREREQUISITE_LIB}
+- DESTINATION "share/hyperhdr/lib"
++ PROGRAMS ${PREREQUISITE_LIB}
++ DESTINATION "lib64"
+ COMPONENT "HyperHDR"
+ )
+ endforeach()
+
+- # install LUT
+- install(FILES "${PROJECT_SOURCE_DIR}/resources/lut/lut_lin_tables.tar.xz" DESTINATION "share/hyperhdr/lut" COMPONENT "HyperHDR")
+- install(FILES "${PROJECT_SOURCE_DIR}/LICENSE" DESTINATION "share/hyperhdr" COMPONENT "HyperHDR")
+- install(FILES "${PROJECT_SOURCE_DIR}/3RD_PARTY_LICENSES" DESTINATION "share/hyperhdr" COMPONENT "HyperHDR")
++
+ else()
+ # Run CMake after target was built to run get_prerequisites on ${TARGET_FILE}
+ add_custom_command(
+@@ -504,82 +379,6 @@
+ separate_arguments(DEPENDENCIES WINDOWS_COMMAND ${DEPS})
+ string(REPLACE "\\" "/" DEPENDENCIES "${DEPENDENCIES}")
+
+- # Copy dependencies to 'hyperhdr/lib' or 'hyperhdr'
+- while (DEPENDENCIES)
+- list(GET DEPENDENCIES 0 src)
+- list(GET DEPENDENCIES 1 dst)
+- get_filename_component(dst ${dst} DIRECTORY)
+-
+- if (NOT "${dst}" STREQUAL "")
+- install(
+- FILES ${src}
+- DESTINATION "lib/${dst}"
+- COMPONENT "HyperHDR"
+- )
+- else()
+- install(
+- FILES ${src}
+- DESTINATION "bin"
+- COMPONENT "HyperHDR"
+- )
+- endif()
+-
+- list(REMOVE_AT DEPENDENCIES 0 1)
+- endwhile()
+-
+- # Copy TurboJPEG Libs
+- if (ENABLE_MF)
+- find_file(TurboJPEG_DLL
+- NAMES "turbojpeg.dll" "jpeg62.dll"
+- PATHS "${TURBOJPEG_LIBRARY_DIRS}"
+- NO_DEFAULT_PATH
+- REQUIRED
+- )
+-
+- if(NOT CMAKE_GITHUB_ACTION)
+- get_filename_component(JPEG_RUNTIME_TARGET ${TARGET_FILE} DIRECTORY)
+- execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${TurboJPEG_DLL} ${JPEG_RUNTIME_TARGET})
+- endif()
+-
+- install(
+- FILES ${TurboJPEG_DLL}
+- DESTINATION "bin"
+- COMPONENT "HyperHDR"
+- )
+- endif()
+-
+- # Copy MQTT Libs
+- if (ENABLE_MQTT)
+- set (MQTT_TARGET_LIB_FOLDER ${LIBRARY_OUTPUT_PATH}/${CMAKE_BUILD_TYPE})
+- message(${MQTT_TARGET_LIB_FOLDER})
+- find_file(MQTT_DLL
+- NAMES "qmqtt.dll"
+- PATHS "${MQTT_TARGET_LIB_FOLDER}"
+- NO_DEFAULT_PATH
+- REQUIRED
+- )
+- message(${MQTT_DLL})
+- if(NOT CMAKE_GITHUB_ACTION)
+- get_filename_component(MQTT_RUNTIME_TARGET ${TARGET_FILE} DIRECTORY)
+- execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${MQTT_DLL} ${MQTT_RUNTIME_TARGET})
+- endif()
+-
+- install(
+- FILES ${MQTT_DLL}
+- DESTINATION "bin"
+- COMPONENT "HyperHDR"
+- )
+- endif()
+-
+-
+- # Create a qt.conf file in 'bin' to override hard-coded search paths in Qt plugins
+- file(WRITE "${CMAKE_BINARY_DIR}/qt.conf" "[Paths]\nPlugins=../lib/\n")
+- install(
+- FILES "${CMAKE_BINARY_DIR}/qt.conf"
+- DESTINATION "bin"
+- COMPONENT "HyperHDR"
+- )
+-
+ execute_process(
+ COMMAND ${SEVENZIP_BIN} e ${PROJECT_SOURCE_DIR}/resources/lut/lut_lin_tables.tar.xz -o${CMAKE_CURRENT_BINARY_DIR} -aoa -y
+ RESULT_VARIABLE STATUS
+diff -uNdr HyperHDR-19.0.0.0_orig/cmake/desktop/hyperhdr.desktop HyperHDR-19.0.0.0_new/cmake/desktop/hyperhdr.desktop
+--- HyperHDR-19.0.0.0_orig/cmake/desktop/hyperhdr.desktop 2023-02-12 20:20:03.000000000 +0300
++++ HyperHDR-19.0.0.0_new/cmake/desktop/hyperhdr.desktop 2023-03-02 10:58:29.233908007 +0300
+@@ -2,7 +2,7 @@
+ Name=HyperHDR
+ GenericName=HyperHDR Ambient Lighting
+ Comment=HyperHDR mimics the well known Ambilight from Philips
+-Icon=/usr/share/pixmaps/hyperhdr/hyperhdr_128.png
++Icon=hyperhdr
+ Terminal=false
+ TryExec=hyperhdr
+ Exec=hyperhdr
+diff -uNdr HyperHDR-19.0.0.0_orig/CMakeLists.txt HyperHDR-19.0.0.0_new/CMakeLists.txt
+--- HyperHDR-19.0.0.0_orig/CMakeLists.txt 2023-02-12 20:20:03.000000000 +0300
++++ HyperHDR-19.0.0.0_new/CMakeLists.txt 2023-03-02 10:46:32.032000510 +0300
+@@ -445,14 +445,6 @@
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--disable-new-dtags")
+ endif()
+
+-# setup -rpath to search for shared libs in BINARY/../lib folder
+-if (UNIX AND NOT APPLE)
+- SET(CMAKE_SKIP_BUILD_RPATH FALSE)
+- SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+- SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:$ORIGIN/../lib")
+- SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+-endif ()
+-
+ # find Threads libs
+ find_package(Threads REQUIRED)
+
+diff -uNdr HyperHDR-19.0.0.0_orig/sources/hyperhdr/CMakeLists.txt HyperHDR-19.0.0.0_new/sources/hyperhdr/CMakeLists.txt
+--- HyperHDR-19.0.0.0_orig/sources/hyperhdr/CMakeLists.txt 2023-02-12 20:20:03.000000000 +0300
++++ HyperHDR-19.0.0.0_new/sources/hyperhdr/CMakeLists.txt 2023-03-02 11:03:15.187047845 +0300
+@@ -130,13 +130,13 @@
+ if(APPLE)
+ install ( TARGETS hyperhdr DESTINATION "share/.." COMPONENT "HyperHDR" )
+ elseif(NOT WIN32)
+- install ( TARGETS hyperhdr DESTINATION "share/hyperhdr/bin" COMPONENT "HyperHDR" )
+- install ( DIRECTORY ${CMAKE_SOURCE_DIR}/cmake/debian/service DESTINATION "share/hyperhdr/" COMPONENT "HyperHDR" )
+- install ( FILES ${CMAKE_SOURCE_DIR}/resources/icons/hyperhdr-icon-32px.png DESTINATION "share/hyperhdr/icons" COMPONENT "HyperHDR" )
++ install ( TARGETS hyperhdr DESTINATION "bin" COMPONENT "HyperHDR" )
++ install ( FILES ${CMAKE_SOURCE_DIR}/resources/icons/hyperhdr-icon-32px.png DESTINATION "share/icons/hicolor/32x32/apps" RENAME "hyperhdr.png" COMPONENT "HyperHDR" )
++ install ( FILES ${CMAKE_SOURCE_DIR}/cmake/debian/service/hyperhdr.systemd DESTINATION "lib/systemd/user" RENAME "hyperhdr.service" COMPONENT "HyperHDR" )
+
+ # Desktop file for hyperhdr
+- install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperhdr_128.png DESTINATION "share/hyperhdr/desktop" COMPONENT "HyperHDR" )
+- install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperhdr.desktop DESTINATION "share/hyperhdr/desktop" COMPONENT "HyperHDR" )
++ install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperhdr_128.png DESTINATION "share/icons/hicolor/128x128/apps" RENAME "hyperhdr.png" COMPONENT "HyperHDR" )
++ install ( FILES ${CMAKE_SOURCE_DIR}/cmake/desktop/hyperhdr.desktop DESTINATION "share/applications" COMPONENT "HyperHDR" )
+ else()
+ install ( TARGETS hyperhdr DESTINATION "bin" COMPONENT "HyperHDR" )
+
+@@ -145,12 +145,6 @@
+ include( InstallRequiredSystemLibraries )
+ endif()
+
+-if(CMAKE_HOST_UNIX AND NOT APPLE)
+- install( CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperhdr/bin/hyperhdr\" \"${CMAKE_BINARY_DIR}/symlink_hyperhdr\" )" COMPONENT "HyperHDR" )
+- install( FILES ${CMAKE_BINARY_DIR}/symlink_hyperhdr DESTINATION "bin" RENAME hyperhdr COMPONENT "HyperHDR" )
+- install( CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_hyperhdr )" COMPONENT "HyperHDR" )
+-endif()
+-
+ # Copy dependencies (not for OSX)
+ include(${CMAKE_SOURCE_DIR}/cmake/Dependencies.cmake)
+
+diff -uNdr HyperHDR-19.0.0.0_orig/sources/hyperhdr-remote/CMakeLists.txt HyperHDR-19.0.0.0_new/sources/hyperhdr-remote/CMakeLists.txt
+--- HyperHDR-19.0.0.0_orig/sources/hyperhdr-remote/CMakeLists.txt 2023-02-12 20:20:03.000000000 +0300
++++ HyperHDR-19.0.0.0_new/sources/hyperhdr-remote/CMakeLists.txt 2023-03-02 11:00:37.892120417 +0300
+@@ -44,17 +44,7 @@
+ Qt${Qt_VERSION}::Core
+ Qt${Qt_VERSION}::Network)
+
+-if(NOT WIN32)
+- install ( TARGETS ${PROJECT_NAME} DESTINATION "share/hyperhdr/bin" COMPONENT "HyperHDR_remote" )
+-else()
+- install ( TARGETS ${PROJECT_NAME} DESTINATION "bin" COMPONENT "HyperHDR_remote" )
+-endif()
+-
+-if(CMAKE_HOST_UNIX)
+- install(CODE "EXECUTE_PROCESS(COMMAND ln -sf \"../share/hyperhdr/bin/${PROJECT_NAME}\" \"${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}\" )" COMPONENT "HyperHDR_remote" )
+- install(FILES "${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME}" DESTINATION "bin" RENAME "${PROJECT_NAME}" COMPONENT "HyperHDR_remote" )
+- install(CODE "FILE (REMOVE ${CMAKE_BINARY_DIR}/symlink_${PROJECT_NAME} )" COMPONENT "HyperHDR_remote" )
+-endif(CMAKE_HOST_UNIX)
++install ( TARGETS ${PROJECT_NAME} DESTINATION "bin" COMPONENT "HyperHDR_remote" )
+
+ if(USE_PRECOMPILED_HEADERS AND COMMAND target_precompile_headers)
+ target_precompile_headers(${PROJECT_NAME} REUSE_FROM precompiled_hyperhdr_headers)
diff --git a/hyperhdr.spec b/hyperhdr.spec
new file mode 100644
index 0000000..e959b7c
--- /dev/null
+++ b/hyperhdr.spec
@@ -0,0 +1,102 @@
+Name: hyperhdr
+Version: 19.0.0.0
+Release: 2%{?dist}
+Summary: Ambient lighting
+
+License: MIT AND LicenseRef-Fedora-Public-Domain AND Apache-2.0 AND BSL-1.0 AND BSD-3-Clause
+URL: https://github.com/awawa-dev/HyperHDR
+Source0: %{url}/archive/refs/tags/v%{version}/%{name}-%{version}.tar.gz
+Source1: https://raw.githubusercontent.com/mjansson/mdns/1.4.2/mdns.h
+Patch0: fix.patch
+
+# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
+ExcludeArch: %{ix86}
+
+BuildRequires: gcc-c++
+BuildRequires: ninja-build
+BuildRequires: pkgconfig
+BuildRequires: cmake
+BuildRequires: cmake(Qt6)
+BuildRequires: pkgconfig(libturbojpeg)
+BuildRequires: pkgconfig(alsa)
+BuildRequires: cmake(Qt6SerialPort)
+BuildRequires: pkgconfig(libpipewire-0.3)
+BuildRequires: mbedtls-devel
+BuildRequires: cmake(flatbuffers)
+BuildRequires: flatbuffers-compiler
+BuildRequires: systemd-rpm-macros
+BuildRequires: desktop-file-utils
+
+Requires: hicolor-icon-theme
+
+Provides: bundled(mdns) = 1.4.2
+
+%description
+Open source ambient lighting implementation for television sets based on the
+video and audio streams analysis, using performance improvements especially
+for USB grabbers.
+
+%package common
+Summary: LUT files for %{name}
+Requires: %{name} = %{version}-%{release}
+BuildArch: noarch
+
+%description common
+The %{name}-common package contains LUT files for
+%{name}.
+
+%prep
+%autosetup -p1 -n HyperHDR-%{version}
+
+mkdir dependencies/bonjour
+cp %{SOURCE1} dependencies/bonjour/
+sed -i -e 's|file(DOWNLOAD "https://raw.githubusercontent.com/mjansson/mdns/${MJANSSON_MDNS_VERSION}/..."||' \
+ -e 's|"${CMAKE_SOURCE_DIR}/dependencies/bonjour/mdns.h"||' \
+ -e 's|STATUS MJANSSON_MDNS_STATUS_H)||' CMakeLists.txt
+
+%cmake -G Ninja \
+ -DCMAKE_CXX_STANDARD=17 \
+ -DUSE_SYSTEM_FLATBUFFERS_LIBS:BOOL=ON \
+ -DUSE_SYSTEM_MBEDTLS_LIBS:BOOL=ON \
+ -DENABLE_MQTT:BOOL=OFF \
+ -DBUILD_SHARED_LIBS:BOOL=OFF \
+ -DPLATFORM=linux
+
+%build
+%cmake_build
+
+
+%install
+%cmake_install
+mkdir -p %{buildroot}%{_datadir}/%{name}/lut/
+tar -xf resources/lut/lut_lin_tables.tar.xz -C %{buildroot}%{_datadir}/%{name}/lut/
+
+%check
+desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
+
+%post
+%systemd_user_post %{name}.service
+
+%preun
+%systemd_user_preun %{name}.service
+
+%files
+%license LICENSE
+%doc README.md
+%{_bindir}/%{name}
+%{_bindir}/%{name}-remote
+%{_libdir}/libsmart*.so*
+%{_userunitdir}/%{name}.service
+%{_datadir}/applications/*.desktop
+%{_datadir}/icons/hicolor/*/apps/*.png
+
+%files common
+%{_datadir}/%{name}
+
+%changelog
+* Thu Mar 02 2023 Vasiliy Glazov <vascom2(a)gmail.com> - 19.0.0.0-2
+- Drop i686 builds
+- Add bundled provides
+
+* Tue Feb 28 2023 Vasiliy Glazov <vascom2(a)gmail.com> - 19.0.0.0-1
+- Initial packaging for Fedora
diff --git a/mdns.h b/mdns.h
new file mode 100644
index 0000000..4b3b03d
--- /dev/null
+++ b/mdns.h
@@ -0,0 +1,1614 @@
+/* mdns.h - mDNS/DNS-SD library - Public Domain - 2017 Mattias Jansson
+ *
+ * This library provides a cross-platform mDNS and DNS-SD library in C.
+ * The implementation is based on RFC 6762 and RFC 6763.
+ *
+ * The latest source code is always available at
+ *
+ * https://github.com/mjansson/mdns
+ *
+ * This library is put in the public domain; you can redistribute it and/or modify it without any
+ * restrictions.
+ *
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#ifdef _WIN32
+#include <Winsock2.h>
+#include <Ws2tcpip.h>
+#define strncasecmp _strnicmp
+#else
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MDNS_INVALID_POS ((size_t)-1)
+
+#define MDNS_STRING_CONST(s) (s), (sizeof((s)) - 1)
+#define MDNS_STRING_ARGS(s) s.str, s.length
+#define MDNS_STRING_FORMAT(s) (int)((s).length), s.str
+
+#define MDNS_POINTER_OFFSET(p, ofs) ((void*)((char*)(p) + (ptrdiff_t)(ofs)))
+#define MDNS_POINTER_OFFSET_CONST(p, ofs) ((const void*)((const char*)(p) + (ptrdiff_t)(ofs)))
+#define MDNS_POINTER_DIFF(a, b) ((size_t)((const char*)(a) - (const char*)(b)))
+
+#define MDNS_PORT 5353
+#define MDNS_UNICAST_RESPONSE 0x8000U
+#define MDNS_CACHE_FLUSH 0x8000U
+#define MDNS_MAX_SUBSTRINGS 64
+
+enum mdns_record_type {
+ MDNS_RECORDTYPE_IGNORE = 0,
+ // Address
+ MDNS_RECORDTYPE_A = 1,
+ // Domain Name pointer
+ MDNS_RECORDTYPE_PTR = 12,
+ // Arbitrary text string
+ MDNS_RECORDTYPE_TXT = 16,
+ // IP6 Address [Thomson]
+ MDNS_RECORDTYPE_AAAA = 28,
+ // Server Selection [RFC2782]
+ MDNS_RECORDTYPE_SRV = 33,
+ // Any available records
+ MDNS_RECORDTYPE_ANY = 255
+};
+
+enum mdns_entry_type {
+ MDNS_ENTRYTYPE_QUESTION = 0,
+ MDNS_ENTRYTYPE_ANSWER = 1,
+ MDNS_ENTRYTYPE_AUTHORITY = 2,
+ MDNS_ENTRYTYPE_ADDITIONAL = 3
+};
+
+enum mdns_class { MDNS_CLASS_IN = 1, MDNS_CLASS_ANY = 255 };
+
+typedef enum mdns_record_type mdns_record_type_t;
+typedef enum mdns_entry_type mdns_entry_type_t;
+typedef enum mdns_class mdns_class_t;
+
+typedef int (*mdns_record_callback_fn)(int sock, const struct sockaddr* from, size_t addrlen,
+ mdns_entry_type_t entry, uint16_t query_id, uint16_t rtype,
+ uint16_t rclass, uint32_t ttl, const void* data, size_t size,
+ size_t name_offset, size_t name_length, size_t record_offset,
+ size_t record_length, void* user_data);
+
+typedef struct mdns_string_t mdns_string_t;
+typedef struct mdns_string_pair_t mdns_string_pair_t;
+typedef struct mdns_string_table_item_t mdns_string_table_item_t;
+typedef struct mdns_string_table_t mdns_string_table_t;
+typedef struct mdns_record_t mdns_record_t;
+typedef struct mdns_record_srv_t mdns_record_srv_t;
+typedef struct mdns_record_ptr_t mdns_record_ptr_t;
+typedef struct mdns_record_a_t mdns_record_a_t;
+typedef struct mdns_record_aaaa_t mdns_record_aaaa_t;
+typedef struct mdns_record_txt_t mdns_record_txt_t;
+typedef struct mdns_query_t mdns_query_t;
+
+#ifdef _WIN32
+typedef int mdns_size_t;
+typedef int mdns_ssize_t;
+#else
+typedef size_t mdns_size_t;
+typedef ssize_t mdns_ssize_t;
+#endif
+
+struct mdns_string_t {
+ const char* str;
+ size_t length;
+};
+
+struct mdns_string_pair_t {
+ size_t offset;
+ size_t length;
+ int ref;
+};
+
+struct mdns_string_table_t {
+ size_t offset[16];
+ size_t count;
+ size_t next;
+};
+
+struct mdns_record_srv_t {
+ uint16_t priority;
+ uint16_t weight;
+ uint16_t port;
+ mdns_string_t name;
+};
+
+struct mdns_record_ptr_t {
+ mdns_string_t name;
+};
+
+struct mdns_record_a_t {
+ struct sockaddr_in addr;
+};
+
+struct mdns_record_aaaa_t {
+ struct sockaddr_in6 addr;
+};
+
+struct mdns_record_txt_t {
+ mdns_string_t key;
+ mdns_string_t value;
+};
+
+struct mdns_record_t {
+ mdns_string_t name;
+ mdns_record_type_t type;
+ union mdns_record_data {
+ mdns_record_ptr_t ptr;
+ mdns_record_srv_t srv;
+ mdns_record_a_t a;
+ mdns_record_aaaa_t aaaa;
+ mdns_record_txt_t txt;
+ } data;
+ uint16_t rclass;
+ uint32_t ttl;
+};
+
+struct mdns_header_t {
+ uint16_t query_id;
+ uint16_t flags;
+ uint16_t questions;
+ uint16_t answer_rrs;
+ uint16_t authority_rrs;
+ uint16_t additional_rrs;
+};
+
+struct mdns_query_t {
+ mdns_record_type_t type;
+ const char* name;
+ size_t length;
+};
+
+// mDNS/DNS-SD public API
+
+//! Open and setup a IPv4 socket for mDNS/DNS-SD. To bind the socket to a specific interface, pass
+//! in the appropriate socket address in saddr, otherwise pass a null pointer for INADDR_ANY. To
+//! send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
+//! random user level ephemeral port. To run discovery service listening for incoming discoveries
+//! and queries, you must set MDNS_PORT as port.
+static inline int
+mdns_socket_open_ipv4(const struct sockaddr_in* saddr);
+
+//! Setup an already opened IPv4 socket for mDNS/DNS-SD. To bind the socket to a specific interface,
+//! pass in the appropriate socket address in saddr, otherwise pass a null pointer for INADDR_ANY.
+//! To send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
+//! random user level ephemeral port. To run discovery service listening for incoming discoveries
+//! and queries, you must set MDNS_PORT as port.
+static inline int
+mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr);
+
+//! Open and setup a IPv6 socket for mDNS/DNS-SD. To bind the socket to a specific interface, pass
+//! in the appropriate socket address in saddr, otherwise pass a null pointer for in6addr_any. To
+//! send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
+//! random user level ephemeral port. To run discovery service listening for incoming discoveries
+//! and queries, you must set MDNS_PORT as port.
+static inline int
+mdns_socket_open_ipv6(const struct sockaddr_in6* saddr);
+
+//! Setup an already opened IPv6 socket for mDNS/DNS-SD. To bind the socket to a specific interface,
+//! pass in the appropriate socket address in saddr, otherwise pass a null pointer for in6addr_any.
+//! To send one-shot discovery requests and queries pass a null pointer or set 0 as port to assign a
+//! random user level ephemeral port. To run discovery service listening for incoming discoveries
+//! and queries, you must set MDNS_PORT as port.
+static inline int
+mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr);
+
+//! Close a socket opened with mdns_socket_open_ipv4 and mdns_socket_open_ipv6.
+static inline void
+mdns_socket_close(int sock);
+
+//! Listen for incoming multicast DNS-SD and mDNS query requests. The socket should have been opened
+//! on port MDNS_PORT using one of the mdns open or setup socket functions. Buffer must be 32 bit
+//! aligned. Parsing is stopped when callback function returns non-zero. Returns the number of
+//! queries parsed.
+static inline size_t
+mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
+ void* user_data);
+
+//! Send a multicast DNS-SD reqeuest on the given socket to discover available services. Returns 0
+//! on success, or <0 if error.
+static inline int
+mdns_discovery_send(int sock);
+
+//! Recieve unicast responses to a DNS-SD sent with mdns_discovery_send. Any data will be piped to
+//! the given callback for parsing. Buffer must be 32 bit aligned. Parsing is stopped when callback
+//! function returns non-zero. Returns the number of responses parsed.
+static inline size_t
+mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
+ void* user_data);
+
+//! Send a multicast mDNS query on the given socket for the given service name. The supplied buffer
+//! will be used to build the query packet and must be 32 bit aligned. The query ID can be set to
+//! non-zero to filter responses, however the RFC states that the query ID SHOULD be set to 0 for
+//! multicast queries. The query will request a unicast response if the socket is bound to an
+//! ephemeral port, or a multicast response if the socket is bound to mDNS port 5353. Returns the
+//! used query ID, or <0 if error.
+static inline int
+mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
+ size_t capacity, uint16_t query_id);
+
+//! Send a multicast mDNS query on the given socket for the given service names. The supplied buffer
+//! will be used to build the query packet and must be 32 bit aligned. The query ID can be set to
+//! non-zero to filter responses, however the RFC states that the query ID SHOULD be set to 0 for
+//! multicast queries. Each additional service name query consists of a triplet - a record type
+//! (mdns_record_type_t), a name string pointer (const char*) and a name length (size_t). The list
+//! of variable arguments should be terminated with a record type of 0. The query will request a
+//! unicast response if the socket is bound to an ephemeral port, or a multicast response if the
+//! socket is bound to mDNS port 5353. Returns the used query ID, or <0 if error.
+static inline int
+mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* buffer,
+ size_t capacity, uint16_t query_id);
+
+//! Receive unicast responses to a mDNS query sent with mdns_discovery_recv, optionally filtering
+//! out any responses not matching the given query ID. Set the query ID to 0 to parse all responses,
+//! even if it is not matching the query ID set in a specific query. Any data will be piped to the
+//! given callback for parsing. Buffer must be 32 bit aligned. Parsing is stopped when callback
+//! function returns non-zero. Returns the number of responses parsed.
+static inline size_t
+mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
+ void* user_data, int query_id);
+
+//! Send a variable unicast mDNS query answer to any question with variable number of records to the
+//! given address. Use the top bit of the query class field (MDNS_UNICAST_RESPONSE) in the query
+//! recieved to determine if the answer should be sent unicast (bit set) or multicast (bit not set).
+//! Buffer must be 32 bit aligned. The record type and name should match the data from the query
+//! recieved. Returns 0 if success, or <0 if error.
+static inline int
+mdns_query_answer_unicast(int sock, const void* address, size_t address_size, void* buffer,
+ size_t capacity, uint16_t query_id, mdns_record_type_t record_type,
+ const char* name, size_t name_length, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count);
+
+//! Send a variable multicast mDNS query answer to any question with variable number of records. Use
+//! the top bit of the query class field (MDNS_UNICAST_RESPONSE) in the query recieved to determine
+//! if the answer should be sent unicast (bit set) or multicast (bit not set). Buffer must be 32 bit
+//! aligned. Returns 0 if success, or <0 if error.
+static inline int
+mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count);
+
+//! Send a variable multicast mDNS announcement (as an unsolicited answer) with variable number of
+//! records.Buffer must be 32 bit aligned. Returns 0 if success, or <0 if error. Use this on service
+//! startup to announce your instance to the local network.
+static inline int
+mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count);
+
+//! Send a variable multicast mDNS announcement. Use this on service end for removing the resource
+//! from the local network. The records must be identical to the according announcement.
+static inline int
+mdns_goodbye_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count);
+
+// Parse records functions
+
+//! Parse a PTR record, returns the name in the record
+static inline mdns_string_t
+mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
+ char* strbuffer, size_t capacity);
+
+//! Parse a SRV record, returns the priority, weight, port and name in the record
+static inline mdns_record_srv_t
+mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
+ char* strbuffer, size_t capacity);
+
+//! Parse an A record, returns the IPv4 address in the record
+static inline struct sockaddr_in*
+mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
+ struct sockaddr_in* addr);
+
+//! Parse an AAAA record, returns the IPv6 address in the record
+static inline struct sockaddr_in6*
+mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
+ struct sockaddr_in6* addr);
+
+//! Parse a TXT record, returns the number of key=value records parsed and stores the key-value
+//! pairs in the supplied buffer
+static inline size_t
+mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
+ mdns_record_txt_t* records, size_t capacity);
+
+// Internal functions
+
+static inline mdns_string_t
+mdns_string_extract(const void* buffer, size_t size, size_t* offset, char* str, size_t capacity);
+
+static inline int
+mdns_string_skip(const void* buffer, size_t size, size_t* offset);
+
+static inline size_t
+mdns_string_find(const char* str, size_t length, char c, size_t offset);
+
+//! Compare if two strings are equal. If the strings are equal it returns >0 and the offset variables are
+//! updated to the end of the corresponding strings. If the strings are not equal it returns 0 and
+//! the offset variables are NOT updated.
+static inline int
+mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs, const void* buffer_rhs,
+ size_t size_rhs, size_t* ofs_rhs);
+
+static inline void*
+mdns_string_make(void* buffer, size_t capacity, void* data, const char* name, size_t length,
+ mdns_string_table_t* string_table);
+
+static inline size_t
+mdns_string_table_find(mdns_string_table_t* string_table, const void* buffer, size_t capacity,
+ const char* str, size_t first_length, size_t total_length);
+
+// Implementations
+
+static inline uint16_t
+mdns_ntohs(const void* data) {
+ uint16_t aligned;
+ memcpy(&aligned, data, sizeof(uint16_t));
+ return ntohs(aligned);
+}
+
+static inline uint32_t
+mdns_ntohl(const void* data) {
+ uint32_t aligned;
+ memcpy(&aligned, data, sizeof(uint32_t));
+ return ntohl(aligned);
+}
+
+static inline void*
+mdns_htons(void* data, uint16_t val) {
+ val = htons(val);
+ memcpy(data, &val, sizeof(uint16_t));
+ return MDNS_POINTER_OFFSET(data, sizeof(uint16_t));
+}
+
+static inline void*
+mdns_htonl(void* data, uint32_t val) {
+ val = htonl(val);
+ memcpy(data, &val, sizeof(uint32_t));
+ return MDNS_POINTER_OFFSET(data, sizeof(uint32_t));
+}
+
+static inline int
+mdns_socket_open_ipv4(const struct sockaddr_in* saddr) {
+ int sock = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock < 0)
+ return -1;
+ if (mdns_socket_setup_ipv4(sock, saddr)) {
+ mdns_socket_close(sock);
+ return -1;
+ }
+ return sock;
+}
+
+static inline int
+mdns_socket_setup_ipv4(int sock, const struct sockaddr_in* saddr) {
+ unsigned char ttl = 1;
+ unsigned char loopback = 1;
+ unsigned int reuseaddr = 1;
+ struct ip_mreq req;
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
+#ifdef SO_REUSEPORT
+ setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseaddr, sizeof(reuseaddr));
+#endif
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl));
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback));
+
+ memset(&req, 0, sizeof(req));
+ req.imr_multiaddr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
+ if (saddr)
+ req.imr_interface = saddr->sin_addr;
+ if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&req, sizeof(req)))
+ return -1;
+
+ struct sockaddr_in sock_addr;
+ if (!saddr) {
+ memset(&sock_addr, 0, sizeof(struct sockaddr_in));
+ sock_addr.sin_family = AF_INET;
+ sock_addr.sin_addr.s_addr = INADDR_ANY;
+#ifdef __APPLE__
+ sock_addr.sin_len = sizeof(struct sockaddr_in);
+#endif
+ } else {
+ memcpy(&sock_addr, saddr, sizeof(struct sockaddr_in));
+ setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&sock_addr.sin_addr,
+ sizeof(sock_addr.sin_addr));
+#ifndef _WIN32
+ sock_addr.sin_addr.s_addr = INADDR_ANY;
+#endif
+ }
+
+ if (bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in)))
+ return -1;
+
+#ifdef _WIN32
+ unsigned long param = 1;
+ ioctlsocket(sock, FIONBIO, ¶m);
+#else
+ const int flags = fcntl(sock, F_GETFL, 0);
+ fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+#endif
+
+ return 0;
+}
+
+static inline int
+mdns_socket_open_ipv6(const struct sockaddr_in6* saddr) {
+ int sock = (int)socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock < 0)
+ return -1;
+ if (mdns_socket_setup_ipv6(sock, saddr)) {
+ mdns_socket_close(sock);
+ return -1;
+ }
+ return sock;
+}
+
+static inline int
+mdns_socket_setup_ipv6(int sock, const struct sockaddr_in6* saddr) {
+ int hops = 1;
+ unsigned int loopback = 1;
+ unsigned int reuseaddr = 1;
+ struct ipv6_mreq req;
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
+#ifdef SO_REUSEPORT
+ setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuseaddr, sizeof(reuseaddr));
+#endif
+ setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&hops, sizeof(hops));
+ setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback));
+
+ memset(&req, 0, sizeof(req));
+ req.ipv6mr_multiaddr.s6_addr[0] = 0xFF;
+ req.ipv6mr_multiaddr.s6_addr[1] = 0x02;
+ req.ipv6mr_multiaddr.s6_addr[15] = 0xFB;
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&req, sizeof(req)))
+ return -1;
+
+ struct sockaddr_in6 sock_addr;
+ if (!saddr) {
+ memset(&sock_addr, 0, sizeof(struct sockaddr_in6));
+ sock_addr.sin6_family = AF_INET6;
+ sock_addr.sin6_addr = in6addr_any;
+#ifdef __APPLE__
+ sock_addr.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ } else {
+ memcpy(&sock_addr, saddr, sizeof(struct sockaddr_in6));
+ unsigned int ifindex = 0;
+ setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (const char*)&ifindex, sizeof(ifindex));
+#ifndef _WIN32
+ sock_addr.sin6_addr = in6addr_any;
+#endif
+ }
+
+ if (bind(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in6)))
+ return -1;
+
+#ifdef _WIN32
+ unsigned long param = 1;
+ ioctlsocket(sock, FIONBIO, ¶m);
+#else
+ const int flags = fcntl(sock, F_GETFL, 0);
+ fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+#endif
+
+ return 0;
+}
+
+static inline void
+mdns_socket_close(int sock) {
+#ifdef _WIN32
+ closesocket(sock);
+#else
+ close(sock);
+#endif
+}
+
+static inline int
+mdns_is_string_ref(uint8_t val) {
+ return (0xC0 == (val & 0xC0));
+}
+
+static inline mdns_string_pair_t
+mdns_get_next_substring(const void* rawdata, size_t size, size_t offset) {
+ const uint8_t* buffer = (const uint8_t*)rawdata;
+ mdns_string_pair_t pair = {MDNS_INVALID_POS, 0, 0};
+ if (offset >= size)
+ return pair;
+ if (!buffer[offset]) {
+ pair.offset = offset;
+ return pair;
+ }
+ int recursion = 0;
+ while (mdns_is_string_ref(buffer[offset])) {
+ if (size < offset + 2)
+ return pair;
+
+ offset = mdns_ntohs(MDNS_POINTER_OFFSET(buffer, offset)) & 0x3fff;
+ if (offset >= size)
+ return pair;
+
+ pair.ref = 1;
+ if (++recursion > 16)
+ return pair;
+ }
+
+ size_t length = (size_t)buffer[offset++];
+ if (size < offset + length)
+ return pair;
+
+ pair.offset = offset;
+ pair.length = length;
+
+ return pair;
+}
+
+static inline int
+mdns_string_skip(const void* buffer, size_t size, size_t* offset) {
+ size_t cur = *offset;
+ mdns_string_pair_t substr;
+ unsigned int counter = 0;
+ do {
+ substr = mdns_get_next_substring(buffer, size, cur);
+ if ((substr.offset == MDNS_INVALID_POS) || (counter++ > MDNS_MAX_SUBSTRINGS))
+ return 0;
+ if (substr.ref) {
+ *offset = cur + 2;
+ return 1;
+ }
+ cur = substr.offset + substr.length;
+ } while (substr.length);
+
+ *offset = cur + 1;
+ return 1;
+}
+
+static inline int
+mdns_string_equal(const void* buffer_lhs, size_t size_lhs, size_t* ofs_lhs, const void* buffer_rhs,
+ size_t size_rhs, size_t* ofs_rhs) {
+ size_t lhs_cur = *ofs_lhs;
+ size_t rhs_cur = *ofs_rhs;
+ size_t lhs_end = MDNS_INVALID_POS;
+ size_t rhs_end = MDNS_INVALID_POS;
+ mdns_string_pair_t lhs_substr;
+ mdns_string_pair_t rhs_substr;
+ unsigned int counter = 0;
+ do {
+ lhs_substr = mdns_get_next_substring(buffer_lhs, size_lhs, lhs_cur);
+ rhs_substr = mdns_get_next_substring(buffer_rhs, size_rhs, rhs_cur);
+ if ((lhs_substr.offset == MDNS_INVALID_POS) || (rhs_substr.offset == MDNS_INVALID_POS) ||
+ (counter++ > MDNS_MAX_SUBSTRINGS))
+ return 0;
+ if (lhs_substr.length != rhs_substr.length)
+ return 0;
+ if (strncasecmp((const char*)MDNS_POINTER_OFFSET_CONST(buffer_rhs, rhs_substr.offset),
+ (const char*)MDNS_POINTER_OFFSET_CONST(buffer_lhs, lhs_substr.offset),
+ rhs_substr.length))
+ return 0;
+ if (lhs_substr.ref && (lhs_end == MDNS_INVALID_POS))
+ lhs_end = lhs_cur + 2;
+ if (rhs_substr.ref && (rhs_end == MDNS_INVALID_POS))
+ rhs_end = rhs_cur + 2;
+ lhs_cur = lhs_substr.offset + lhs_substr.length;
+ rhs_cur = rhs_substr.offset + rhs_substr.length;
+ } while (lhs_substr.length);
+
+ if (lhs_end == MDNS_INVALID_POS)
+ lhs_end = lhs_cur + 1;
+ *ofs_lhs = lhs_end;
+
+ if (rhs_end == MDNS_INVALID_POS)
+ rhs_end = rhs_cur + 1;
+ *ofs_rhs = rhs_end;
+
+ return 1;
+}
+
+static inline mdns_string_t
+mdns_string_extract(const void* buffer, size_t size, size_t* offset, char* str, size_t capacity) {
+ size_t cur = *offset;
+ size_t end = MDNS_INVALID_POS;
+ mdns_string_pair_t substr;
+ mdns_string_t result;
+ result.str = str;
+ result.length = 0;
+ char* dst = str;
+ unsigned int counter = 0;
+ size_t remain = capacity;
+ do {
+ substr = mdns_get_next_substring(buffer, size, cur);
+ if ((substr.offset == MDNS_INVALID_POS) || (counter++ > MDNS_MAX_SUBSTRINGS))
+ return result;
+ if (substr.ref && (end == MDNS_INVALID_POS))
+ end = cur + 2;
+ if (substr.length) {
+ size_t to_copy = (substr.length < remain) ? substr.length : remain;
+ memcpy(dst, (const char*)buffer + substr.offset, to_copy);
+ dst += to_copy;
+ remain -= to_copy;
+ if (remain) {
+ *dst++ = '.';
+ --remain;
+ }
+ }
+ cur = substr.offset + substr.length;
+ } while (substr.length);
+
+ if (end == MDNS_INVALID_POS)
+ end = cur + 1;
+ *offset = end;
+
+ result.length = capacity - remain;
+ return result;
+}
+
+static inline size_t
+mdns_string_table_find(mdns_string_table_t* string_table, const void* buffer, size_t capacity,
+ const char* str, size_t first_length, size_t total_length) {
+ if (!string_table)
+ return MDNS_INVALID_POS;
+
+ for (size_t istr = 0; istr < string_table->count; ++istr) {
+ if (string_table->offset[istr] >= capacity)
+ continue;
+ size_t offset = 0;
+ mdns_string_pair_t sub_string =
+ mdns_get_next_substring(buffer, capacity, string_table->offset[istr]);
+ if (!sub_string.length || (sub_string.length != first_length))
+ continue;
+ if (memcmp(str, MDNS_POINTER_OFFSET(buffer, sub_string.offset), sub_string.length))
+ continue;
+
+ // Initial substring matches, now match all remaining substrings
+ offset += first_length + 1;
+ while (offset < total_length) {
+ size_t dot_pos = mdns_string_find(str, total_length, '.', offset);
+ if (dot_pos == MDNS_INVALID_POS)
+ dot_pos = total_length;
+ size_t current_length = dot_pos - offset;
+
+ sub_string =
+ mdns_get_next_substring(buffer, capacity, sub_string.offset + sub_string.length);
+ if (!sub_string.length || (sub_string.length != current_length))
+ break;
+ if (memcmp(str + offset, MDNS_POINTER_OFFSET(buffer, sub_string.offset),
+ sub_string.length))
+ break;
+
+ offset = dot_pos + 1;
+ }
+
+ // Return reference offset if entire string matches
+ if (offset >= total_length)
+ return string_table->offset[istr];
+ }
+
+ return MDNS_INVALID_POS;
+}
+
+static inline void
+mdns_string_table_add(mdns_string_table_t* string_table, size_t offset) {
+ if (!string_table)
+ return;
+
+ string_table->offset[string_table->next] = offset;
+
+ size_t table_capacity = sizeof(string_table->offset) / sizeof(string_table->offset[0]);
+ if (++string_table->count > table_capacity)
+ string_table->count = table_capacity;
+ if (++string_table->next >= table_capacity)
+ string_table->next = 0;
+}
+
+static inline size_t
+mdns_string_find(const char* str, size_t length, char c, size_t offset) {
+ const void* found;
+ if (offset >= length)
+ return MDNS_INVALID_POS;
+ found = memchr(str + offset, c, length - offset);
+ if (found)
+ return (size_t)MDNS_POINTER_DIFF(found, str);
+ return MDNS_INVALID_POS;
+}
+
+static inline void*
+mdns_string_make_ref(void* data, size_t capacity, size_t ref_offset) {
+ if (capacity < 2)
+ return 0;
+ return mdns_htons(data, 0xC000 | (uint16_t)ref_offset);
+}
+
+static inline void*
+mdns_string_make(void* buffer, size_t capacity, void* data, const char* name, size_t length,
+ mdns_string_table_t* string_table) {
+ size_t last_pos = 0;
+ size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
+ if (name[length - 1] == '.')
+ --length;
+ while (last_pos < length) {
+ size_t pos = mdns_string_find(name, length, '.', last_pos);
+ size_t sub_length = ((pos != MDNS_INVALID_POS) ? pos : length) - last_pos;
+ size_t total_length = length - last_pos;
+
+ size_t ref_offset =
+ mdns_string_table_find(string_table, buffer, capacity,
+ (char*)MDNS_POINTER_OFFSET(name, last_pos), sub_length,
+ total_length);
+ if (ref_offset != MDNS_INVALID_POS)
+ return mdns_string_make_ref(data, remain, ref_offset);
+
+ if (remain <= (sub_length + 1))
+ return 0;
+
+ *(unsigned char*)data = (unsigned char)sub_length;
+ memcpy(MDNS_POINTER_OFFSET(data, 1), name + last_pos, sub_length);
+ mdns_string_table_add(string_table, MDNS_POINTER_DIFF(data, buffer));
+
+ data = MDNS_POINTER_OFFSET(data, sub_length + 1);
+ last_pos = ((pos != MDNS_INVALID_POS) ? pos + 1 : length);
+ remain = capacity - MDNS_POINTER_DIFF(data, buffer);
+ }
+
+ if (!remain)
+ return 0;
+
+ *(unsigned char*)data = 0;
+ return MDNS_POINTER_OFFSET(data, 1);
+}
+
+static inline size_t
+mdns_records_parse(int sock, const struct sockaddr* from, size_t addrlen, const void* buffer,
+ size_t size, size_t* offset, mdns_entry_type_t type, uint16_t query_id,
+ size_t records, mdns_record_callback_fn callback, void* user_data) {
+ size_t parsed = 0;
+ for (size_t i = 0; i < records; ++i) {
+ size_t name_offset = *offset;
+ mdns_string_skip(buffer, size, offset);
+ if (((*offset) + 10) > size)
+ return parsed;
+ size_t name_length = (*offset) - name_offset;
+ const uint16_t* data = (const uint16_t*)MDNS_POINTER_OFFSET(buffer, *offset);
+
+ uint16_t rtype = mdns_ntohs(data++);
+ uint16_t rclass = mdns_ntohs(data++);
+ uint32_t ttl = mdns_ntohl(data);
+ data += 2;
+ uint16_t length = mdns_ntohs(data++);
+
+ *offset += 10;
+
+ if (length <= (size - (*offset))) {
+ ++parsed;
+ if (callback &&
+ callback(sock, from, addrlen, type, query_id, rtype, rclass, ttl, buffer, size,
+ name_offset, name_length, *offset, length, user_data))
+ break;
+ }
+
+ *offset += length;
+ }
+ return parsed;
+}
+
+static inline int
+mdns_unicast_send(int sock, const void* address, size_t address_size, const void* buffer,
+ size_t size) {
+ if (sendto(sock, (const char*)buffer, (mdns_size_t)size, 0, (const struct sockaddr*)address,
+ (socklen_t)address_size) < 0)
+ return -1;
+ return 0;
+}
+
+static inline int
+mdns_multicast_send(int sock, const void* buffer, size_t size) {
+ struct sockaddr_storage addr_storage;
+ struct sockaddr_in addr;
+ struct sockaddr_in6 addr6;
+ struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
+ socklen_t saddrlen = sizeof(struct sockaddr_storage);
+ if (getsockname(sock, saddr, &saddrlen))
+ return -1;
+ if (saddr->sa_family == AF_INET6) {
+ memset(&addr6, 0, sizeof(addr6));
+ addr6.sin6_family = AF_INET6;
+#ifdef __APPLE__
+ addr6.sin6_len = sizeof(addr6);
+#endif
+ addr6.sin6_addr.s6_addr[0] = 0xFF;
+ addr6.sin6_addr.s6_addr[1] = 0x02;
+ addr6.sin6_addr.s6_addr[15] = 0xFB;
+ addr6.sin6_port = htons((unsigned short)MDNS_PORT);
+ saddr = (struct sockaddr*)&addr6;
+ saddrlen = sizeof(addr6);
+ } else {
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+#ifdef __APPLE__
+ addr.sin_len = sizeof(addr);
+#endif
+ addr.sin_addr.s_addr = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
+ addr.sin_port = htons((unsigned short)MDNS_PORT);
+ saddr = (struct sockaddr*)&addr;
+ saddrlen = sizeof(addr);
+ }
+
+ if (sendto(sock, (const char*)buffer, (mdns_size_t)size, 0, saddr, saddrlen) < 0)
+ return -1;
+ return 0;
+}
+
+static const uint8_t mdns_services_query[] = {
+ // Query ID
+ 0x00, 0x00,
+ // Flags
+ 0x00, 0x00,
+ // 1 question
+ 0x00, 0x01,
+ // No answer, authority or additional RRs
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // _services._dns-sd._udp.local.
+ 0x09, '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', 0x07, '_', 'd', 'n', 's', '-', 's', 'd',
+ 0x04, '_', 'u', 'd', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
+ // PTR record
+ 0x00, MDNS_RECORDTYPE_PTR,
+ // QU (unicast response) and class IN
+ 0x80, MDNS_CLASS_IN};
+
+static inline int
+mdns_discovery_send(int sock) {
+ return mdns_multicast_send(sock, mdns_services_query, sizeof(mdns_services_query));
+}
+
+static inline size_t
+mdns_discovery_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
+ void* user_data) {
+ struct sockaddr_in6 addr;
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
+ socklen_t addrlen = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+#ifdef __APPLE__
+ saddr->sa_len = sizeof(addr);
+#endif
+ mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
+ if (ret <= 0)
+ return 0;
+
+ size_t data_size = (size_t)ret;
+ size_t records = 0;
+ const uint16_t* data = (uint16_t*)buffer;
+
+ uint16_t query_id = mdns_ntohs(data++);
+ uint16_t flags = mdns_ntohs(data++);
+ uint16_t questions = mdns_ntohs(data++);
+ uint16_t answer_rrs = mdns_ntohs(data++);
+ uint16_t authority_rrs = mdns_ntohs(data++);
+ uint16_t additional_rrs = mdns_ntohs(data++);
+
+ // According to RFC 6762 the query ID MUST match the sent query ID (which is 0 in our case)
+ if (query_id || (flags != 0x8400))
+ return 0; // Not a reply to our question
+
+ // It seems some implementations do not fill the correct questions field,
+ // so ignore this check for now and only validate answer string
+ // if (questions != 1)
+ // return 0;
+
+ int i;
+ for (i = 0; i < questions; ++i) {
+ size_t offset = MDNS_POINTER_DIFF(data, buffer);
+ size_t verify_offset = 12;
+ // Verify it's our question, _services._dns-sd._udp.local.
+ if (!mdns_string_equal(buffer, data_size, &offset, mdns_services_query,
+ sizeof(mdns_services_query), &verify_offset))
+ return 0;
+ data = (const uint16_t*)MDNS_POINTER_OFFSET(buffer, offset);
+
+ uint16_t rtype = mdns_ntohs(data++);
+ uint16_t rclass = mdns_ntohs(data++);
+
+ // Make sure we get a reply based on our PTR question for class IN
+ if ((rtype != MDNS_RECORDTYPE_PTR) || ((rclass & 0x7FFF) != MDNS_CLASS_IN))
+ return 0;
+ }
+
+ for (i = 0; i < answer_rrs; ++i) {
+ size_t offset = MDNS_POINTER_DIFF(data, buffer);
+ size_t verify_offset = 12;
+ // Verify it's an answer to our question, _services._dns-sd._udp.local.
+ size_t name_offset = offset;
+ int is_answer = mdns_string_equal(buffer, data_size, &offset, mdns_services_query,
+ sizeof(mdns_services_query), &verify_offset);
+ if (!is_answer && !mdns_string_skip(buffer, data_size, &offset))
+ break;
+ size_t name_length = offset - name_offset;
+ if ((offset + 10) > data_size)
+ return records;
+ data = (const uint16_t*)MDNS_POINTER_OFFSET(buffer, offset);
+
+ uint16_t rtype = mdns_ntohs(data++);
+ uint16_t rclass = mdns_ntohs(data++);
+ uint32_t ttl = mdns_ntohl(data);
+ data += 2;
+ uint16_t length = mdns_ntohs(data++);
+ if (length > (data_size - offset))
+ return 0;
+
+ if (is_answer) {
+ ++records;
+ offset = MDNS_POINTER_DIFF(data, buffer);
+ if (callback &&
+ callback(sock, saddr, addrlen, MDNS_ENTRYTYPE_ANSWER, query_id, rtype, rclass, ttl,
+ buffer, data_size, name_offset, name_length, offset, length, user_data))
+ return records;
+ }
+ data = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(data, length);
+ }
+
+ size_t total_records = records;
+ size_t offset = MDNS_POINTER_DIFF(data, buffer);
+ records =
+ mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_AUTHORITY, query_id, authority_rrs, callback, user_data);
+ total_records += records;
+ if (records != authority_rrs)
+ return total_records;
+
+ records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ADDITIONAL, query_id, additional_rrs, callback,
+ user_data);
+ total_records += records;
+ if (records != additional_rrs)
+ return total_records;
+
+ return total_records;
+}
+
+static inline size_t
+mdns_socket_listen(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
+ void* user_data) {
+ struct sockaddr_in6 addr;
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
+ socklen_t addrlen = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+#ifdef __APPLE__
+ saddr->sa_len = sizeof(addr);
+#endif
+ mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
+ if (ret <= 0)
+ return 0;
+
+ size_t data_size = (size_t)ret;
+ const uint16_t* data = (const uint16_t*)buffer;
+
+ uint16_t query_id = mdns_ntohs(data++);
+ uint16_t flags = mdns_ntohs(data++);
+ uint16_t questions = mdns_ntohs(data++);
+ uint16_t answer_rrs = mdns_ntohs(data++);
+ uint16_t authority_rrs = mdns_ntohs(data++);
+ uint16_t additional_rrs = mdns_ntohs(data++);
+
+ size_t records;
+ size_t total_records = 0;
+ for (int iquestion = 0; iquestion < questions; ++iquestion) {
+ size_t question_offset = MDNS_POINTER_DIFF(data, buffer);
+ size_t offset = question_offset;
+ size_t verify_offset = 12;
+ int dns_sd = 0;
+ if (mdns_string_equal(buffer, data_size, &offset, mdns_services_query,
+ sizeof(mdns_services_query), &verify_offset)) {
+ dns_sd = 1;
+ } else if (!mdns_string_skip(buffer, data_size, &offset)) {
+ break;
+ }
+ size_t length = offset - question_offset;
+ data = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(buffer, offset);
+
+ uint16_t rtype = mdns_ntohs(data++);
+ uint16_t rclass = mdns_ntohs(data++);
+ uint16_t class_without_flushbit = rclass & ~MDNS_CACHE_FLUSH;
+
+ // Make sure we get a question of class IN or ANY
+ if (!((class_without_flushbit == MDNS_CLASS_IN) ||
+ (class_without_flushbit == MDNS_CLASS_ANY))) {
+ break;
+ }
+
+ if (dns_sd && flags)
+ continue;
+
+ ++total_records;
+ if (callback && callback(sock, saddr, addrlen, MDNS_ENTRYTYPE_QUESTION, query_id, rtype,
+ rclass, 0, buffer, data_size, question_offset, length,
+ question_offset, length, user_data))
+ return total_records;
+ }
+
+ size_t offset = MDNS_POINTER_DIFF(data, buffer);
+ records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ANSWER, query_id, answer_rrs, callback, user_data);
+ total_records += records;
+ if (records != answer_rrs)
+ return total_records;
+
+ records =
+ mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_AUTHORITY, query_id, authority_rrs, callback, user_data);
+ total_records += records;
+ if (records != authority_rrs)
+ return total_records;
+
+ records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ADDITIONAL, query_id, additional_rrs, callback,
+ user_data);
+
+ return total_records;
+}
+
+static inline int
+mdns_query_send(int sock, mdns_record_type_t type, const char* name, size_t length, void* buffer,
+ size_t capacity, uint16_t query_id) {
+ mdns_query_t query;
+ query.type = type;
+ query.name = name;
+ query.length = length;
+ return mdns_multiquery_send(sock, &query, 1, buffer, capacity, query_id);
+}
+
+static inline int
+mdns_multiquery_send(int sock, const mdns_query_t* query, size_t count, void* buffer, size_t capacity,
+ uint16_t query_id) {
+ if (!count || (capacity < (sizeof(struct mdns_header_t) + (6 * count))))
+ return -1;
+
+ // Ask for a unicast response since it's a one-shot query
+ uint16_t rclass = MDNS_CLASS_IN | MDNS_UNICAST_RESPONSE;
+
+ struct sockaddr_storage addr_storage;
+ struct sockaddr* saddr = (struct sockaddr*)&addr_storage;
+ socklen_t saddrlen = sizeof(addr_storage);
+ if (getsockname(sock, saddr, &saddrlen) == 0) {
+ if ((saddr->sa_family == AF_INET) &&
+ (ntohs(((struct sockaddr_in*)saddr)->sin_port) == MDNS_PORT))
+ rclass &= ~MDNS_UNICAST_RESPONSE;
+ else if ((saddr->sa_family == AF_INET6) &&
+ (ntohs(((struct sockaddr_in6*)saddr)->sin6_port) == MDNS_PORT))
+ rclass &= ~MDNS_UNICAST_RESPONSE;
+ }
+
+ struct mdns_header_t* header = (struct mdns_header_t*)buffer;
+ // Query ID
+ header->query_id = htons((unsigned short)query_id);
+ // Flags
+ header->flags = 0;
+ // Questions
+ header->questions = htons((unsigned short)count);
+ // No answer, authority or additional RRs
+ header->answer_rrs = 0;
+ header->authority_rrs = 0;
+ header->additional_rrs = 0;
+ // Fill in questions
+ void* data = MDNS_POINTER_OFFSET(buffer, sizeof(struct mdns_header_t));
+ for (size_t iq = 0; iq < count; ++iq) {
+ // Name string
+ data = mdns_string_make(buffer, capacity, data, query[iq].name, query[iq].length, 0);
+ if (!data)
+ return -1;
+ // Record type
+ data = mdns_htons(data, query[iq].type);
+ //! Optional unicast response based on local port, class IN
+ data = mdns_htons(data, rclass);
+ }
+
+ size_t tosend = MDNS_POINTER_DIFF(data, buffer);
+ if (mdns_multicast_send(sock, buffer, (size_t)tosend))
+ return -1;
+ return query_id;
+}
+
+static inline size_t
+mdns_query_recv(int sock, void* buffer, size_t capacity, mdns_record_callback_fn callback,
+ void* user_data, int only_query_id) {
+ struct sockaddr_in6 addr;
+ struct sockaddr* saddr = (struct sockaddr*)&addr;
+ socklen_t addrlen = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+#ifdef __APPLE__
+ saddr->sa_len = sizeof(addr);
+#endif
+ mdns_ssize_t ret = recvfrom(sock, (char*)buffer, (mdns_size_t)capacity, 0, saddr, &addrlen);
+ if (ret <= 0)
+ return 0;
+
+ size_t data_size = (size_t)ret;
+ const uint16_t* data = (const uint16_t*)buffer;
+
+ uint16_t query_id = mdns_ntohs(data++);
+ uint16_t flags = mdns_ntohs(data++);
+ uint16_t questions = mdns_ntohs(data++);
+ uint16_t answer_rrs = mdns_ntohs(data++);
+ uint16_t authority_rrs = mdns_ntohs(data++);
+ uint16_t additional_rrs = mdns_ntohs(data++);
+ (void)sizeof(flags);
+
+ if ((only_query_id > 0) && (query_id != only_query_id))
+ return 0; // Not a reply to the wanted one-shot query
+
+ if (questions > 1)
+ return 0;
+
+ // Skip questions part
+ int i;
+ for (i = 0; i < questions; ++i) {
+ size_t offset = MDNS_POINTER_DIFF(data, buffer);
+ if (!mdns_string_skip(buffer, data_size, &offset))
+ return 0;
+ data = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(buffer, offset);
+ // Record type and class not used, skip
+ // uint16_t rtype = mdns_ntohs(data++);
+ // uint16_t rclass = mdns_ntohs(data++);
+ data += 2;
+ }
+
+ size_t records = 0;
+ size_t total_records = 0;
+ size_t offset = MDNS_POINTER_DIFF(data, buffer);
+ records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ANSWER, query_id, answer_rrs, callback, user_data);
+ total_records += records;
+ if (records != answer_rrs)
+ return total_records;
+
+ records =
+ mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_AUTHORITY, query_id, authority_rrs, callback, user_data);
+ total_records += records;
+ if (records != authority_rrs)
+ return total_records;
+
+ records = mdns_records_parse(sock, saddr, addrlen, buffer, data_size, &offset,
+ MDNS_ENTRYTYPE_ADDITIONAL, query_id, additional_rrs, callback,
+ user_data);
+ total_records += records;
+ if (records != additional_rrs)
+ return total_records;
+
+ return total_records;
+}
+
+static inline void*
+mdns_answer_add_question_unicast(void* buffer, size_t capacity, void* data,
+ mdns_record_type_t record_type, const char* name,
+ size_t name_length, mdns_string_table_t* string_table) {
+ data = mdns_string_make(buffer, capacity, data, name, name_length, string_table);
+ if (!data)
+ return 0;
+ size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
+ if (remain < 4)
+ return 0;
+
+ data = mdns_htons(data, record_type);
+ data = mdns_htons(data, MDNS_UNICAST_RESPONSE | MDNS_CLASS_IN);
+
+ return data;
+}
+
+static inline void*
+mdns_answer_add_record_header(void* buffer, size_t capacity, void* data, mdns_record_t record,
+ mdns_string_table_t* string_table) {
+ data = mdns_string_make(buffer, capacity, data, record.name.str, record.name.length, string_table);
+ if (!data)
+ return 0;
+ size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
+ if (remain < 10)
+ return 0;
+
+ data = mdns_htons(data, record.type);
+ data = mdns_htons(data, record.rclass);
+ data = mdns_htonl(data, record.ttl);
+ data = mdns_htons(data, 0); // Length, to be filled later
+ return data;
+}
+
+static inline void*
+mdns_answer_add_record(void* buffer, size_t capacity, void* data, mdns_record_t record,
+ mdns_string_table_t* string_table) {
+ // TXT records will be coalesced into one record later
+ if (!data || (record.type == MDNS_RECORDTYPE_TXT))
+ return data;
+
+ data = mdns_answer_add_record_header(buffer, capacity, data, record, string_table);
+ if (!data)
+ return 0;
+
+ // Pointer to length of record to be filled at end
+ void* record_length = MDNS_POINTER_OFFSET(data, -2);
+ void* record_data = data;
+
+ size_t remain = capacity - MDNS_POINTER_DIFF(data, buffer);
+ switch (record.type) {
+ case MDNS_RECORDTYPE_PTR:
+ data = mdns_string_make(buffer, capacity, data, record.data.ptr.name.str,
+ record.data.ptr.name.length, string_table);
+ break;
+
+ case MDNS_RECORDTYPE_SRV:
+ if (remain <= 6)
+ return 0;
+ data = mdns_htons(data, record.data.srv.priority);
+ data = mdns_htons(data, record.data.srv.weight);
+ data = mdns_htons(data, record.data.srv.port);
+ data = mdns_string_make(buffer, capacity, data, record.data.srv.name.str,
+ record.data.srv.name.length, string_table);
+ break;
+
+ case MDNS_RECORDTYPE_A:
+ if (remain < 4)
+ return 0;
+ memcpy(data, &record.data.a.addr.sin_addr.s_addr, 4);
+ data = MDNS_POINTER_OFFSET(data, 4);
+ break;
+
+ case MDNS_RECORDTYPE_AAAA:
+ if (remain < 16)
+ return 0;
+ memcpy(data, &record.data.aaaa.addr.sin6_addr, 16); // ipv6 address
+ data = MDNS_POINTER_OFFSET(data, 16);
+ break;
+
+ default:
+ break;
+ }
+
+ if (!data)
+ return 0;
+
+ // Fill record length
+ mdns_htons(record_length, (uint16_t)MDNS_POINTER_DIFF(data, record_data));
+ return data;
+}
+
+static inline void
+mdns_record_update_rclass_ttl(mdns_record_t* record, uint16_t rclass, uint32_t ttl) {
+ if (!record->rclass)
+ record->rclass = rclass;
+ if (!record->ttl || !ttl)
+ record->ttl = ttl;
+ record->rclass &= (uint16_t)(MDNS_CLASS_IN | MDNS_CACHE_FLUSH);
+ // Never flush PTR record
+ if (record->type == MDNS_RECORDTYPE_PTR)
+ record->rclass &= ~(uint16_t)MDNS_CACHE_FLUSH;
+}
+
+static inline void*
+mdns_answer_add_txt_record(void* buffer, size_t capacity, void* data, const mdns_record_t* records,
+ size_t record_count, uint16_t rclass, uint32_t ttl,
+ mdns_string_table_t* string_table) {
+ // Pointer to length of record to be filled at end
+ void* record_length = 0;
+ void* record_data = 0;
+
+ size_t remain = 0;
+ for (size_t irec = 0; data && (irec < record_count); ++irec) {
+ if (records[irec].type != MDNS_RECORDTYPE_TXT)
+ continue;
+
+ mdns_record_t record = records[irec];
+ mdns_record_update_rclass_ttl(&record, rclass, ttl);
+ if (!record_data) {
+ data = mdns_answer_add_record_header(buffer, capacity, data, record, string_table);
+ if (!data)
+ return data;
+ record_length = MDNS_POINTER_OFFSET(data, -2);
+ record_data = data;
+ }
+
+ // TXT strings are unlikely to be shared, just make then raw. Also need one byte for
+ // termination, thus the <= check
+ size_t string_length = record.data.txt.key.length + record.data.txt.value.length + 1;
+ if (!data)
+ return 0;
+ remain = capacity - MDNS_POINTER_DIFF(data, buffer);
+ if ((remain <= string_length) || (string_length > 0x3FFF))
+ return 0;
+
+ unsigned char* strdata = (unsigned char*)data;
+ *strdata++ = (unsigned char)string_length;
+ memcpy(strdata, record.data.txt.key.str, record.data.txt.key.length);
+ strdata += record.data.txt.key.length;
+ *strdata++ = '=';
+ memcpy(strdata, record.data.txt.value.str, record.data.txt.value.length);
+ strdata += record.data.txt.value.length;
+
+ data = strdata;
+ }
+
+ // Fill record length
+ if (record_data)
+ mdns_htons(record_length, (uint16_t)MDNS_POINTER_DIFF(data, record_data));
+
+ return data;
+}
+
+static inline uint16_t
+mdns_answer_get_record_count(const mdns_record_t* records, size_t record_count) {
+ // TXT records will be coalesced into one record
+ uint16_t total_count = 0;
+ uint16_t txt_record = 0;
+ for (size_t irec = 0; irec < record_count; ++irec) {
+ if (records[irec].type == MDNS_RECORDTYPE_TXT)
+ txt_record = 1;
+ else
+ ++total_count;
+ }
+ return total_count + txt_record;
+}
+
+static inline int
+mdns_query_answer_unicast(int sock, const void* address, size_t address_size, void* buffer,
+ size_t capacity, uint16_t query_id, mdns_record_type_t record_type,
+ const char* name, size_t name_length, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count) {
+ if (capacity < (sizeof(struct mdns_header_t) + 32 + 4))
+ return -1;
+
+ // According to RFC 6762:
+ // The cache-flush bit MUST NOT be set in any resource records in a response message
+ // sent in legacy unicast responses to UDP ports other than 5353.
+ uint16_t rclass = MDNS_CLASS_IN;
+ uint32_t ttl = 10;
+
+ // Basic answer structure
+ struct mdns_header_t* header = (struct mdns_header_t*)buffer;
+ header->query_id = htons(query_id);
+ header->flags = htons(0x8400);
+ header->questions = htons(1);
+ header->answer_rrs = htons(1);
+ header->authority_rrs = htons(mdns_answer_get_record_count(authority, authority_count));
+ header->additional_rrs = htons(mdns_answer_get_record_count(additional, additional_count));
+
+ mdns_string_table_t string_table = {{0}, 0, 0};
+ void* data = MDNS_POINTER_OFFSET(buffer, sizeof(struct mdns_header_t));
+
+ // Fill in question
+ data = mdns_answer_add_question_unicast(buffer, capacity, data, record_type, name, name_length,
+ &string_table);
+
+ // Fill in answer
+ answer.rclass = rclass;
+ answer.ttl = ttl;
+ data = mdns_answer_add_record(buffer, capacity, data, answer, &string_table);
+
+ // Fill in authority records
+ for (size_t irec = 0; data && (irec < authority_count); ++irec) {
+ mdns_record_t record = authority[irec];
+ record.rclass = rclass;
+ if (!record.ttl)
+ record.ttl = ttl;
+ data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
+ }
+ data = mdns_answer_add_txt_record(buffer, capacity, data, authority, authority_count,
+ rclass, ttl, &string_table);
+
+ // Fill in additional records
+ for (size_t irec = 0; data && (irec < additional_count); ++irec) {
+ mdns_record_t record = additional[irec];
+ record.rclass = rclass;
+ if (!record.ttl)
+ record.ttl = ttl;
+ data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
+ }
+ data = mdns_answer_add_txt_record(buffer, capacity, data, additional, additional_count,
+ rclass, ttl, &string_table);
+ if (!data)
+ return -1;
+
+ size_t tosend = MDNS_POINTER_DIFF(data, buffer);
+ return mdns_unicast_send(sock, address, address_size, buffer, tosend);
+}
+
+static inline int
+mdns_answer_multicast_rclass_ttl(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count,
+ uint16_t rclass, uint32_t ttl) {
+ if (capacity < (sizeof(struct mdns_header_t) + 32 + 4))
+ return -1;
+
+ // Basic answer structure
+ struct mdns_header_t* header = (struct mdns_header_t*)buffer;
+ header->query_id = 0;
+ header->flags = htons(0x8400);
+ header->questions = 0;
+ header->answer_rrs = htons(1);
+ header->authority_rrs = htons(mdns_answer_get_record_count(authority, authority_count));
+ header->additional_rrs = htons(mdns_answer_get_record_count(additional, additional_count));
+
+ mdns_string_table_t string_table = {{0}, 0, 0};
+ void* data = MDNS_POINTER_OFFSET(buffer, sizeof(struct mdns_header_t));
+
+ // Fill in answer
+ mdns_record_t record = answer;
+ mdns_record_update_rclass_ttl(&record, rclass, ttl);
+ data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
+
+ // Fill in authority records
+ for (size_t irec = 0; data && (irec < authority_count); ++irec) {
+ record = authority[irec];
+ mdns_record_update_rclass_ttl(&record, rclass, ttl);
+ data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
+ }
+ data = mdns_answer_add_txt_record(buffer, capacity, data, authority, authority_count,
+ rclass, ttl, &string_table);
+
+ // Fill in additional records
+ for (size_t irec = 0; data && (irec < additional_count); ++irec) {
+ record = additional[irec];
+ mdns_record_update_rclass_ttl(&record, rclass, ttl);
+ data = mdns_answer_add_record(buffer, capacity, data, record, &string_table);
+ }
+ data = mdns_answer_add_txt_record(buffer, capacity, data, additional, additional_count,
+ rclass, ttl, &string_table);
+ if (!data)
+ return -1;
+
+ size_t tosend = MDNS_POINTER_DIFF(data, buffer);
+ return mdns_multicast_send(sock, buffer, tosend);
+}
+
+static inline int
+mdns_query_answer_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count) {
+ return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
+ authority_count, additional, additional_count,
+ MDNS_CLASS_IN, 60);
+}
+
+static inline int
+mdns_announce_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count) {
+ return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
+ authority_count, additional, additional_count,
+ MDNS_CLASS_IN | MDNS_CACHE_FLUSH, 60);
+}
+
+static inline int
+mdns_goodbye_multicast(int sock, void* buffer, size_t capacity, mdns_record_t answer,
+ const mdns_record_t* authority, size_t authority_count,
+ const mdns_record_t* additional, size_t additional_count) {
+ // Goodbye should have ttl of 0
+ return mdns_answer_multicast_rclass_ttl(sock, buffer, capacity, answer, authority,
+ authority_count, additional, additional_count,
+ MDNS_CLASS_IN, 0);
+}
+
+static inline mdns_string_t
+mdns_record_parse_ptr(const void* buffer, size_t size, size_t offset, size_t length,
+ char* strbuffer, size_t capacity) {
+ // PTR record is just a string
+ if ((size >= offset + length) && (length >= 2))
+ return mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
+ mdns_string_t empty = {0, 0};
+ return empty;
+}
+
+static inline mdns_record_srv_t
+mdns_record_parse_srv(const void* buffer, size_t size, size_t offset, size_t length,
+ char* strbuffer, size_t capacity) {
+ mdns_record_srv_t srv;
+ memset(&srv, 0, sizeof(mdns_record_srv_t));
+ // Read the service priority, weight, port number and the discovery name
+ // SRV record format (http://www.ietf.org/rfc/rfc2782.txt):
+ // 2 bytes network-order unsigned priority
+ // 2 bytes network-order unsigned weight
+ // 2 bytes network-order unsigned port
+ // string: discovery (domain) name, minimum 2 bytes when compressed
+ if ((size >= offset + length) && (length >= 8)) {
+ const uint16_t* recorddata = (const uint16_t*)MDNS_POINTER_OFFSET_CONST(buffer, offset);
+ srv.priority = mdns_ntohs(recorddata++);
+ srv.weight = mdns_ntohs(recorddata++);
+ srv.port = mdns_ntohs(recorddata++);
+ offset += 6;
+ srv.name = mdns_string_extract(buffer, size, &offset, strbuffer, capacity);
+ }
+ return srv;
+}
+
+static inline struct sockaddr_in*
+mdns_record_parse_a(const void* buffer, size_t size, size_t offset, size_t length,
+ struct sockaddr_in* addr) {
+ memset(addr, 0, sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
+#ifdef __APPLE__
+ addr->sin_len = sizeof(struct sockaddr_in);
+#endif
+ if ((size >= offset + length) && (length == 4))
+ memcpy(&addr->sin_addr.s_addr, MDNS_POINTER_OFFSET(buffer, offset), 4);
+ return addr;
+}
+
+static inline struct sockaddr_in6*
+mdns_record_parse_aaaa(const void* buffer, size_t size, size_t offset, size_t length,
+ struct sockaddr_in6* addr) {
+ memset(addr, 0, sizeof(struct sockaddr_in6));
+ addr->sin6_family = AF_INET6;
+#ifdef __APPLE__
+ addr->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ if ((size >= offset + length) && (length == 16))
+ memcpy(&addr->sin6_addr, MDNS_POINTER_OFFSET(buffer, offset), 16);
+ return addr;
+}
+
+static inline size_t
+mdns_record_parse_txt(const void* buffer, size_t size, size_t offset, size_t length,
+ mdns_record_txt_t* records, size_t capacity) {
+ size_t parsed = 0;
+ const char* strdata;
+ size_t end = offset + length;
+
+ if (size < end)
+ end = size;
+
+ while ((offset < end) && (parsed < capacity)) {
+ strdata = (const char*)MDNS_POINTER_OFFSET(buffer, offset);
+ size_t sublength = *(const unsigned char*)strdata;
+
+ ++strdata;
+ offset += sublength + 1;
+
+ size_t separator = 0;
+ for (size_t c = 0; c < sublength; ++c) {
+ // DNS-SD TXT record keys MUST be printable US-ASCII, [0x20, 0x7E]
+ if ((strdata[c] < 0x20) || (strdata[c] > 0x7E))
+ break;
+ if (strdata[c] == '=') {
+ separator = c;
+ break;
+ }
+ }
+
+ if (!separator)
+ continue;
+
+ if (separator < sublength) {
+ records[parsed].key.str = strdata;
+ records[parsed].key.length = separator;
+ records[parsed].value.str = strdata + separator + 1;
+ records[parsed].value.length = sublength - (separator + 1);
+ } else {
+ records[parsed].key.str = strdata;
+ records[parsed].key.length = sublength;
+ }
+
+ ++parsed;
+ }
+
+ return parsed;
+}
+
+#ifdef _WIN32
+#undef strncasecmp
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/sources b/sources
new file mode 100644
index 0000000..eac1a48
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+SHA512 (hyperhdr-19.0.0.0.tar.gz) = 4f63dc701ae6df7f12f49ae6a02961f86eed0d0a659a7690c6775befd4edbd2321a735b1c240fc00b74f2149484f359e982139b304d9674673729e5dd1b9aa08
1 year, 2 months
Architecture specific change in rpms/rust-crc.git
by githook-noreply@fedoraproject.org
The package rpms/rust-crc.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/rust-crc.git/commit/?id=307342842....
Change:
-ExclusiveArch: %{rust_arches}
Thanks.
Full change:
============
commit 307342842744722bfb19e1c854d846fdddee7ca5
Author: Fabio Valentini <decathorpe(a)gmail.com>
Date: Tue Feb 28 22:13:02 2023 +0100
Update to version 3.0.1; Fixes RHBZ#2078053
diff --git a/.gitignore b/.gitignore
index 861033e..1ced20b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/crc-1.8.1.crate
/crc-1.9.0.crate
/crc-2.1.0.crate
+/crc-3.0.1.crate
diff --git a/384fb68.patch b/384fb68.patch
deleted file mode 100644
index 10646c2..0000000
--- a/384fb68.patch
+++ /dev/null
@@ -1,674 +0,0 @@
-From 384fb68b7af4a06bedbddf2624c715070306a29a Mon Sep 17 00:00:00 2001
-From: Bartel Sielski <bartel.sielski(a)gmail.com>
-Date: Sun, 17 Oct 2021 18:06:46 +0200
-Subject: [PATCH] Add support for CRC algorithms which have a non-power of 2
- width
-
----
- Cargo.toml.orig | 2 +-
- README.md | 1 +
- benches/bench.rs | 20 +++++++-
- src/crc16.rs | 15 ++++--
- src/crc32.rs | 15 ++++--
- src/crc64.rs | 15 ++++--
- src/crc8.rs | 9 ++--
- src/lib.rs | 1 +
- src/table.rs | 45 ++++++++++++++---
- src/util.rs | 100 ++++++++++++++++++++-----------------
- tests/crc.rs | 125 ++++++++++++++++++++++++++++++++++++++++++-----
- 11 files changed, 266 insertions(+), 82 deletions(-)
-
-diff --git a/Cargo.toml.orig b/Cargo.toml.orig
-index b787734..3f24e44 100644
---- a/Cargo.toml.orig
-+++ b/Cargo.toml.orig
-@@ -15,4 +15,4 @@ categories = ["algorithms", "no-std"]
- edition = "2018"
-
- [dependencies]
--crc-catalog = "1.1.1"
-+crc-catalog = "2.0.1"
-diff --git a/README.md b/README.md
-index eefae7b..88bad96 100644
---- a/README.md
-+++ b/README.md
-@@ -27,6 +27,7 @@ assert_eq!(CASTAGNOLI.checksum(b"123456789"), 0xe3069283);
-
- // use custom algorithm
- const CUSTOM_ALG: Algorithm<u16> = Algorithm {
-+ width: 16,
- poly: 0x8005,
- init: 0xffff,
- refin: false,
-diff --git a/benches/bench.rs b/benches/bench.rs
-index 520e3f7..a5fc4b7 100644
---- a/benches/bench.rs
-+++ b/benches/bench.rs
-@@ -5,6 +5,7 @@ use criterion::{Benchmark, Criterion, Throughput};
- pub const BLUETOOTH: Crc<u8> = Crc::<u8>::new(&CRC_8_BLUETOOTH);
- pub const X25: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_SDLC);
- pub const CASTAGNOLI: Crc<u32> = Crc::<u32>::new(&CRC_32_ISCSI);
-+pub const GSM_40: Crc<u64> = Crc::<u64>::new(&CRC_40_GSM);
- pub const ECMA: Crc<u64> = Crc::<u64>::new(&CRC_64_ECMA_182);
-
- fn crc8(c: &mut Criterion) {
-@@ -37,6 +38,16 @@ fn crc32(c: &mut Criterion) {
- );
- }
-
-+fn crc40(c: &mut Criterion) {
-+ let mut digest = GSM_40.digest();
-+ let bytes = vec![0u8; 1_000_000];
-+ c.bench(
-+ "crc40",
-+ Benchmark::new("crc40", move |b| b.iter(|| digest.update(&bytes)))
-+ .throughput(Throughput::Bytes(1_000_000)),
-+ );
-+}
-+
- fn crc64(c: &mut Criterion) {
- let mut digest = ECMA.digest();
- let bytes = vec![0u8; 1_000_000];
-@@ -50,5 +61,12 @@ fn crc64(c: &mut Criterion) {
- criterion_group!(crc8_benches, crc8);
- criterion_group!(crc16_benches, crc16);
- criterion_group!(crc32_benches, crc32);
-+criterion_group!(crc40_benches, crc40);
- criterion_group!(crc64_benches, crc64);
--criterion_main!(crc8_benches, crc16_benches, crc32_benches, crc64_benches);
-+criterion_main!(
-+ crc8_benches,
-+ crc16_benches,
-+ crc32_benches,
-+ crc40_benches,
-+ crc64_benches,
-+);
-diff --git a/src/crc16.rs b/src/crc16.rs
-index d6474da..b88669f 100644
---- a/src/crc16.rs
-+++ b/src/crc16.rs
-@@ -3,7 +3,7 @@ use crate::table::crc16_table;
-
- impl Crc<u16> {
- pub const fn new(algorithm: &'static Algorithm<u16>) -> Self {
-- let table = crc16_table(algorithm.poly, algorithm.refin);
-+ let table = crc16_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u16> {
-
- const fn init(&self) -> u16 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u16::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u16::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u16> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u16) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u16;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u16 ^ (crc >> 8)) ^ (crc << 8);
-+ let table_index = (crc >> (u16::BITS - 8)) ^ bytes[i] as u16;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u16> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u16::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc32.rs b/src/crc32.rs
-index 6ac49cf..d7e7767 100644
---- a/src/crc32.rs
-+++ b/src/crc32.rs
-@@ -3,7 +3,7 @@ use crate::table::crc32_table;
-
- impl Crc<u32> {
- pub const fn new(algorithm: &'static Algorithm<u32>) -> Self {
-- let table = crc32_table(algorithm.poly, algorithm.refin);
-+ let table = crc32_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u32> {
-
- const fn init(&self) -> u32 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u32::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u32::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u32> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u32) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u32;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u32 ^ (crc >> 24)) ^ (crc << 8);
-+ let table_index = (crc >> (u32::BITS - 8)) ^ bytes[i] as u32;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u32> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u32::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc64.rs b/src/crc64.rs
-index b405cd9..52cb0af 100644
---- a/src/crc64.rs
-+++ b/src/crc64.rs
-@@ -3,7 +3,7 @@ use crate::table::crc64_table;
-
- impl Crc<u64> {
- pub const fn new(algorithm: &'static Algorithm<u64>) -> Self {
-- let table = crc64_table(algorithm.poly, algorithm.refin);
-+ let table = crc64_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u64> {
-
- const fn init(&self) -> u64 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u64::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u64::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u64> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u64) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u64;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u64 ^ (crc >> 56)) ^ (crc << 8);
-+ let table_index = (crc >> (u64::BITS - 8)) ^ bytes[i] as u64;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u64> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u64::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc8.rs b/src/crc8.rs
-index f37935d..0cf45c1 100644
---- a/src/crc8.rs
-+++ b/src/crc8.rs
-@@ -3,7 +3,7 @@ use crate::table::crc8_table;
-
- impl Crc<u8> {
- pub const fn new(algorithm: &'static Algorithm<u8>) -> Self {
-- let table = crc8_table(algorithm.poly, algorithm.refin);
-+ let table = crc8_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u8> {
-
- const fn init(&self) -> u8 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u8::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u8::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -40,6 +40,9 @@ impl Crc<u8> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u8::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/lib.rs b/src/lib.rs
-index 7944e19..99a30f6 100644
---- a/src/lib.rs
-+++ b/src/lib.rs
-@@ -14,6 +14,7 @@
- //!
- //! // use custom algorithm
- //! const CUSTOM_ALG: Algorithm<u16> = Algorithm {
-+//! width: 16,
- //! poly: 0x8005,
- //! init: 0xffff,
- //! refin: false,
-diff --git a/src/table.rs b/src/table.rs
-index 1e7ad75..a921ec2 100644
---- a/src/table.rs
-+++ b/src/table.rs
-@@ -1,6 +1,13 @@
- use crate::util::*;
-
--pub(crate) const fn crc8_table(poly: u8, reflect: bool) -> [u8; 256] {
-+pub(crate) const fn crc8_table(width: u8, poly: u8, reflect: bool) -> [u8; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u8::BITS as u8 - width)
-+ } else {
-+ poly << (u8::BITS as u8 - width)
-+ };
-+
- let mut table = [0u8; 256];
- let mut i = 0;
- while i < table.len() {
-@@ -9,29 +16,53 @@ pub(crate) const fn crc8_table(poly: u8, reflect: bool) -> [u8; 256] {
- }
- table
- }
--pub(crate) const fn crc16_table(poly: u16, reflect: bool) -> [u16; 256] {
-+
-+pub(crate) const fn crc16_table(width: u8, poly: u16, reflect: bool) -> [u16; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u16::BITS as u8 - width)
-+ } else {
-+ poly << (u16::BITS as u8 - width)
-+ };
-+
- let mut table = [0u16; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc16(poly, reflect, i as u8);
-+ table[i] = crc16(poly, reflect, i as u16);
- i += 1;
- }
- table
- }
--pub(crate) const fn crc32_table(poly: u32, reflect: bool) -> [u32; 256] {
-+
-+pub(crate) const fn crc32_table(width: u8, poly: u32, reflect: bool) -> [u32; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u32::BITS as u8 - width)
-+ } else {
-+ poly << (u32::BITS as u8 - width)
-+ };
-+
- let mut table = [0u32; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc32(poly, reflect, i as u8);
-+ table[i] = crc32(poly, reflect, i as u32);
- i += 1;
- }
- table
- }
--pub(crate) const fn crc64_table(poly: u64, reflect: bool) -> [u64; 256] {
-+
-+pub(crate) const fn crc64_table(width: u8, poly: u64, reflect: bool) -> [u64; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u64::BITS as u8 - width)
-+ } else {
-+ poly << (u64::BITS as u8 - width)
-+ };
-+
- let mut table = [0u64; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc64(poly, reflect, i as u8);
-+ table[i] = crc64(poly, reflect, i as u64);
- i += 1;
- }
- table
-diff --git a/src/util.rs b/src/util.rs
-index c378c23..b69f89e 100644
---- a/src/util.rs
-+++ b/src/util.rs
-@@ -1,63 +1,75 @@
--pub(crate) const fn crc8(poly: u8, reflect: bool, mut byte: u8) -> u8 {
-+pub(crate) const fn crc8(poly: u8, reflect: bool, mut value: u8) -> u8 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = byte;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 7) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u8::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u8::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc16(poly: u16, reflect: bool, mut byte: u8) -> u16 {
-+pub(crate) const fn crc16(poly: u16, reflect: bool, mut value: u16) -> u16 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u16) << 8;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 15) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u16::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u16::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc32(poly: u32, reflect: bool, mut byte: u8) -> u32 {
-+pub(crate) const fn crc32(poly: u32, reflect: bool, mut value: u32) -> u32 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u32) << 24;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 31) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u32::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u32::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc64(poly: u64, reflect: bool, mut byte: u8) -> u64 {
-+pub(crate) const fn crc64(poly: u64, reflect: bool, mut value: u64) -> u64 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u64) << 56;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 63) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u64::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u64::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-diff --git a/tests/crc.rs b/tests/crc.rs
-index 7ee3238..dc89eb5 100644
---- a/tests/crc.rs
-+++ b/tests/crc.rs
-@@ -2,14 +2,53 @@ use crc::*;
-
- const INIT: &[u8] = b"123456789";
-
-+const INIT_PART1: &[u8] = b"1234";
-+const INIT_PART2: &[u8] = b"56789";
-+
- #[test]
- fn crc_8() {
-- let algs = &[CRC_8_AUTOSAR, CRC_8_BLUETOOTH, CRC_8_SMBUS, CRC_8_DARC];
-- for alg in algs {
-+ let algs = &[
-+ CRC_3_GSM,
-+ CRC_3_ROHC,
-+ CRC_4_G_704,
-+ CRC_4_INTERLAKEN,
-+ CRC_5_EPC_C1G2,
-+ CRC_5_G_704,
-+ CRC_5_USB,
-+ CRC_6_CDMA2000_A,
-+ CRC_6_CDMA2000_B,
-+ CRC_6_DARC,
-+ CRC_6_G_704,
-+ CRC_6_GSM,
-+ CRC_7_MMC,
-+ CRC_7_ROHC,
-+ CRC_7_UMTS,
-+ CRC_8_AUTOSAR,
-+ CRC_8_BLUETOOTH,
-+ CRC_8_CDMA2000,
-+ CRC_8_DARC,
-+ CRC_8_DVB_S2,
-+ CRC_8_GSM_A,
-+ CRC_8_GSM_B,
-+ CRC_8_I_432_1,
-+ CRC_8_I_CODE,
-+ CRC_8_LTE,
-+ CRC_8_MAXIM_DOW,
-+ CRC_8_MIFARE_MAD,
-+ CRC_8_NRSC_5,
-+ CRC_8_OPENSAFETY,
-+ CRC_8_ROHC,
-+ CRC_8_SAE_J1850,
-+ CRC_8_SMBUS,
-+ CRC_8_TECH_3250,
-+ CRC_8_WCDMA,
-+ ];
-+ for alg in algs.iter() {
- let crc = Crc::<u8>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-@@ -17,19 +56,57 @@ fn crc_8() {
- #[test]
- fn crc_16() {
- let algs = &[
-- CRC_16_IBM_SDLC,
-- CRC_16_USB,
-+ CRC_10_ATM,
-+ CRC_10_CDMA2000,
-+ CRC_10_GSM,
-+ CRC_11_FLEXRAY,
-+ CRC_11_UMTS,
-+ CRC_12_CDMA2000,
-+ CRC_12_DECT,
-+ CRC_12_GSM,
-+ CRC_12_UMTS,
-+ CRC_13_BBC,
-+ CRC_14_DARC,
-+ CRC_14_GSM,
-+ CRC_15_CAN,
-+ CRC_15_MPT1327,
- CRC_16_ARC,
- CRC_16_CDMA2000,
-+ CRC_16_CMS,
-+ CRC_16_DDS_110,
-+ CRC_16_DECT_R,
-+ CRC_16_DECT_X,
-+ CRC_16_DNP,
-+ CRC_16_EN_13757,
-+ CRC_16_GENIBUS,
-+ CRC_16_GSM,
- CRC_16_IBM_3740,
- CRC_16_IBM_SDLC,
-+ CRC_16_ISO_IEC_14443_3_A,
- CRC_16_KERMIT,
-+ CRC_16_LJ1200,
-+ CRC_16_MAXIM_DOW,
-+ CRC_16_MCRF4XX,
-+ CRC_16_MODBUS,
-+ CRC_16_NRSC_5,
-+ CRC_16_OPENSAFETY_A,
-+ CRC_16_OPENSAFETY_B,
-+ CRC_16_PROFIBUS,
-+ CRC_16_RIELLO,
-+ CRC_16_SPI_FUJITSU,
-+ CRC_16_T10_DIF,
-+ CRC_16_TELEDISK,
-+ CRC_16_TMS37157,
-+ CRC_16_UMTS,
-+ CRC_16_USB,
-+ CRC_16_XMODEM,
- ];
-- for alg in algs {
-+ for alg in algs.iter() {
- let crc = Crc::<u16>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-@@ -37,29 +114,55 @@ fn crc_16() {
- #[test]
- fn crc_32() {
- let algs = &[
-- CRC_32_ISCSI,
-+ CRC_17_CAN_FD,
-+ CRC_21_CAN_FD,
-+ CRC_24_BLE,
-+ CRC_24_FLEXRAY_A,
-+ CRC_24_FLEXRAY_B,
-+ CRC_24_INTERLAKEN,
-+ CRC_24_LTE_A,
-+ CRC_24_LTE_B,
-+ CRC_24_OPENPGP,
-+ CRC_24_OS_9,
-+ CRC_30_CDMA,
-+ CRC_31_PHILIPS,
-+ CRC_32_AIXM,
- CRC_32_AUTOSAR,
-+ CRC_32_BASE91_D,
- CRC_32_BZIP2,
-+ CRC_32_CD_ROM_EDC,
-+ CRC_32_CKSUM,
- CRC_32_ISCSI,
- CRC_32_ISO_HDLC,
-+ CRC_32_JAMCRC,
-+ CRC_32_MPEG_2,
-+ CRC_32_XFER,
- ];
- for alg in algs {
- let crc = Crc::<u32>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-
- #[test]
- fn crc_64() {
-- let algs = &[CRC_64_ECMA_182, CRC_64_GO_ISO, CRC_64_WE, CRC_64_XZ];
-+ let algs = &[
-+ CRC_40_GSM,
-+ CRC_64_ECMA_182,
-+ CRC_64_GO_ISO,
-+ CRC_64_WE,
-+ CRC_64_XZ,
-+ ];
- for alg in algs {
- let crc = Crc::<u64>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
diff --git a/README.md b/README.md
deleted file mode 100644
index 027cd63..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# rust-crc
-
-The rust-crc package
\ No newline at end of file
diff --git a/crc-fix-metadata.diff b/crc-fix-metadata.diff
deleted file mode 100644
index aa444fc..0000000
--- a/crc-fix-metadata.diff
+++ /dev/null
@@ -1,8 +0,0 @@
---- crc-2.1.0/Cargo.toml 1970-01-01T00:00:01+00:00
-+++ crc-2.1.0/Cargo.toml 2021-12-15T11:44:35.308461+00:00
-@@ -22,4 +22,4 @@
- license = "MIT OR Apache-2.0"
- repository = "https://github.com/mrhooray/crc-rs.git"
- [dependencies.crc-catalog]
--version = "1.1.1"
-+version = "2"
diff --git a/rust-crc.spec b/rust-crc.spec
index 0dde5ee..1296434 100644
--- a/rust-crc.spec
+++ b/rust-crc.spec
@@ -1,30 +1,22 @@
-# Generated by rust2rpm 20
+# Generated by rust2rpm 24
%bcond_without check
%global debug_package %{nil}
%global crate crc
-Name: rust-%{crate}
-Version: 2.1.0
+Name: rust-crc
+Version: 3.0.1
Release: %autorelease
-Summary: Rust implementation of CRC(16, 32, 64) with support of various standards
+Summary: Rust implementation of CRC with support of various standards
-# Upstream license specification: MIT OR Apache-2.0
-License: MIT or ASL 2.0
+License: MIT OR Apache-2.0
URL: https://crates.io/crates/crc
Source: %{crates_source}
-# Initial patched metadata
-# * bump crc-catalog from 1.1.1 to 2
-Patch0: crc-fix-metadata.diff
-# * port to crc-catalog 2: https://github.com/mrhooray/crc-rs/commit/384fb68
-Patch1: 384fb68.patch
-ExclusiveArch: %{rust_arches}
-
-BuildRequires: rust-packaging
+BuildRequires: rust-packaging >= 21
%global _description %{expand:
-Rust implementation of CRC(16, 32, 64) with support of various standards.}
+Rust implementation of CRC with support of various standards.}
%description %{_description}
@@ -38,9 +30,10 @@ This package contains library source intended for building other packages which
use the "%{crate}" crate.
%files devel
-%license LICENSE-APACHE LICENSE-MIT
-%doc README.md
-%{cargo_registry}/%{crate}-%{version_no_tilde}/
+%license %{crate_instdir}/LICENSE-APACHE
+%license %{crate_instdir}/LICENSE-MIT
+%doc %{crate_instdir}/README.md
+%{crate_instdir}/
%package -n %{name}+default-devel
Summary: %{summary}
@@ -52,7 +45,7 @@ This package contains library source intended for building other packages which
use the "default" feature of the "%{crate}" crate.
%files -n %{name}+default-devel
-%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml
+%ghost %{crate_instdir}/Cargo.toml
%prep
%autosetup -n %{crate}-%{version_no_tilde} -p1
diff --git a/sources b/sources
index 9b5c89c..548bd43 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (crc-2.1.0.crate) = 45109925b4da84c9c60f0b6c2f79bde09a0dcdb4b901e3e0856a763b779ea02d251a1b150d6e588848ee517d8b63e16ee3b93522a0ccf8c10e4fd1f71345bca5
+SHA512 (crc-3.0.1.crate) = aabe9d4058fb4710405146e978ec5881bce5ce8971618b69a7ff873b0fff15fc78e5c48ff0136ca6d37663a53905bc3c5daa0ed3a2ed4d8d721e90c3b0ec28a5
commit 959d1d9e1c85880364641299cfd9e8bb6c93eec6
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Fri Jan 20 22:13:38 2023 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng(a)fedoraproject.org>
commit 4c237d60002e7fe12eded573601868d35f7f6071
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Sat Jul 23 03:28:36 2022 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng(a)fedoraproject.org>
1 year, 2 months
Architecture specific change in rpms/rust-crc.git
by githook-noreply@fedoraproject.org
The package rpms/rust-crc.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/rust-crc.git/commit/?id=307342842....
Change:
-ExclusiveArch: %{rust_arches}
Thanks.
Full change:
============
commit 307342842744722bfb19e1c854d846fdddee7ca5
Author: Fabio Valentini <decathorpe(a)gmail.com>
Date: Tue Feb 28 22:13:02 2023 +0100
Update to version 3.0.1; Fixes RHBZ#2078053
diff --git a/.gitignore b/.gitignore
index 861033e..1ced20b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/crc-1.8.1.crate
/crc-1.9.0.crate
/crc-2.1.0.crate
+/crc-3.0.1.crate
diff --git a/384fb68.patch b/384fb68.patch
deleted file mode 100644
index 10646c2..0000000
--- a/384fb68.patch
+++ /dev/null
@@ -1,674 +0,0 @@
-From 384fb68b7af4a06bedbddf2624c715070306a29a Mon Sep 17 00:00:00 2001
-From: Bartel Sielski <bartel.sielski(a)gmail.com>
-Date: Sun, 17 Oct 2021 18:06:46 +0200
-Subject: [PATCH] Add support for CRC algorithms which have a non-power of 2
- width
-
----
- Cargo.toml.orig | 2 +-
- README.md | 1 +
- benches/bench.rs | 20 +++++++-
- src/crc16.rs | 15 ++++--
- src/crc32.rs | 15 ++++--
- src/crc64.rs | 15 ++++--
- src/crc8.rs | 9 ++--
- src/lib.rs | 1 +
- src/table.rs | 45 ++++++++++++++---
- src/util.rs | 100 ++++++++++++++++++++-----------------
- tests/crc.rs | 125 ++++++++++++++++++++++++++++++++++++++++++-----
- 11 files changed, 266 insertions(+), 82 deletions(-)
-
-diff --git a/Cargo.toml.orig b/Cargo.toml.orig
-index b787734..3f24e44 100644
---- a/Cargo.toml.orig
-+++ b/Cargo.toml.orig
-@@ -15,4 +15,4 @@ categories = ["algorithms", "no-std"]
- edition = "2018"
-
- [dependencies]
--crc-catalog = "1.1.1"
-+crc-catalog = "2.0.1"
-diff --git a/README.md b/README.md
-index eefae7b..88bad96 100644
---- a/README.md
-+++ b/README.md
-@@ -27,6 +27,7 @@ assert_eq!(CASTAGNOLI.checksum(b"123456789"), 0xe3069283);
-
- // use custom algorithm
- const CUSTOM_ALG: Algorithm<u16> = Algorithm {
-+ width: 16,
- poly: 0x8005,
- init: 0xffff,
- refin: false,
-diff --git a/benches/bench.rs b/benches/bench.rs
-index 520e3f7..a5fc4b7 100644
---- a/benches/bench.rs
-+++ b/benches/bench.rs
-@@ -5,6 +5,7 @@ use criterion::{Benchmark, Criterion, Throughput};
- pub const BLUETOOTH: Crc<u8> = Crc::<u8>::new(&CRC_8_BLUETOOTH);
- pub const X25: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_SDLC);
- pub const CASTAGNOLI: Crc<u32> = Crc::<u32>::new(&CRC_32_ISCSI);
-+pub const GSM_40: Crc<u64> = Crc::<u64>::new(&CRC_40_GSM);
- pub const ECMA: Crc<u64> = Crc::<u64>::new(&CRC_64_ECMA_182);
-
- fn crc8(c: &mut Criterion) {
-@@ -37,6 +38,16 @@ fn crc32(c: &mut Criterion) {
- );
- }
-
-+fn crc40(c: &mut Criterion) {
-+ let mut digest = GSM_40.digest();
-+ let bytes = vec![0u8; 1_000_000];
-+ c.bench(
-+ "crc40",
-+ Benchmark::new("crc40", move |b| b.iter(|| digest.update(&bytes)))
-+ .throughput(Throughput::Bytes(1_000_000)),
-+ );
-+}
-+
- fn crc64(c: &mut Criterion) {
- let mut digest = ECMA.digest();
- let bytes = vec![0u8; 1_000_000];
-@@ -50,5 +61,12 @@ fn crc64(c: &mut Criterion) {
- criterion_group!(crc8_benches, crc8);
- criterion_group!(crc16_benches, crc16);
- criterion_group!(crc32_benches, crc32);
-+criterion_group!(crc40_benches, crc40);
- criterion_group!(crc64_benches, crc64);
--criterion_main!(crc8_benches, crc16_benches, crc32_benches, crc64_benches);
-+criterion_main!(
-+ crc8_benches,
-+ crc16_benches,
-+ crc32_benches,
-+ crc40_benches,
-+ crc64_benches,
-+);
-diff --git a/src/crc16.rs b/src/crc16.rs
-index d6474da..b88669f 100644
---- a/src/crc16.rs
-+++ b/src/crc16.rs
-@@ -3,7 +3,7 @@ use crate::table::crc16_table;
-
- impl Crc<u16> {
- pub const fn new(algorithm: &'static Algorithm<u16>) -> Self {
-- let table = crc16_table(algorithm.poly, algorithm.refin);
-+ let table = crc16_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u16> {
-
- const fn init(&self) -> u16 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u16::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u16::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u16> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u16) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u16;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u16 ^ (crc >> 8)) ^ (crc << 8);
-+ let table_index = (crc >> (u16::BITS - 8)) ^ bytes[i] as u16;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u16> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u16::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc32.rs b/src/crc32.rs
-index 6ac49cf..d7e7767 100644
---- a/src/crc32.rs
-+++ b/src/crc32.rs
-@@ -3,7 +3,7 @@ use crate::table::crc32_table;
-
- impl Crc<u32> {
- pub const fn new(algorithm: &'static Algorithm<u32>) -> Self {
-- let table = crc32_table(algorithm.poly, algorithm.refin);
-+ let table = crc32_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u32> {
-
- const fn init(&self) -> u32 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u32::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u32::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u32> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u32) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u32;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u32 ^ (crc >> 24)) ^ (crc << 8);
-+ let table_index = (crc >> (u32::BITS - 8)) ^ bytes[i] as u32;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u32> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u32::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc64.rs b/src/crc64.rs
-index b405cd9..52cb0af 100644
---- a/src/crc64.rs
-+++ b/src/crc64.rs
-@@ -3,7 +3,7 @@ use crate::table::crc64_table;
-
- impl Crc<u64> {
- pub const fn new(algorithm: &'static Algorithm<u64>) -> Self {
-- let table = crc64_table(algorithm.poly, algorithm.refin);
-+ let table = crc64_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u64> {
-
- const fn init(&self) -> u64 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u64::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u64::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u64> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u64) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u64;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u64 ^ (crc >> 56)) ^ (crc << 8);
-+ let table_index = (crc >> (u64::BITS - 8)) ^ bytes[i] as u64;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u64> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u64::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc8.rs b/src/crc8.rs
-index f37935d..0cf45c1 100644
---- a/src/crc8.rs
-+++ b/src/crc8.rs
-@@ -3,7 +3,7 @@ use crate::table::crc8_table;
-
- impl Crc<u8> {
- pub const fn new(algorithm: &'static Algorithm<u8>) -> Self {
-- let table = crc8_table(algorithm.poly, algorithm.refin);
-+ let table = crc8_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u8> {
-
- const fn init(&self) -> u8 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u8::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u8::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -40,6 +40,9 @@ impl Crc<u8> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u8::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/lib.rs b/src/lib.rs
-index 7944e19..99a30f6 100644
---- a/src/lib.rs
-+++ b/src/lib.rs
-@@ -14,6 +14,7 @@
- //!
- //! // use custom algorithm
- //! const CUSTOM_ALG: Algorithm<u16> = Algorithm {
-+//! width: 16,
- //! poly: 0x8005,
- //! init: 0xffff,
- //! refin: false,
-diff --git a/src/table.rs b/src/table.rs
-index 1e7ad75..a921ec2 100644
---- a/src/table.rs
-+++ b/src/table.rs
-@@ -1,6 +1,13 @@
- use crate::util::*;
-
--pub(crate) const fn crc8_table(poly: u8, reflect: bool) -> [u8; 256] {
-+pub(crate) const fn crc8_table(width: u8, poly: u8, reflect: bool) -> [u8; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u8::BITS as u8 - width)
-+ } else {
-+ poly << (u8::BITS as u8 - width)
-+ };
-+
- let mut table = [0u8; 256];
- let mut i = 0;
- while i < table.len() {
-@@ -9,29 +16,53 @@ pub(crate) const fn crc8_table(poly: u8, reflect: bool) -> [u8; 256] {
- }
- table
- }
--pub(crate) const fn crc16_table(poly: u16, reflect: bool) -> [u16; 256] {
-+
-+pub(crate) const fn crc16_table(width: u8, poly: u16, reflect: bool) -> [u16; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u16::BITS as u8 - width)
-+ } else {
-+ poly << (u16::BITS as u8 - width)
-+ };
-+
- let mut table = [0u16; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc16(poly, reflect, i as u8);
-+ table[i] = crc16(poly, reflect, i as u16);
- i += 1;
- }
- table
- }
--pub(crate) const fn crc32_table(poly: u32, reflect: bool) -> [u32; 256] {
-+
-+pub(crate) const fn crc32_table(width: u8, poly: u32, reflect: bool) -> [u32; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u32::BITS as u8 - width)
-+ } else {
-+ poly << (u32::BITS as u8 - width)
-+ };
-+
- let mut table = [0u32; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc32(poly, reflect, i as u8);
-+ table[i] = crc32(poly, reflect, i as u32);
- i += 1;
- }
- table
- }
--pub(crate) const fn crc64_table(poly: u64, reflect: bool) -> [u64; 256] {
-+
-+pub(crate) const fn crc64_table(width: u8, poly: u64, reflect: bool) -> [u64; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u64::BITS as u8 - width)
-+ } else {
-+ poly << (u64::BITS as u8 - width)
-+ };
-+
- let mut table = [0u64; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc64(poly, reflect, i as u8);
-+ table[i] = crc64(poly, reflect, i as u64);
- i += 1;
- }
- table
-diff --git a/src/util.rs b/src/util.rs
-index c378c23..b69f89e 100644
---- a/src/util.rs
-+++ b/src/util.rs
-@@ -1,63 +1,75 @@
--pub(crate) const fn crc8(poly: u8, reflect: bool, mut byte: u8) -> u8 {
-+pub(crate) const fn crc8(poly: u8, reflect: bool, mut value: u8) -> u8 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = byte;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 7) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u8::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u8::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc16(poly: u16, reflect: bool, mut byte: u8) -> u16 {
-+pub(crate) const fn crc16(poly: u16, reflect: bool, mut value: u16) -> u16 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u16) << 8;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 15) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u16::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u16::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc32(poly: u32, reflect: bool, mut byte: u8) -> u32 {
-+pub(crate) const fn crc32(poly: u32, reflect: bool, mut value: u32) -> u32 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u32) << 24;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 31) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u32::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u32::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc64(poly: u64, reflect: bool, mut byte: u8) -> u64 {
-+pub(crate) const fn crc64(poly: u64, reflect: bool, mut value: u64) -> u64 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u64) << 56;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 63) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u64::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u64::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-diff --git a/tests/crc.rs b/tests/crc.rs
-index 7ee3238..dc89eb5 100644
---- a/tests/crc.rs
-+++ b/tests/crc.rs
-@@ -2,14 +2,53 @@ use crc::*;
-
- const INIT: &[u8] = b"123456789";
-
-+const INIT_PART1: &[u8] = b"1234";
-+const INIT_PART2: &[u8] = b"56789";
-+
- #[test]
- fn crc_8() {
-- let algs = &[CRC_8_AUTOSAR, CRC_8_BLUETOOTH, CRC_8_SMBUS, CRC_8_DARC];
-- for alg in algs {
-+ let algs = &[
-+ CRC_3_GSM,
-+ CRC_3_ROHC,
-+ CRC_4_G_704,
-+ CRC_4_INTERLAKEN,
-+ CRC_5_EPC_C1G2,
-+ CRC_5_G_704,
-+ CRC_5_USB,
-+ CRC_6_CDMA2000_A,
-+ CRC_6_CDMA2000_B,
-+ CRC_6_DARC,
-+ CRC_6_G_704,
-+ CRC_6_GSM,
-+ CRC_7_MMC,
-+ CRC_7_ROHC,
-+ CRC_7_UMTS,
-+ CRC_8_AUTOSAR,
-+ CRC_8_BLUETOOTH,
-+ CRC_8_CDMA2000,
-+ CRC_8_DARC,
-+ CRC_8_DVB_S2,
-+ CRC_8_GSM_A,
-+ CRC_8_GSM_B,
-+ CRC_8_I_432_1,
-+ CRC_8_I_CODE,
-+ CRC_8_LTE,
-+ CRC_8_MAXIM_DOW,
-+ CRC_8_MIFARE_MAD,
-+ CRC_8_NRSC_5,
-+ CRC_8_OPENSAFETY,
-+ CRC_8_ROHC,
-+ CRC_8_SAE_J1850,
-+ CRC_8_SMBUS,
-+ CRC_8_TECH_3250,
-+ CRC_8_WCDMA,
-+ ];
-+ for alg in algs.iter() {
- let crc = Crc::<u8>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-@@ -17,19 +56,57 @@ fn crc_8() {
- #[test]
- fn crc_16() {
- let algs = &[
-- CRC_16_IBM_SDLC,
-- CRC_16_USB,
-+ CRC_10_ATM,
-+ CRC_10_CDMA2000,
-+ CRC_10_GSM,
-+ CRC_11_FLEXRAY,
-+ CRC_11_UMTS,
-+ CRC_12_CDMA2000,
-+ CRC_12_DECT,
-+ CRC_12_GSM,
-+ CRC_12_UMTS,
-+ CRC_13_BBC,
-+ CRC_14_DARC,
-+ CRC_14_GSM,
-+ CRC_15_CAN,
-+ CRC_15_MPT1327,
- CRC_16_ARC,
- CRC_16_CDMA2000,
-+ CRC_16_CMS,
-+ CRC_16_DDS_110,
-+ CRC_16_DECT_R,
-+ CRC_16_DECT_X,
-+ CRC_16_DNP,
-+ CRC_16_EN_13757,
-+ CRC_16_GENIBUS,
-+ CRC_16_GSM,
- CRC_16_IBM_3740,
- CRC_16_IBM_SDLC,
-+ CRC_16_ISO_IEC_14443_3_A,
- CRC_16_KERMIT,
-+ CRC_16_LJ1200,
-+ CRC_16_MAXIM_DOW,
-+ CRC_16_MCRF4XX,
-+ CRC_16_MODBUS,
-+ CRC_16_NRSC_5,
-+ CRC_16_OPENSAFETY_A,
-+ CRC_16_OPENSAFETY_B,
-+ CRC_16_PROFIBUS,
-+ CRC_16_RIELLO,
-+ CRC_16_SPI_FUJITSU,
-+ CRC_16_T10_DIF,
-+ CRC_16_TELEDISK,
-+ CRC_16_TMS37157,
-+ CRC_16_UMTS,
-+ CRC_16_USB,
-+ CRC_16_XMODEM,
- ];
-- for alg in algs {
-+ for alg in algs.iter() {
- let crc = Crc::<u16>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-@@ -37,29 +114,55 @@ fn crc_16() {
- #[test]
- fn crc_32() {
- let algs = &[
-- CRC_32_ISCSI,
-+ CRC_17_CAN_FD,
-+ CRC_21_CAN_FD,
-+ CRC_24_BLE,
-+ CRC_24_FLEXRAY_A,
-+ CRC_24_FLEXRAY_B,
-+ CRC_24_INTERLAKEN,
-+ CRC_24_LTE_A,
-+ CRC_24_LTE_B,
-+ CRC_24_OPENPGP,
-+ CRC_24_OS_9,
-+ CRC_30_CDMA,
-+ CRC_31_PHILIPS,
-+ CRC_32_AIXM,
- CRC_32_AUTOSAR,
-+ CRC_32_BASE91_D,
- CRC_32_BZIP2,
-+ CRC_32_CD_ROM_EDC,
-+ CRC_32_CKSUM,
- CRC_32_ISCSI,
- CRC_32_ISO_HDLC,
-+ CRC_32_JAMCRC,
-+ CRC_32_MPEG_2,
-+ CRC_32_XFER,
- ];
- for alg in algs {
- let crc = Crc::<u32>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-
- #[test]
- fn crc_64() {
-- let algs = &[CRC_64_ECMA_182, CRC_64_GO_ISO, CRC_64_WE, CRC_64_XZ];
-+ let algs = &[
-+ CRC_40_GSM,
-+ CRC_64_ECMA_182,
-+ CRC_64_GO_ISO,
-+ CRC_64_WE,
-+ CRC_64_XZ,
-+ ];
- for alg in algs {
- let crc = Crc::<u64>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
diff --git a/README.md b/README.md
deleted file mode 100644
index 027cd63..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# rust-crc
-
-The rust-crc package
\ No newline at end of file
diff --git a/crc-fix-metadata.diff b/crc-fix-metadata.diff
deleted file mode 100644
index aa444fc..0000000
--- a/crc-fix-metadata.diff
+++ /dev/null
@@ -1,8 +0,0 @@
---- crc-2.1.0/Cargo.toml 1970-01-01T00:00:01+00:00
-+++ crc-2.1.0/Cargo.toml 2021-12-15T11:44:35.308461+00:00
-@@ -22,4 +22,4 @@
- license = "MIT OR Apache-2.0"
- repository = "https://github.com/mrhooray/crc-rs.git"
- [dependencies.crc-catalog]
--version = "1.1.1"
-+version = "2"
diff --git a/rust-crc.spec b/rust-crc.spec
index 0dde5ee..1296434 100644
--- a/rust-crc.spec
+++ b/rust-crc.spec
@@ -1,30 +1,22 @@
-# Generated by rust2rpm 20
+# Generated by rust2rpm 24
%bcond_without check
%global debug_package %{nil}
%global crate crc
-Name: rust-%{crate}
-Version: 2.1.0
+Name: rust-crc
+Version: 3.0.1
Release: %autorelease
-Summary: Rust implementation of CRC(16, 32, 64) with support of various standards
+Summary: Rust implementation of CRC with support of various standards
-# Upstream license specification: MIT OR Apache-2.0
-License: MIT or ASL 2.0
+License: MIT OR Apache-2.0
URL: https://crates.io/crates/crc
Source: %{crates_source}
-# Initial patched metadata
-# * bump crc-catalog from 1.1.1 to 2
-Patch0: crc-fix-metadata.diff
-# * port to crc-catalog 2: https://github.com/mrhooray/crc-rs/commit/384fb68
-Patch1: 384fb68.patch
-ExclusiveArch: %{rust_arches}
-
-BuildRequires: rust-packaging
+BuildRequires: rust-packaging >= 21
%global _description %{expand:
-Rust implementation of CRC(16, 32, 64) with support of various standards.}
+Rust implementation of CRC with support of various standards.}
%description %{_description}
@@ -38,9 +30,10 @@ This package contains library source intended for building other packages which
use the "%{crate}" crate.
%files devel
-%license LICENSE-APACHE LICENSE-MIT
-%doc README.md
-%{cargo_registry}/%{crate}-%{version_no_tilde}/
+%license %{crate_instdir}/LICENSE-APACHE
+%license %{crate_instdir}/LICENSE-MIT
+%doc %{crate_instdir}/README.md
+%{crate_instdir}/
%package -n %{name}+default-devel
Summary: %{summary}
@@ -52,7 +45,7 @@ This package contains library source intended for building other packages which
use the "default" feature of the "%{crate}" crate.
%files -n %{name}+default-devel
-%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml
+%ghost %{crate_instdir}/Cargo.toml
%prep
%autosetup -n %{crate}-%{version_no_tilde} -p1
diff --git a/sources b/sources
index 9b5c89c..548bd43 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (crc-2.1.0.crate) = 45109925b4da84c9c60f0b6c2f79bde09a0dcdb4b901e3e0856a763b779ea02d251a1b150d6e588848ee517d8b63e16ee3b93522a0ccf8c10e4fd1f71345bca5
+SHA512 (crc-3.0.1.crate) = aabe9d4058fb4710405146e978ec5881bce5ce8971618b69a7ff873b0fff15fc78e5c48ff0136ca6d37663a53905bc3c5daa0ed3a2ed4d8d721e90c3b0ec28a5
commit 959d1d9e1c85880364641299cfd9e8bb6c93eec6
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Fri Jan 20 22:13:38 2023 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng(a)fedoraproject.org>
1 year, 2 months
Architecture specific change in rpms/rust-crc.git
by githook-noreply@fedoraproject.org
The package rpms/rust-crc.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/rust-crc.git/commit/?id=307342842....
Change:
-ExclusiveArch: %{rust_arches}
Thanks.
Full change:
============
commit 307342842744722bfb19e1c854d846fdddee7ca5
Author: Fabio Valentini <decathorpe(a)gmail.com>
Date: Tue Feb 28 22:13:02 2023 +0100
Update to version 3.0.1; Fixes RHBZ#2078053
diff --git a/.gitignore b/.gitignore
index 861033e..1ced20b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/crc-1.8.1.crate
/crc-1.9.0.crate
/crc-2.1.0.crate
+/crc-3.0.1.crate
diff --git a/384fb68.patch b/384fb68.patch
deleted file mode 100644
index 10646c2..0000000
--- a/384fb68.patch
+++ /dev/null
@@ -1,674 +0,0 @@
-From 384fb68b7af4a06bedbddf2624c715070306a29a Mon Sep 17 00:00:00 2001
-From: Bartel Sielski <bartel.sielski(a)gmail.com>
-Date: Sun, 17 Oct 2021 18:06:46 +0200
-Subject: [PATCH] Add support for CRC algorithms which have a non-power of 2
- width
-
----
- Cargo.toml.orig | 2 +-
- README.md | 1 +
- benches/bench.rs | 20 +++++++-
- src/crc16.rs | 15 ++++--
- src/crc32.rs | 15 ++++--
- src/crc64.rs | 15 ++++--
- src/crc8.rs | 9 ++--
- src/lib.rs | 1 +
- src/table.rs | 45 ++++++++++++++---
- src/util.rs | 100 ++++++++++++++++++++-----------------
- tests/crc.rs | 125 ++++++++++++++++++++++++++++++++++++++++++-----
- 11 files changed, 266 insertions(+), 82 deletions(-)
-
-diff --git a/Cargo.toml.orig b/Cargo.toml.orig
-index b787734..3f24e44 100644
---- a/Cargo.toml.orig
-+++ b/Cargo.toml.orig
-@@ -15,4 +15,4 @@ categories = ["algorithms", "no-std"]
- edition = "2018"
-
- [dependencies]
--crc-catalog = "1.1.1"
-+crc-catalog = "2.0.1"
-diff --git a/README.md b/README.md
-index eefae7b..88bad96 100644
---- a/README.md
-+++ b/README.md
-@@ -27,6 +27,7 @@ assert_eq!(CASTAGNOLI.checksum(b"123456789"), 0xe3069283);
-
- // use custom algorithm
- const CUSTOM_ALG: Algorithm<u16> = Algorithm {
-+ width: 16,
- poly: 0x8005,
- init: 0xffff,
- refin: false,
-diff --git a/benches/bench.rs b/benches/bench.rs
-index 520e3f7..a5fc4b7 100644
---- a/benches/bench.rs
-+++ b/benches/bench.rs
-@@ -5,6 +5,7 @@ use criterion::{Benchmark, Criterion, Throughput};
- pub const BLUETOOTH: Crc<u8> = Crc::<u8>::new(&CRC_8_BLUETOOTH);
- pub const X25: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_SDLC);
- pub const CASTAGNOLI: Crc<u32> = Crc::<u32>::new(&CRC_32_ISCSI);
-+pub const GSM_40: Crc<u64> = Crc::<u64>::new(&CRC_40_GSM);
- pub const ECMA: Crc<u64> = Crc::<u64>::new(&CRC_64_ECMA_182);
-
- fn crc8(c: &mut Criterion) {
-@@ -37,6 +38,16 @@ fn crc32(c: &mut Criterion) {
- );
- }
-
-+fn crc40(c: &mut Criterion) {
-+ let mut digest = GSM_40.digest();
-+ let bytes = vec![0u8; 1_000_000];
-+ c.bench(
-+ "crc40",
-+ Benchmark::new("crc40", move |b| b.iter(|| digest.update(&bytes)))
-+ .throughput(Throughput::Bytes(1_000_000)),
-+ );
-+}
-+
- fn crc64(c: &mut Criterion) {
- let mut digest = ECMA.digest();
- let bytes = vec![0u8; 1_000_000];
-@@ -50,5 +61,12 @@ fn crc64(c: &mut Criterion) {
- criterion_group!(crc8_benches, crc8);
- criterion_group!(crc16_benches, crc16);
- criterion_group!(crc32_benches, crc32);
-+criterion_group!(crc40_benches, crc40);
- criterion_group!(crc64_benches, crc64);
--criterion_main!(crc8_benches, crc16_benches, crc32_benches, crc64_benches);
-+criterion_main!(
-+ crc8_benches,
-+ crc16_benches,
-+ crc32_benches,
-+ crc40_benches,
-+ crc64_benches,
-+);
-diff --git a/src/crc16.rs b/src/crc16.rs
-index d6474da..b88669f 100644
---- a/src/crc16.rs
-+++ b/src/crc16.rs
-@@ -3,7 +3,7 @@ use crate::table::crc16_table;
-
- impl Crc<u16> {
- pub const fn new(algorithm: &'static Algorithm<u16>) -> Self {
-- let table = crc16_table(algorithm.poly, algorithm.refin);
-+ let table = crc16_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u16> {
-
- const fn init(&self) -> u16 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u16::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u16::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u16> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u16) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u16;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u16 ^ (crc >> 8)) ^ (crc << 8);
-+ let table_index = (crc >> (u16::BITS - 8)) ^ bytes[i] as u16;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u16> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u16::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc32.rs b/src/crc32.rs
-index 6ac49cf..d7e7767 100644
---- a/src/crc32.rs
-+++ b/src/crc32.rs
-@@ -3,7 +3,7 @@ use crate::table::crc32_table;
-
- impl Crc<u32> {
- pub const fn new(algorithm: &'static Algorithm<u32>) -> Self {
-- let table = crc32_table(algorithm.poly, algorithm.refin);
-+ let table = crc32_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u32> {
-
- const fn init(&self) -> u32 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u32::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u32::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u32> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u32) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u32;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u32 ^ (crc >> 24)) ^ (crc << 8);
-+ let table_index = (crc >> (u32::BITS - 8)) ^ bytes[i] as u32;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u32> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u32::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc64.rs b/src/crc64.rs
-index b405cd9..52cb0af 100644
---- a/src/crc64.rs
-+++ b/src/crc64.rs
-@@ -3,7 +3,7 @@ use crate::table::crc64_table;
-
- impl Crc<u64> {
- pub const fn new(algorithm: &'static Algorithm<u64>) -> Self {
-- let table = crc64_table(algorithm.poly, algorithm.refin);
-+ let table = crc64_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u64> {
-
- const fn init(&self) -> u64 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u64::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u64::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -29,12 +29,14 @@ impl Crc<u64> {
- let mut i = 0;
- if self.algorithm.refin {
- while i < bytes.len() {
-- crc = self.table_entry(crc ^ bytes[i] as u64) ^ (crc >> 8);
-+ let table_index = crc ^ bytes[i] as u64;
-+ crc = self.table_entry(table_index) ^ (crc >> 8);
- i += 1;
- }
- } else {
- while i < bytes.len() {
-- crc = self.table_entry(bytes[i] as u64 ^ (crc >> 56)) ^ (crc << 8);
-+ let table_index = (crc >> (u64::BITS - 8)) ^ bytes[i] as u64;
-+ crc = self.table_entry(table_index) ^ (crc << 8);
- i += 1;
- }
- }
-@@ -45,6 +47,9 @@ impl Crc<u64> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u64::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/crc8.rs b/src/crc8.rs
-index f37935d..0cf45c1 100644
---- a/src/crc8.rs
-+++ b/src/crc8.rs
-@@ -3,7 +3,7 @@ use crate::table::crc8_table;
-
- impl Crc<u8> {
- pub const fn new(algorithm: &'static Algorithm<u8>) -> Self {
-- let table = crc8_table(algorithm.poly, algorithm.refin);
-+ let table = crc8_table(algorithm.width, algorithm.poly, algorithm.refin);
- Self { algorithm, table }
- }
-
-@@ -15,9 +15,9 @@ impl Crc<u8> {
-
- const fn init(&self) -> u8 {
- if self.algorithm.refin {
-- self.algorithm.init.reverse_bits()
-+ self.algorithm.init.reverse_bits() >> (u8::BITS as u8 - self.algorithm.width)
- } else {
-- self.algorithm.init
-+ self.algorithm.init << (u8::BITS as u8 - self.algorithm.width)
- }
- }
-
-@@ -40,6 +40,9 @@ impl Crc<u8> {
- if self.algorithm.refin ^ self.algorithm.refout {
- crc = crc.reverse_bits();
- }
-+ if !self.algorithm.refout {
-+ crc >>= u8::BITS as u8 - self.algorithm.width;
-+ }
- crc ^ self.algorithm.xorout
- }
-
-diff --git a/src/lib.rs b/src/lib.rs
-index 7944e19..99a30f6 100644
---- a/src/lib.rs
-+++ b/src/lib.rs
-@@ -14,6 +14,7 @@
- //!
- //! // use custom algorithm
- //! const CUSTOM_ALG: Algorithm<u16> = Algorithm {
-+//! width: 16,
- //! poly: 0x8005,
- //! init: 0xffff,
- //! refin: false,
-diff --git a/src/table.rs b/src/table.rs
-index 1e7ad75..a921ec2 100644
---- a/src/table.rs
-+++ b/src/table.rs
-@@ -1,6 +1,13 @@
- use crate::util::*;
-
--pub(crate) const fn crc8_table(poly: u8, reflect: bool) -> [u8; 256] {
-+pub(crate) const fn crc8_table(width: u8, poly: u8, reflect: bool) -> [u8; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u8::BITS as u8 - width)
-+ } else {
-+ poly << (u8::BITS as u8 - width)
-+ };
-+
- let mut table = [0u8; 256];
- let mut i = 0;
- while i < table.len() {
-@@ -9,29 +16,53 @@ pub(crate) const fn crc8_table(poly: u8, reflect: bool) -> [u8; 256] {
- }
- table
- }
--pub(crate) const fn crc16_table(poly: u16, reflect: bool) -> [u16; 256] {
-+
-+pub(crate) const fn crc16_table(width: u8, poly: u16, reflect: bool) -> [u16; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u16::BITS as u8 - width)
-+ } else {
-+ poly << (u16::BITS as u8 - width)
-+ };
-+
- let mut table = [0u16; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc16(poly, reflect, i as u8);
-+ table[i] = crc16(poly, reflect, i as u16);
- i += 1;
- }
- table
- }
--pub(crate) const fn crc32_table(poly: u32, reflect: bool) -> [u32; 256] {
-+
-+pub(crate) const fn crc32_table(width: u8, poly: u32, reflect: bool) -> [u32; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u32::BITS as u8 - width)
-+ } else {
-+ poly << (u32::BITS as u8 - width)
-+ };
-+
- let mut table = [0u32; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc32(poly, reflect, i as u8);
-+ table[i] = crc32(poly, reflect, i as u32);
- i += 1;
- }
- table
- }
--pub(crate) const fn crc64_table(poly: u64, reflect: bool) -> [u64; 256] {
-+
-+pub(crate) const fn crc64_table(width: u8, poly: u64, reflect: bool) -> [u64; 256] {
-+ let poly = if reflect {
-+ let poly = poly.reverse_bits();
-+ poly >> (u64::BITS as u8 - width)
-+ } else {
-+ poly << (u64::BITS as u8 - width)
-+ };
-+
- let mut table = [0u64; 256];
- let mut i = 0;
- while i < table.len() {
-- table[i] = crc64(poly, reflect, i as u8);
-+ table[i] = crc64(poly, reflect, i as u64);
- i += 1;
- }
- table
-diff --git a/src/util.rs b/src/util.rs
-index c378c23..b69f89e 100644
---- a/src/util.rs
-+++ b/src/util.rs
-@@ -1,63 +1,75 @@
--pub(crate) const fn crc8(poly: u8, reflect: bool, mut byte: u8) -> u8 {
-+pub(crate) const fn crc8(poly: u8, reflect: bool, mut value: u8) -> u8 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = byte;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 7) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u8::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u8::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc16(poly: u16, reflect: bool, mut byte: u8) -> u16 {
-+pub(crate) const fn crc16(poly: u16, reflect: bool, mut value: u16) -> u16 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u16) << 8;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 15) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u16::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u16::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc32(poly: u32, reflect: bool, mut byte: u8) -> u32 {
-+pub(crate) const fn crc32(poly: u32, reflect: bool, mut value: u32) -> u32 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u32) << 24;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 31) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u32::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u32::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-
--pub(crate) const fn crc64(poly: u64, reflect: bool, mut byte: u8) -> u64 {
-+pub(crate) const fn crc64(poly: u64, reflect: bool, mut value: u64) -> u64 {
- if reflect {
-- byte = byte.reverse_bits()
-- };
-- let mut value = (byte as u64) << 56;
-- let mut i = 0;
-- while i < 8 {
-- value = (value << 1) ^ ((value >> 63) * poly);
-- i += 1;
-- }
-- if reflect {
-- value = value.reverse_bits()
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value >> 1) ^ ((value & 1) * poly);
-+ i += 1;
-+ }
-+ } else {
-+ value <<= u64::BITS - 8;
-+
-+ let mut i = 0;
-+ while i < 8 {
-+ value = (value << 1) ^ (((value >> (u64::BITS - 1)) & 1) * poly);
-+ i += 1;
-+ }
- }
- value
- }
-diff --git a/tests/crc.rs b/tests/crc.rs
-index 7ee3238..dc89eb5 100644
---- a/tests/crc.rs
-+++ b/tests/crc.rs
-@@ -2,14 +2,53 @@ use crc::*;
-
- const INIT: &[u8] = b"123456789";
-
-+const INIT_PART1: &[u8] = b"1234";
-+const INIT_PART2: &[u8] = b"56789";
-+
- #[test]
- fn crc_8() {
-- let algs = &[CRC_8_AUTOSAR, CRC_8_BLUETOOTH, CRC_8_SMBUS, CRC_8_DARC];
-- for alg in algs {
-+ let algs = &[
-+ CRC_3_GSM,
-+ CRC_3_ROHC,
-+ CRC_4_G_704,
-+ CRC_4_INTERLAKEN,
-+ CRC_5_EPC_C1G2,
-+ CRC_5_G_704,
-+ CRC_5_USB,
-+ CRC_6_CDMA2000_A,
-+ CRC_6_CDMA2000_B,
-+ CRC_6_DARC,
-+ CRC_6_G_704,
-+ CRC_6_GSM,
-+ CRC_7_MMC,
-+ CRC_7_ROHC,
-+ CRC_7_UMTS,
-+ CRC_8_AUTOSAR,
-+ CRC_8_BLUETOOTH,
-+ CRC_8_CDMA2000,
-+ CRC_8_DARC,
-+ CRC_8_DVB_S2,
-+ CRC_8_GSM_A,
-+ CRC_8_GSM_B,
-+ CRC_8_I_432_1,
-+ CRC_8_I_CODE,
-+ CRC_8_LTE,
-+ CRC_8_MAXIM_DOW,
-+ CRC_8_MIFARE_MAD,
-+ CRC_8_NRSC_5,
-+ CRC_8_OPENSAFETY,
-+ CRC_8_ROHC,
-+ CRC_8_SAE_J1850,
-+ CRC_8_SMBUS,
-+ CRC_8_TECH_3250,
-+ CRC_8_WCDMA,
-+ ];
-+ for alg in algs.iter() {
- let crc = Crc::<u8>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-@@ -17,19 +56,57 @@ fn crc_8() {
- #[test]
- fn crc_16() {
- let algs = &[
-- CRC_16_IBM_SDLC,
-- CRC_16_USB,
-+ CRC_10_ATM,
-+ CRC_10_CDMA2000,
-+ CRC_10_GSM,
-+ CRC_11_FLEXRAY,
-+ CRC_11_UMTS,
-+ CRC_12_CDMA2000,
-+ CRC_12_DECT,
-+ CRC_12_GSM,
-+ CRC_12_UMTS,
-+ CRC_13_BBC,
-+ CRC_14_DARC,
-+ CRC_14_GSM,
-+ CRC_15_CAN,
-+ CRC_15_MPT1327,
- CRC_16_ARC,
- CRC_16_CDMA2000,
-+ CRC_16_CMS,
-+ CRC_16_DDS_110,
-+ CRC_16_DECT_R,
-+ CRC_16_DECT_X,
-+ CRC_16_DNP,
-+ CRC_16_EN_13757,
-+ CRC_16_GENIBUS,
-+ CRC_16_GSM,
- CRC_16_IBM_3740,
- CRC_16_IBM_SDLC,
-+ CRC_16_ISO_IEC_14443_3_A,
- CRC_16_KERMIT,
-+ CRC_16_LJ1200,
-+ CRC_16_MAXIM_DOW,
-+ CRC_16_MCRF4XX,
-+ CRC_16_MODBUS,
-+ CRC_16_NRSC_5,
-+ CRC_16_OPENSAFETY_A,
-+ CRC_16_OPENSAFETY_B,
-+ CRC_16_PROFIBUS,
-+ CRC_16_RIELLO,
-+ CRC_16_SPI_FUJITSU,
-+ CRC_16_T10_DIF,
-+ CRC_16_TELEDISK,
-+ CRC_16_TMS37157,
-+ CRC_16_UMTS,
-+ CRC_16_USB,
-+ CRC_16_XMODEM,
- ];
-- for alg in algs {
-+ for alg in algs.iter() {
- let crc = Crc::<u16>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-@@ -37,29 +114,55 @@ fn crc_16() {
- #[test]
- fn crc_32() {
- let algs = &[
-- CRC_32_ISCSI,
-+ CRC_17_CAN_FD,
-+ CRC_21_CAN_FD,
-+ CRC_24_BLE,
-+ CRC_24_FLEXRAY_A,
-+ CRC_24_FLEXRAY_B,
-+ CRC_24_INTERLAKEN,
-+ CRC_24_LTE_A,
-+ CRC_24_LTE_B,
-+ CRC_24_OPENPGP,
-+ CRC_24_OS_9,
-+ CRC_30_CDMA,
-+ CRC_31_PHILIPS,
-+ CRC_32_AIXM,
- CRC_32_AUTOSAR,
-+ CRC_32_BASE91_D,
- CRC_32_BZIP2,
-+ CRC_32_CD_ROM_EDC,
-+ CRC_32_CKSUM,
- CRC_32_ISCSI,
- CRC_32_ISO_HDLC,
-+ CRC_32_JAMCRC,
-+ CRC_32_MPEG_2,
-+ CRC_32_XFER,
- ];
- for alg in algs {
- let crc = Crc::<u32>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
-
- #[test]
- fn crc_64() {
-- let algs = &[CRC_64_ECMA_182, CRC_64_GO_ISO, CRC_64_WE, CRC_64_XZ];
-+ let algs = &[
-+ CRC_40_GSM,
-+ CRC_64_ECMA_182,
-+ CRC_64_GO_ISO,
-+ CRC_64_WE,
-+ CRC_64_XZ,
-+ ];
- for alg in algs {
- let crc = Crc::<u64>::new(alg);
- assert_eq!(alg.check, crc.checksum(INIT));
- let mut digest = crc.digest();
-- digest.update(INIT);
-+ digest.update(INIT_PART1);
-+ digest.update(INIT_PART2);
- assert_eq!(alg.check, digest.finalize());
- }
- }
diff --git a/README.md b/README.md
deleted file mode 100644
index 027cd63..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# rust-crc
-
-The rust-crc package
\ No newline at end of file
diff --git a/crc-fix-metadata.diff b/crc-fix-metadata.diff
deleted file mode 100644
index aa444fc..0000000
--- a/crc-fix-metadata.diff
+++ /dev/null
@@ -1,8 +0,0 @@
---- crc-2.1.0/Cargo.toml 1970-01-01T00:00:01+00:00
-+++ crc-2.1.0/Cargo.toml 2021-12-15T11:44:35.308461+00:00
-@@ -22,4 +22,4 @@
- license = "MIT OR Apache-2.0"
- repository = "https://github.com/mrhooray/crc-rs.git"
- [dependencies.crc-catalog]
--version = "1.1.1"
-+version = "2"
diff --git a/rust-crc.spec b/rust-crc.spec
index 0dde5ee..1296434 100644
--- a/rust-crc.spec
+++ b/rust-crc.spec
@@ -1,30 +1,22 @@
-# Generated by rust2rpm 20
+# Generated by rust2rpm 24
%bcond_without check
%global debug_package %{nil}
%global crate crc
-Name: rust-%{crate}
-Version: 2.1.0
+Name: rust-crc
+Version: 3.0.1
Release: %autorelease
-Summary: Rust implementation of CRC(16, 32, 64) with support of various standards
+Summary: Rust implementation of CRC with support of various standards
-# Upstream license specification: MIT OR Apache-2.0
-License: MIT or ASL 2.0
+License: MIT OR Apache-2.0
URL: https://crates.io/crates/crc
Source: %{crates_source}
-# Initial patched metadata
-# * bump crc-catalog from 1.1.1 to 2
-Patch0: crc-fix-metadata.diff
-# * port to crc-catalog 2: https://github.com/mrhooray/crc-rs/commit/384fb68
-Patch1: 384fb68.patch
-ExclusiveArch: %{rust_arches}
-
-BuildRequires: rust-packaging
+BuildRequires: rust-packaging >= 21
%global _description %{expand:
-Rust implementation of CRC(16, 32, 64) with support of various standards.}
+Rust implementation of CRC with support of various standards.}
%description %{_description}
@@ -38,9 +30,10 @@ This package contains library source intended for building other packages which
use the "%{crate}" crate.
%files devel
-%license LICENSE-APACHE LICENSE-MIT
-%doc README.md
-%{cargo_registry}/%{crate}-%{version_no_tilde}/
+%license %{crate_instdir}/LICENSE-APACHE
+%license %{crate_instdir}/LICENSE-MIT
+%doc %{crate_instdir}/README.md
+%{crate_instdir}/
%package -n %{name}+default-devel
Summary: %{summary}
@@ -52,7 +45,7 @@ This package contains library source intended for building other packages which
use the "default" feature of the "%{crate}" crate.
%files -n %{name}+default-devel
-%ghost %{cargo_registry}/%{crate}-%{version_no_tilde}/Cargo.toml
+%ghost %{crate_instdir}/Cargo.toml
%prep
%autosetup -n %{crate}-%{version_no_tilde} -p1
diff --git a/sources b/sources
index 9b5c89c..548bd43 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (crc-2.1.0.crate) = 45109925b4da84c9c60f0b6c2f79bde09a0dcdb4b901e3e0856a763b779ea02d251a1b150d6e588848ee517d8b63e16ee3b93522a0ccf8c10e4fd1f71345bca5
+SHA512 (crc-3.0.1.crate) = aabe9d4058fb4710405146e978ec5881bce5ce8971618b69a7ff873b0fff15fc78e5c48ff0136ca6d37663a53905bc3c5daa0ed3a2ed4d8d721e90c3b0ec28a5
1 year, 2 months
Architecture specific change in rpms/gnutls.git
by githook-noreply@fedoraproject.org
The package rpms/gnutls.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/gnutls.git/commit/?id=e2932d98f28....
Change:
+%ifarch %{ix86}
Thanks.
Full change:
============
commit e2932d98f28b6461bd65a9abf728898f5be3e661
Author: Daniel P. Berrangé <berrange(a)redhat.com>
Date: Thu Mar 2 11:14:44 2023 +0000
Disable GNULIB's year2038 support for 64-bit time_t
GNUTLS exposes time_t in its public API and thus the size of time_t
is ABI relevant. It can't be changed in size without breaking
ABI compatibility with applications built against GNUTLS that use
the default time_t size.
https://gitlab.com/gnutls/gnutls/-/issues/1466
https://bugzilla.redhat.com/show_bug.cgi?id=2174758
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
diff --git a/gnutls.spec b/gnutls.spec
index 55c9277..23c169a 100644
--- a/gnutls.spec
+++ b/gnutls.spec
@@ -241,6 +241,9 @@ pushd native_build
%endif
%if %{with_srp}
--enable-srp-authentication \
+%endif
+%ifarch %{ix86}
+ --disable-year2038 \
%endif
--enable-sha1-support \
--disable-static \
1 year, 2 months
Architecture specific change in rpms/gnutls.git
by githook-noreply@fedoraproject.org
The package rpms/gnutls.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/gnutls.git/commit/?id=96f7e472a53....
Change:
+%ifarch %{ix86}
Thanks.
Full change:
============
commit 96f7e472a5359d958b5873e615b264c10ef5f241
Author: Daniel P. Berrangé <berrange(a)redhat.com>
Date: Thu Mar 2 11:14:44 2023 +0000
Disable GNULIB's year2038 support for 64-bit time_t
GNUTLS exposes time_t in its public API and thus the size of time_t
is ABI relevant. It can't be changed in size without breaking
ABI compatibility with applications built against GNUTLS that use
the default time_t size.
https://gitlab.com/gnutls/gnutls/-/issues/1466
https://bugzilla.redhat.com/show_bug.cgi?id=2174758
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
diff --git a/gnutls.spec b/gnutls.spec
index 55c9277..23c169a 100644
--- a/gnutls.spec
+++ b/gnutls.spec
@@ -241,6 +241,9 @@ pushd native_build
%endif
%if %{with_srp}
--enable-srp-authentication \
+%endif
+%ifarch %{ix86}
+ --disable-year2038 \
%endif
--enable-sha1-support \
--disable-static \
1 year, 2 months
Architecture specific change in rpms/gnutls.git
by githook-noreply@fedoraproject.org
The package rpms/gnutls.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/gnutls.git/commit/?id=ae52b0f1bda....
Change:
+%ifarch %{ix86}
Thanks.
Full change:
============
commit ae52b0f1bdaa6951b426cd61cde905cbb616296d
Author: Daniel P. Berrangé <berrange(a)redhat.com>
Date: Thu Mar 2 11:14:44 2023 +0000
Disable GNULIB's year2038 support for 64-bit time_t
GNUTLS exposes time_t in its public API and thus the size of time_t
is ABI relevant. It can't be changed in size without breaking
ABI compatibility with applications built against GNUTLS that use
the default time_t size.
https://gitlab.com/gnutls/gnutls/-/issues/1466
https://bugzilla.redhat.com/show_bug.cgi?id=2174758
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
diff --git a/gnutls.spec b/gnutls.spec
index 55c9277..23c169a 100644
--- a/gnutls.spec
+++ b/gnutls.spec
@@ -241,6 +241,9 @@ pushd native_build
%endif
%if %{with_srp}
--enable-srp-authentication \
+%endif
+%ifarch %{ix86}
+ --disable-year2038 \
%endif
--enable-sha1-support \
--disable-static \
1 year, 2 months
Architecture specific change in rpms/lammps.git
by githook-noreply@fedoraproject.org
The package rpms/lammps.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/lammps.git/commit/?id=4bcdebca904....
Change:
+ExcludeArch: i686
Thanks.
Full change:
============
commit ad6fe6215272b798fefcb791a958e01981fce9e4
Author: Richard Berger <richard.berger(a)outlook.com>
Date: Tue Feb 28 21:32:13 2023 -0700
Use pyproject RPM macros
diff --git a/lammps.spec b/lammps.spec
index a61f933..d75e74c 100644
--- a/lammps.spec
+++ b/lammps.spec
@@ -37,6 +37,7 @@ Source0: https://github.com/lammps/lammps/archive/%{uversion}.tar.gz#/%{n
Source1: https://github.com/google/googletest/archive/release-1.12.1.tar.gz#/googl...
Source2: https://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz
Source3: https://download.lammps.org/thirdparty/opencl-loader-2022.01.04.tar.gz
+Patch0: remove-python-package-install-from-cmake-install.patch
BuildRequires: fftw-devel
BuildRequires: gcc-c++
BuildRequires: gcc-fortran
@@ -47,10 +48,7 @@ BuildRequires: python%{python3_pkgversion}-mpi4py-openmpi
BuildRequires: mpich-devel
BuildRequires: python%{python3_pkgversion}-mpi4py-mpich
BuildRequires: python%{python3_pkgversion}-devel
-BuildRequires: python%{python3_pkgversion}-setuptools
-BuildRequires: python%{python3_pkgversion}-pip
-BuildRequires: python%{python3_pkgversion}-wheel
-BuildRequires: python%{python3_pkgversion}-build
+BuildRequires: python%{python3_pkgversion}-numpy
BuildRequires: fftw3-devel
BuildRequires: zlib-devel
BuildRequires: gsl-devel
@@ -87,6 +85,7 @@ LAMMPS runs on single processors or in parallel using message-passing \
techniques and a spatial-decomposition of the simulation domain. The code is \
designed to be easy to modify or extend with new functionality.
+
%description
%{lammps_desc}
@@ -114,6 +113,7 @@ This package contains LAMMPS MPICH binaries and libraries
%package -n python%{python3_pkgversion}-%{name}
Summary: LAMMPS Python interface
Requires: python%{python3_pkgversion}
+Requires: python%{python3_pkgversion}-numpy
Requires: %{name}%{?_isa} = %{version}-%{release}
%{?python_provide:%python_provide python%{python3_pkgversion}-%{name}}
@@ -193,12 +193,17 @@ BuildArch: noarch
This package contains data files for LAMMPS.
+%generate_buildrequires
+cd python
+%pyproject_buildrequires
+
%prep
%if %{git}
%setup -q -n %{name}-%{commit}
%else
%setup -q -n %{name}-%{uversion}
%endif
+%patch0 -p1
%build
%global _vpath_srcdir cmake
@@ -240,6 +245,9 @@ for mpi in '' mpich openmpi %{?el7:openmpi3} ; do
test -n "${mpi}" && module unload mpi/${mpi}-%{_arch}
done
+cd python
+%pyproject_wheel
+
%install
. /etc/profile.d/modules.sh
@@ -247,6 +255,10 @@ for mpi in '' mpich openmpi %{?el7:openmpi3} ; do
%cmake_install
done
+cd python
+%pyproject_install
+%pyproject_save_files lammps
+
%check
%global testargs --label-exclude unstable --exclude-regex '\(Variables\|ComputeGlobal\|MolPairStyle:tip4p_long\|MolPairStyle:tip4p_table\|MolPairStyle:lj_cut_tip4p_table\|FixTimestep:rigid_nvt\|MolPairStyle:coul_slater_long\|AtomicPairStyle:meam_spline\|FixTimestep:addtorque_const\|FixTimestep:spring_rg\|FixTimestep:wall_harmonic_const\)'
@@ -263,6 +275,8 @@ for mpi in '' mpich openmpi %{?el7:openmpi3} ; do
test -n "${mpi}" && module unload mpi/${mpi}-%{_arch} && export PYTHONPATH="${old_PYTHONPATH}"
done
+%pyproject_check_import -t
+
%ldconfig_scriptlets
%files
@@ -294,9 +308,7 @@ done
%{_libdir}/mpich*/lib/pkgconfig/liblammps_mpich.pc
%{_libdir}/mpich*/lib/cmake/LAMMPS
-%files -n python%{python3_pkgversion}-%{name}
-%{python3_sitelib}/%{name}/
-%{python3_sitelib}/%{name}-*.egg-info
+%files -n python%{python3_pkgversion}-%{name} -f %{pyproject_files}
%files headers
%license LICENSE
diff --git a/remove-python-package-install-from-cmake-install.patch b/remove-python-package-install-from-cmake-install.patch
new file mode 100644
index 0000000..ea70d75
--- /dev/null
+++ b/remove-python-package-install-from-cmake-install.patch
@@ -0,0 +1,52 @@
+From a0bf63bdd5f7d705b78299027506b227c2d1cf4a Mon Sep 17 00:00:00 2001
+From: Richard Berger <richard.berger(a)outlook.com>
+Date: Tue, 28 Feb 2023 20:16:47 -0700
+Subject: [PATCH] Remove python package install from CMake install
+
+---
+ cmake/CMakeLists.txt | 29 -----------------------------
+ 1 file changed, 29 deletions(-)
+
+diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
+index f29ff52e8a..83f43ab30f 100644
+--- a/cmake/CMakeLists.txt
++++ b/cmake/CMakeLists.txt
+@@ -856,35 +856,6 @@ else()
+ ${CMAKE_COMMAND} -E echo "Must build LAMMPS as a shared library to use the Python module")
+ endif()
+
+-###############################################################################
+-# Add LAMMPS python module to "install" target. This is taylored for building
+-# LAMMPS for package managers and with different prefix settings.
+-# This requires either a shared library or that the PYTHON package is included.
+-###############################################################################
+-if(BUILD_SHARED_LIBS OR PKG_PYTHON)
+- if(CMAKE_VERSION VERSION_LESS 3.12)
+- # adjust so we find Python 3 versions before Python 2 on old systems with old CMake
+- set(Python_ADDITIONAL_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6)
+- find_package(PythonInterp) # Deprecated since version 3.12
+- if(PYTHONINTERP_FOUND)
+- set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
+- endif()
+- else()
+- # backward compatibility
+- if(PYTHON_EXECUTABLE)
+- set(Python_EXECUTABLE ${PYTHON_EXECUTABLE})
+- endif()
+- find_package(Python COMPONENTS Interpreter)
+- endif()
+- if(Python_EXECUTABLE)
+- file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/lib)
+- file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/src)
+- file(COPY ${LAMMPS_SOURCE_DIR}/version.h DESTINATION ${CMAKE_BINARY_DIR}/python/src)
+- file(COPY ${LAMMPS_PYTHON_DIR}/README ${LAMMPS_PYTHON_DIR}/pyproject.toml ${LAMMPS_PYTHON_DIR}/setup.py ${LAMMPS_PYTHON_DIR}/lammps DESTINATION ${CMAKE_BINARY_DIR}/python/lib)
+- install(CODE "if(\"\$ENV{DESTDIR}\" STREQUAL \"\")\n execute_process(COMMAND ${Python_EXECUTABLE} -m pip install -v ${CMAKE_BINARY_DIR}/python/lib --prefix=${CMAKE_INSTALL_PREFIX})\n else()\n execute_process(COMMAND ${Python_EXECUTABLE} -m pip install -v ${CMAKE_BINARY_DIR}/python/lib --prefix=${CMAKE_INSTALL_PREFIX} --root=\$ENV{DESTDIR})\n endif()")
+- endif()
+-endif()
+-
+ include(Testing)
+ include(CodeCoverage)
+ include(CodingStandard)
+--
+2.39.2
+
commit f6e1630c484062feccbc827fe1b7dfb8e51bbb84
Author: Richard Berger <richard.berger(a)outlook.com>
Date: Mon Feb 27 21:25:35 2023 -0700
Add missing python build dependencies
diff --git a/lammps.spec b/lammps.spec
index 47ce746..a61f933 100644
--- a/lammps.spec
+++ b/lammps.spec
@@ -48,6 +48,9 @@ BuildRequires: mpich-devel
BuildRequires: python%{python3_pkgversion}-mpi4py-mpich
BuildRequires: python%{python3_pkgversion}-devel
BuildRequires: python%{python3_pkgversion}-setuptools
+BuildRequires: python%{python3_pkgversion}-pip
+BuildRequires: python%{python3_pkgversion}-wheel
+BuildRequires: python%{python3_pkgversion}-build
BuildRequires: fftw3-devel
BuildRequires: zlib-devel
BuildRequires: gsl-devel
commit 4bcdebca9044bb0582950a20008d7520a4ffd7f7
Author: Richard Berger <richard.berger(a)outlook.com>
Date: Mon Feb 20 10:58:54 2023 -0700
Version bump 20220623.3
diff --git a/2986.patch b/2986.patch
deleted file mode 100644
index bb1192b..0000000
--- a/2986.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 2ad136f97f97380ae8da848d3d08c78dbd01d35b Mon Sep 17 00:00:00 2001
-From: Christoph Junghans <junghans(a)lanl.gov>
-Date: Tue, 5 Oct 2021 16:15:03 -0600
-Subject: [PATCH] cmake: label tests in force-styles
-
----
- unittest/force-styles/CMakeLists.txt | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/unittest/force-styles/CMakeLists.txt b/unittest/force-styles/CMakeLists.txt
-index 75e95c3bf03..28a58369c66 100644
---- a/unittest/force-styles/CMakeLists.txt
-+++ b/unittest/force-styles/CMakeLists.txt
-@@ -45,6 +45,7 @@ add_executable(test_error_stats test_error_stats.cpp)
- target_include_directories(test_error_stats PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LAMMPS_SOURCE_DIR})
- target_link_libraries(test_error_stats PRIVATE GTest::GTestMain GTest::GTest)
- add_test(NAME ErrorStats COMMAND test_error_stats)
-+set_tests_properties(ErrorStats PROPERTIES LABELS "force-style")
-
- # pair style tester
- add_executable(test_pair_style test_pair_style.cpp)
-@@ -63,6 +64,7 @@ foreach(TEST ${MOL_PAIR_TESTS})
- string(REGEX REPLACE "^.*mol-pair-(.*)\.yaml" "MolPairStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # tests for metal-like atomic systems and related pair styles
-@@ -71,6 +73,7 @@ foreach(TEST ${ATOMIC_PAIR_TESTS})
- string(REGEX REPLACE "^.*atomic-pair-(.*)\.yaml" "AtomicPairStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # tests for Si-like manybody systems and related pair styles
-@@ -79,6 +82,7 @@ foreach(TEST ${MANYBODY_PAIR_TESTS})
- string(REGEX REPLACE "^.*manybody-pair-(.*)\.yaml" "ManybodyPairStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # bond style tester
-@@ -90,6 +94,7 @@ foreach(TEST ${BOND_TESTS})
- string(REGEX REPLACE "^.*bond-(.*)\.yaml" "BondStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_bond_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # angle style tester
-@@ -101,6 +106,7 @@ foreach(TEST ${ANGLE_TESTS})
- string(REGEX REPLACE "^.*angle-(.*)\.yaml" "AngleStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_angle_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # kspace style tester, currently uses the pair style tool
-@@ -113,6 +119,7 @@ foreach(TEST ${KSPACE_TESTS})
- string(REGEX REPLACE "^.*kspace-(.*)\.yaml" "KSpaceStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # tester for timestepping fixes
-@@ -128,6 +135,7 @@ foreach(TEST ${FIX_TIMESTEP_TESTS})
- string(REGEX REPLACE "^.*fix-timestep-(.*)\.yaml" "FixTimestep:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # dihedral style tester
-@@ -139,6 +147,7 @@ foreach(TEST ${DIHEDRAL_TESTS})
- string(REGEX REPLACE "^.*dihedral-(.*)\.yaml" "DihedralStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
-
- # improper style tester
-@@ -150,4 +159,5 @@ foreach(TEST ${IMPROPER_TESTS})
- string(REGEX REPLACE "^.*improper-(.*)\.yaml" "ImproperStyle:\\1" TNAME ${TEST})
- add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
-+ set_tests_properties(${TNAME} PROPERTIES LABELS "force-style")
- endforeach()
diff --git a/lammps.spec b/lammps.spec
index 16774f7..47ce746 100644
--- a/lammps.spec
+++ b/lammps.spec
@@ -1,7 +1,6 @@
%global git 0
-%global commit 7d5fc356fefa1dd31d64b1cc856134b165febb8a
+%global commit 83ba1c9d20a7370b629bbebe88238a2c3c8194b3
%global shortcommit %(c=%{commit}; echo ${c:0:7})
-%global gtest_commit 8d51dc50eb7e7698427fed81b85edad0e032112e
%if 0%{?fedora} >= 33 || 0%{?rhel} >= 9
%global blaslib flexiblas
@@ -14,9 +13,9 @@
Name: lammps
%if %{git}
-Version: 20220623^%{shortcommit}
+Version: 20220623.3^%{shortcommit}
%else
-Version: 20220623
+Version: 20220623.3
%endif
%global uversion %(v=%{version}; \
patch=${v##*.}; [[ $v = $patch ]] && patch= \
@@ -26,7 +25,7 @@ Version: 20220623
m=${v:4:2};
y=${v:0:4};
echo $([[ -z $patch ]] && echo patch || echo stable)_${d#0}${months[${m#0}]}${y}$([[ -n $patch ]] && echo _update${patch}))
-Release: 4%{?dist}
+Release: 1%{?dist}
Summary: Molecular Dynamics Simulator
License: GPLv2
Url: https://www.lammps.org/
@@ -35,11 +34,9 @@ Source0: https://github.com/lammps/lammps/archive/%{commit}/lammps-%{comm
%else
Source0: https://github.com/lammps/lammps/archive/%{uversion}.tar.gz#/%{name}-%{uv...
%endif
-Source1: https://github.com/google/googletest/archive/%{gtest_commit}.tar.gz#/goog...
+Source1: https://github.com/google/googletest/archive/release-1.12.1.tar.gz#/googl...
Source2: https://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz
Source3: https://download.lammps.org/thirdparty/opencl-loader-2022.01.04.tar.gz
-Patch0: https://github.com/lammps/lammps/commit/cf942e7d5f7af16b308a9e652cda8ccc7...
-Patch1: https://github.com/lammps/lammps/commit/a00201c899b054923ffe9c21874aa207b...
BuildRequires: fftw-devel
BuildRequires: gcc-c++
BuildRequires: gcc-fortran
@@ -94,6 +91,7 @@ designed to be easy to modify or extend with new functionality.
Summary: LAMMPS Open MPI binaries and libraries
Requires: openmpi
Requires: %{name}-data
+ExcludeArch: i686
%description openmpi
%{lammps_desc}
@@ -153,6 +151,7 @@ This package contains development headers and libraries for MPICH LAMMPS.
Summary: Development libraries for Open MPI LAMMPS
Requires: %{name}-openmpi%{?_isa} = %{version}-%{release}
Requires: %{name}-headers%{?_isa} = %{version}-%{release}
+ExcludeArch: i686
%description openmpi-devel
%{lammps_desc}
@@ -197,13 +196,13 @@ This package contains data files for LAMMPS.
%else
%setup -q -n %{name}-%{uversion}
%endif
-%patch0 -p1
-%patch1 -p1
%build
%global _vpath_srcdir cmake
%global _vpath_builddir ${mpi:-serial}
. /etc/profile.d/modules.sh
+
+
for mpi in '' mpich openmpi %{?el7:openmpi3} ; do
test -n "${mpi}" && module load mpi/${mpi}-%{_arch}
#python wrapper isn't mpi specific
@@ -240,18 +239,20 @@ done
%install
. /etc/profile.d/modules.sh
+
for mpi in '' mpich openmpi %{?el7:openmpi3} ; do
%cmake_install
done
%check
-%global testargs --label-exclude unstable --exclude-regex '\(Variables\|ComputeGlobal\|MolPairStyle:tip4p_long\|MolPairStyle:tip4p_table\|MolPairStyle:lj_cut_tip4p_table\|FixTimestep:rigid_nvt\)'
+%global testargs --label-exclude unstable --exclude-regex '\(Variables\|ComputeGlobal\|MolPairStyle:tip4p_long\|MolPairStyle:tip4p_table\|MolPairStyle:lj_cut_tip4p_table\|FixTimestep:rigid_nvt\|MolPairStyle:coul_slater_long\|AtomicPairStyle:meam_spline\|FixTimestep:addtorque_const\|FixTimestep:spring_rg\|FixTimestep:wall_harmonic_const\)'
%ifarch ppc64le
-%global testargs --label-exclude unstable --exclude-regex '\(Variables\|ComputeGlobal\|MolPairStyle:tip4p_long\|MolPairStyle:tip4p_table\|MolPairStyle:lj_cut_tip4p_table\|MolPairStyle:tip4p_cut\|MolPairStyle:lj_cut_tip4p_cut\|MolPairStyle:lj_cut_tip4p_long_soft\|FixTimestep:rigid_nvt\)'
+%global testargs --label-exclude unstable --exclude-regex '\(Variables\|ComputeGlobal\|MolPairStyle:tip4p_long\|MolPairStyle:tip4p_table\|MolPairStyle:lj_cut_tip4p_table\|MolPairStyle:tip4p_cut\|MolPairStyle:lj_cut_tip4p_cut\|MolPairStyle:lj_cut_tip4p_long_soft\|FixTimestep:rigid_nvt\|MolPairStyle:coul_slater_long\|AtomicPairStyle:meam_spline\|FixTimestep:addtorque_const\|FixTimestep:spring_rg\|FixTimestep:wall_harmonic_const\)'
%endif
. /etc/profile.d/modules.sh
+
for mpi in '' mpich openmpi %{?el7:openmpi3} ; do
old_PYTHONPATH="${PYTHONPATH}"
test -n "${mpi}" && module load mpi/${mpi}-%{_arch} && export PYTHONPATH="${MPI_PYTHON3_SITEARCH}:${PYTHONPATH}"
@@ -331,6 +332,9 @@ done
%config %{_sysconfdir}/profile.d/lammps.*
%changelog
+* Mon Feb 20 2023 Richard Berger <richard.berger(a)outlook.com> - 20220623.3-1`
+- Version bump to 20220623.3
+
* Thu Jan 19 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 20220623-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
diff --git a/sources b/sources
index 9e2c201..118f298 100644
--- a/sources
+++ b/sources
@@ -1,6 +1,4 @@
+SHA512 (googletest-1.12.1.tar.gz) = a9104dc6c53747e36e7dd7bb93dfce51a558bd31b487a9ef08def095518e1296da140e0db263e0644d9055dbd903c0cb69380cb2322941dbfb04780ef247df9c
+SHA512 (lammps-stable_23Jun2022_update3.tar.gz) = fa5c7f605cfc7d5dde847afafe298e63516a2c2d22cd434b0fc16930e3e013c5e07324b89e11130138475e1873869eb501fea9e9deac0a477ef97f774ea9e6f1
SHA512 (opencl-loader-2022.01.04.tar.gz) = cfedca22d06e547b5621eebd9a9c112ba923bd940c0e46723cf2e0a139a50bf8080c28481435b011f20e72c525e793b51d38679ebb1656375e3c14c20301d2e8
SHA512 (yaml-0.2.5.tar.gz) = dadd7d8e0d88b5ebab005e5d521d56d541580198aa497370966b98c904586e642a1cd4f3881094eb57624f218d50db77417bbfd0ffdce50340f011e35e8c4c02
-SHA512 (googletest-8d51dc50eb7e7698427fed81b85edad0e032112e.tar.gz) = f7f804abf68af5e4e6cd767151773394fb8297d7d7fc878532ebb22b8c41d13554f68fa38a27470d458b590259a939e93cee7e5f5f6de8f1726c7ce85a606099
-SHA512 (lammps-patch_23Jun2022.tar.gz) = cc02b6d8958a452f4c06c19e2e08978db9cc41e8dfe868406c847a3b1912ae113d72ad6d2bd3b0139a1a1f2f8575eb3e7ff7fef2f6472ea94476d8033d59ac1d
-SHA512 (a00201c899b054923ffe9c21874aa207bc791a1a.patch) = 6c76688cb9a683faa41d795d53ffacef493f2a2c2e1dfa911c0387fda8848735903a574fa06a61e2f3113e1795a83878dbb53abee3745b81daed12d128d871d3
-SHA512 (cf942e7d5f7af16b308a9e652cda8ccc78e2d19e.patch) = a83029319a72b0871b2fc229dda2c1d20bf113f65cacbcc2b634843d121db144ec0c86468cf1e18e8df4ad6440e9bfc75a6cbfbd6d6f42fdac999d7ebf176b14
1 year, 2 months