diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/kyua/doc/kyuafile.5.in | 10 | ||||
-rw-r--r-- | contrib/kyua/drivers/report_junit_test.cpp | 3 | ||||
-rw-r--r-- | contrib/kyua/engine/atf_list.cpp | 2 | ||||
-rw-r--r-- | contrib/kyua/engine/requirements.cpp | 57 | ||||
-rw-r--r-- | contrib/kyua/engine/requirements.hpp | 26 | ||||
-rw-r--r-- | contrib/kyua/integration/cmd_report_junit_test.sh | 4 | ||||
-rw-r--r-- | contrib/kyua/integration/cmd_report_test.sh | 1 | ||||
-rw-r--r-- | contrib/kyua/model/metadata.cpp | 16 | ||||
-rw-r--r-- | contrib/kyua/model/metadata.hpp | 4 | ||||
-rw-r--r-- | contrib/kyua/model/metadata_test.cpp | 6 | ||||
-rw-r--r-- | contrib/kyua/model/test_case_test.cpp | 2 | ||||
-rw-r--r-- | contrib/kyua/model/test_program_test.cpp | 8 | ||||
-rw-r--r-- | contrib/kyua/os/freebsd/main.cpp | 11 | ||||
-rw-r--r-- | contrib/kyua/os/freebsd/reqs_checker_kmods.cpp | 50 | ||||
-rw-r--r-- | contrib/kyua/os/freebsd/reqs_checker_kmods.hpp | 54 | ||||
-rw-r--r-- | contrib/one-true-awk/FIXES | 8 | ||||
-rw-r--r-- | contrib/one-true-awk/main.c | 2 | ||||
-rw-r--r-- | contrib/one-true-awk/run.c | 4 | ||||
-rw-r--r-- | contrib/tcpdump/print-pfsync.c | 12 | ||||
-rw-r--r-- | contrib/tzcode/localtime.c | 341 |
20 files changed, 423 insertions, 198 deletions
diff --git a/contrib/kyua/doc/kyuafile.5.in b/contrib/kyua/doc/kyuafile.5.in index ae1e4fe40e32..43f00816d407 100644 --- a/contrib/kyua/doc/kyuafile.5.in +++ b/contrib/kyua/doc/kyuafile.5.in @@ -290,6 +290,16 @@ it can run. .Pp ATF: .Va require.files +.It Va required_kmods +Whitespace-separated list of kernel module names that the test requires to +be loaded before it can run. +This requirement checking is platform-dependent. +It is ignored for a non-supported platform. +Supported platforms: +.Fx . +.Pp +ATF: +.Va require.kmods .It Va required_memory Amount of physical memory that the test needs to run successfully. .Pp diff --git a/contrib/kyua/drivers/report_junit_test.cpp b/contrib/kyua/drivers/report_junit_test.cpp index 0f009c6befd3..1c0929c0fef2 100644 --- a/contrib/kyua/drivers/report_junit_test.cpp +++ b/contrib/kyua/drivers/report_junit_test.cpp @@ -70,6 +70,7 @@ static const char* const default_metadata = "required_configs is empty\n" "required_disk_space = 0\n" "required_files is empty\n" + "required_kmods is empty\n" "required_memory = 0\n" "required_programs is empty\n" "required_user is empty\n" @@ -89,6 +90,7 @@ static const char* const overriden_metadata = "required_configs is empty\n" "required_disk_space = 0\n" "required_files is empty\n" + "required_kmods is empty\n" "required_memory = 0\n" "required_programs is empty\n" "required_user is empty\n" @@ -228,6 +230,7 @@ ATF_TEST_CASE_BODY(junit_metadata__overrides) + "required_configs = config1\n" + "required_disk_space = 456\n" + "required_files = file1\n" + + "required_kmods is empty\n" + "required_memory = 123\n" + "required_programs = prog1\n" + "required_user = root\n" diff --git a/contrib/kyua/engine/atf_list.cpp b/contrib/kyua/engine/atf_list.cpp index e0c4170605d1..5c74a80be913 100644 --- a/contrib/kyua/engine/atf_list.cpp +++ b/contrib/kyua/engine/atf_list.cpp @@ -133,10 +133,8 @@ engine::parse_atf_metadata(const model::properties_map& props) mdbuilder.set_string("required_disk_space", value); } else if (name == "require.files") { mdbuilder.set_string("required_files", value); -#ifdef __FreeBSD__ } else if (name == "require.kmods") { mdbuilder.set_string("required_kmods", value); -#endif } else if (name == "require.machine") { mdbuilder.set_string("allowed_platforms", value); } else if (name == "require.memory") { diff --git a/contrib/kyua/engine/requirements.cpp b/contrib/kyua/engine/requirements.cpp index dff43e531a57..d5838b83f33a 100644 --- a/contrib/kyua/engine/requirements.cpp +++ b/contrib/kyua/engine/requirements.cpp @@ -41,10 +41,6 @@ #include "utils/sanity.hpp" #include "utils/units.hpp" -#ifdef __FreeBSD__ -#include <libutil.h> -#endif - namespace config = utils::config; namespace fs = utils::fs; namespace passwd = utils::passwd; @@ -224,26 +220,6 @@ check_required_programs(const model::paths_set& required_programs) } -#ifdef __FreeBSD__ -/// Checks if all required kmods are loaded. -/// -/// \param required_programs Set of kmods. -/// -/// \return Empty if the required kmods are all loaded or an error -/// message otherwise. -static std::string -check_required_kmods(const model::strings_set& required_kmods) -{ - for (model::strings_set::const_iterator iter = required_kmods.begin(); - iter != required_kmods.end(); iter++) { - if (!kld_isloaded((*iter).c_str())) - return F("Required kmod '%s' not loaded") % *iter; - } - return ""; -} -#endif - - /// Checks if the current system has the specified amount of memory. /// /// \param required_memory Amount of required physical memory, or zero if not @@ -289,9 +265,29 @@ check_required_disk_space(const units::bytes& required_disk_space, } +/// List of registered extra requirement checkers. +/// +/// Use register_reqs_checker() to add an entry to this global list. +static std::vector< std::shared_ptr< engine::reqs_checker > > _reqs_checkers; + + } // anonymous namespace +const std::vector< std::shared_ptr< engine::reqs_checker > > +engine::reqs_checkers() +{ + return _reqs_checkers; +} + +void +engine::register_reqs_checker( + const std::shared_ptr< engine::reqs_checker > checker) +{ + _reqs_checkers.push_back(checker); +} + + /// Checks if all the requirements specified by the test case are met. /// /// \param md The test metadata. @@ -336,12 +332,6 @@ engine::check_reqs(const model::metadata& md, const config::tree& cfg, if (!reason.empty()) return reason; -#ifdef __FreeBSD__ - reason = check_required_kmods(md.required_kmods()); - if (!reason.empty()) - return reason; -#endif - reason = check_required_memory(md.required_memory()); if (!reason.empty()) return reason; @@ -351,6 +341,13 @@ engine::check_reqs(const model::metadata& md, const config::tree& cfg, if (!reason.empty()) return reason; + // Iterate over extra checkers registered. + for (auto& checker : engine::reqs_checkers()) { + reason = checker->exec(md, cfg, test_suite, work_directory); + if (!reason.empty()) + return reason; + } + INV(reason.empty()); return reason; } diff --git a/contrib/kyua/engine/requirements.hpp b/contrib/kyua/engine/requirements.hpp index a36a938b3034..92e80c5122aa 100644 --- a/contrib/kyua/engine/requirements.hpp +++ b/contrib/kyua/engine/requirements.hpp @@ -44,6 +44,32 @@ namespace engine { std::string check_reqs(const model::metadata&, const utils::config::tree&, const std::string&, const utils::fs::path&); +/// Abstract interface of a requirement checker. +class reqs_checker { +public: + /// Constructor. + reqs_checker() {} + + /// Destructor. + virtual ~reqs_checker() {} + + /// Run the checker. + virtual std::string exec(const model::metadata&, + const utils::config::tree&, + const std::string&, + const utils::fs::path&) const = 0; +}; + +/// Register an extra requirement checker. +/// +/// \param checker A requirement checker. +void register_reqs_checker(const std::shared_ptr< reqs_checker > checker); + +/// Returns the list of registered extra requirement checkers. +/// +/// \return A vector of pointers to extra requirement checkers. +const std::vector< std::shared_ptr< reqs_checker > > reqs_checkers(); + } // namespace engine diff --git a/contrib/kyua/integration/cmd_report_junit_test.sh b/contrib/kyua/integration/cmd_report_junit_test.sh index d86228acf7e5..49b8c5790167 100644 --- a/contrib/kyua/integration/cmd_report_junit_test.sh +++ b/contrib/kyua/integration/cmd_report_junit_test.sh @@ -104,6 +104,7 @@ is_exclusive = false required_configs is empty required_disk_space = 0 required_files is empty +required_kmods is empty required_memory = 0 required_programs is empty required_user is empty @@ -144,6 +145,7 @@ is_exclusive = false required_configs is empty required_disk_space = 0 required_files is empty +required_kmods is empty required_memory = 0 required_programs is empty required_user is empty @@ -222,6 +224,7 @@ is_exclusive = false required_configs is empty required_disk_space = 0 required_files is empty +required_kmods is empty required_memory = 0 required_programs is empty required_user is empty @@ -262,6 +265,7 @@ is_exclusive = false required_configs is empty required_disk_space = 0 required_files is empty +required_kmods is empty required_memory = 0 required_programs is empty required_user is empty diff --git a/contrib/kyua/integration/cmd_report_test.sh b/contrib/kyua/integration/cmd_report_test.sh index 8b2b97f9cb4a..1fc1932d3c47 100644 --- a/contrib/kyua/integration/cmd_report_test.sh +++ b/contrib/kyua/integration/cmd_report_test.sh @@ -258,6 +258,7 @@ Metadata: required_configs is empty required_disk_space = 0 required_files is empty + required_kmods is empty required_memory = 0 required_programs is empty required_user is empty diff --git a/contrib/kyua/model/metadata.cpp b/contrib/kyua/model/metadata.cpp index a5a9a1315964..afb31435a238 100644 --- a/contrib/kyua/model/metadata.cpp +++ b/contrib/kyua/model/metadata.cpp @@ -256,9 +256,7 @@ init_tree(config::tree& tree) tree.define< bytes_node >("required_disk_space"); tree.define< paths_set_node >("required_files"); tree.define< bytes_node >("required_memory"); -#ifdef __FreeBSD__ tree.define< config::strings_set_node >("required_kmods"); -#endif tree.define< paths_set_node >("required_programs"); tree.define< user_node >("required_user"); tree.define< delta_node >("timeout"); @@ -285,9 +283,7 @@ set_defaults(config::tree& tree) tree.set< bytes_node >("required_disk_space", units::bytes(0)); tree.set< paths_set_node >("required_files", model::paths_set()); tree.set< bytes_node >("required_memory", units::bytes(0)); -#ifdef __FreeBSD__ tree.set< config::strings_set_node >("required_kmods", model::strings_set()); -#endif tree.set< paths_set_node >("required_programs", model::paths_set()); tree.set< user_node >("required_user", ""); // TODO(jmmv): We shouldn't be setting a default timeout like this. See @@ -603,20 +599,20 @@ model::metadata::required_memory(void) const } -#ifdef __FreeBSD__ -/// Returns the list of kmods needed by the test. +/// Returns the list of kernel modules needed by the test. /// -/// \return Set of strings. +/// \return Set of kernel module names. const model::strings_set& model::metadata::required_kmods(void) const { if (_pimpl->props.is_set("required_kmods")) { - return _pimpl->props.lookup< config::strings_set_node >("required_kmods"); + return _pimpl->props.lookup< config::strings_set_node >( + "required_kmods"); } else { - return get_defaults().lookup< config::strings_set_node >("required_kmods"); + return get_defaults().lookup< config::strings_set_node >( + "required_kmods"); } } -#endif /// Returns the list of programs needed by the test. diff --git a/contrib/kyua/model/metadata.hpp b/contrib/kyua/model/metadata.hpp index 8af6c7c161af..eee7eaf0f7c4 100644 --- a/contrib/kyua/model/metadata.hpp +++ b/contrib/kyua/model/metadata.hpp @@ -76,9 +76,7 @@ public: const utils::units::bytes& required_disk_space(void) const; const paths_set& required_files(void) const; const utils::units::bytes& required_memory(void) const; -#ifdef __FreeBSD__ const strings_set& required_kmods(void) const; -#endif const paths_set& required_programs(void) const; const std::string& required_user(void) const; const utils::datetime::delta& timeout(void) const; @@ -124,9 +122,7 @@ public: metadata_builder& set_required_disk_space(const utils::units::bytes&); metadata_builder& set_required_files(const paths_set&); metadata_builder& set_required_memory(const utils::units::bytes&); -#ifdef __FreeBSD__ metadata_builder& set_required_kmods(const strings_set&); -#endif metadata_builder& set_required_programs(const paths_set&); metadata_builder& set_required_user(const std::string&); metadata_builder& set_string(const std::string&, const std::string&); diff --git a/contrib/kyua/model/metadata_test.cpp b/contrib/kyua/model/metadata_test.cpp index b4c3dff5b029..bdb1d3655c33 100644 --- a/contrib/kyua/model/metadata_test.cpp +++ b/contrib/kyua/model/metadata_test.cpp @@ -57,6 +57,7 @@ ATF_TEST_CASE_BODY(defaults) ATF_REQUIRE(md.required_configs().empty()); ATF_REQUIRE_EQ(units::bytes(0), md.required_disk_space()); ATF_REQUIRE(md.required_files().empty()); + ATF_REQUIRE(md.required_kmods().empty()); ATF_REQUIRE_EQ(units::bytes(0), md.required_memory()); ATF_REQUIRE(md.required_programs().empty()); ATF_REQUIRE(md.required_user().empty()); @@ -322,6 +323,7 @@ ATF_TEST_CASE_BODY(to_properties) props["required_configs"] = ""; props["required_disk_space"] = "0"; props["required_files"] = "bar foo"; + props["required_kmods"] = ""; props["required_memory"] = "1.00K"; props["required_programs"] = ""; props["required_user"] = ""; @@ -412,7 +414,7 @@ ATF_TEST_CASE_BODY(output__defaults) "has_cleanup='false', is_exclusive='false', " "required_configs='', " "required_disk_space='0', required_files='', " - "required_memory='0', " + "required_kmods='', required_memory='0', " "required_programs='', required_user='', timeout='300'}", str.str()); } @@ -435,7 +437,7 @@ ATF_TEST_CASE_BODY(output__some_values) "has_cleanup='false', is_exclusive='true', " "required_configs='', " "required_disk_space='0', required_files='bar foo', " - "required_memory='1.00K', " + "required_kmods='', required_memory='1.00K', " "required_programs='', required_user='', timeout='300'}", str.str()); } diff --git a/contrib/kyua/model/test_case_test.cpp b/contrib/kyua/model/test_case_test.cpp index 1e2597d1501e..29df7ee35863 100644 --- a/contrib/kyua/model/test_case_test.cpp +++ b/contrib/kyua/model/test_case_test.cpp @@ -204,7 +204,7 @@ ATF_TEST_CASE_BODY(test_case__output) "has_cleanup='false', " "is_exclusive='false', " "required_configs='', required_disk_space='0', required_files='', " - "required_memory='0', " + "required_kmods='', required_memory='0', " "required_programs='', required_user='', timeout='300'}}", str.str()); } diff --git a/contrib/kyua/model/test_program_test.cpp b/contrib/kyua/model/test_program_test.cpp index ddfbc430387c..f7a84d770fc0 100644 --- a/contrib/kyua/model/test_program_test.cpp +++ b/contrib/kyua/model/test_program_test.cpp @@ -547,7 +547,7 @@ check_output__no_test_cases(void) "description='', execenv='', execenv_jail_params='', " "has_cleanup='false', is_exclusive='false', " "required_configs='', required_disk_space='0', required_files='', " - "required_memory='0', " + "required_kmods='', required_memory='0', " "required_programs='', required_user='', timeout='300'}, " "test_cases=map()}", str.str()); @@ -597,7 +597,7 @@ check_output__some_test_cases(void) "description='', execenv='', execenv_jail_params='', " "has_cleanup='false', is_exclusive='false', " "required_configs='', required_disk_space='0', required_files='', " - "required_memory='0', " + "required_kmods='', required_memory='0', " "required_programs='', required_user='', timeout='300'}, " "test_cases=map(" "another-name=test_case{name='another-name', " @@ -605,14 +605,14 @@ check_output__some_test_cases(void) "description='', execenv='', execenv_jail_params='', " "has_cleanup='false', is_exclusive='false', " "required_configs='', required_disk_space='0', required_files='', " - "required_memory='0', " + "required_kmods='', required_memory='0', " "required_programs='', required_user='', timeout='300'}}, " "the-name=test_case{name='the-name', " "metadata=metadata{allowed_architectures='a', allowed_platforms='foo', " "custom.bar='baz', description='', execenv='', execenv_jail_params='', " "has_cleanup='false', is_exclusive='false', " "required_configs='', required_disk_space='0', required_files='', " - "required_memory='0', " + "required_kmods='', required_memory='0', " "required_programs='', required_user='', timeout='300'}})}", str.str()); } diff --git a/contrib/kyua/os/freebsd/main.cpp b/contrib/kyua/os/freebsd/main.cpp index 13e5dcf0e023..700284b64b78 100644 --- a/contrib/kyua/os/freebsd/main.cpp +++ b/contrib/kyua/os/freebsd/main.cpp @@ -31,6 +31,9 @@ #include "engine/execenv/execenv.hpp" #include "os/freebsd/execenv_jail_manager.hpp" +#include "engine/requirements.hpp" +#include "os/freebsd/reqs_checker_kmods.hpp" + namespace execenv = engine::execenv; /// FreeBSD related features initialization. @@ -50,5 +53,13 @@ freebsd::main(const int, const char* const* const) std::shared_ptr< execenv::manager >(new freebsd::execenv_jail_manager()) ); +#ifdef __FreeBSD__ + engine::register_reqs_checker( + std::shared_ptr< engine::reqs_checker >( + new freebsd::reqs_checker_kmods() + ) + ); +#endif + return 0; } diff --git a/contrib/kyua/os/freebsd/reqs_checker_kmods.cpp b/contrib/kyua/os/freebsd/reqs_checker_kmods.cpp new file mode 100644 index 000000000000..3ae3446a7815 --- /dev/null +++ b/contrib/kyua/os/freebsd/reqs_checker_kmods.cpp @@ -0,0 +1,50 @@ +// Copyright 2025 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "os/freebsd/reqs_checker_kmods.hpp" + +#include "model/metadata.hpp" + +extern "C" { +#include "libutil.h" +} + +std::string +freebsd::reqs_checker_kmods::exec(const model::metadata& md, + const utils::config::tree&, + const std::string&, + const utils::fs::path&) const +{ + std::string reason = ""; + for (auto& kmod : md.required_kmods()) + if (!::kld_isloaded((kmod).c_str())) + reason += " " + kmod; + if (!reason.empty()) + reason = "Required kmods are not loaded:" + reason + "."; + return reason; +} diff --git a/contrib/kyua/os/freebsd/reqs_checker_kmods.hpp b/contrib/kyua/os/freebsd/reqs_checker_kmods.hpp new file mode 100644 index 000000000000..8c7c69e35d07 --- /dev/null +++ b/contrib/kyua/os/freebsd/reqs_checker_kmods.hpp @@ -0,0 +1,54 @@ +// Copyright 2025 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/// \file os/freebsd/reqs_checker_kmods.hpp +/// FreeBSD kernel module requirement checker. + +#if !defined(FREEBSD_REQS_CHECKER_KMODS) +#define FREEBSD_REQS_CHECKER_KMODS + +#include "engine/requirements.hpp" +#include "model/metadata_fwd.hpp" +#include "utils/config/tree_fwd.hpp" +#include "utils/fs/path_fwd.hpp" + +namespace freebsd { + + +class reqs_checker_kmods : public engine::reqs_checker { +public: + std::string exec(const model::metadata&, + const utils::config::tree&, + const std::string&, + const utils::fs::path&) const; +}; + + +} // namespace freebsd + +#endif // !defined(FREEBSD_REQS_CHECKER_KMODS) diff --git a/contrib/one-true-awk/FIXES b/contrib/one-true-awk/FIXES index b3bf38f0aa1c..b876b9ec5ec9 100644 --- a/contrib/one-true-awk/FIXES +++ b/contrib/one-true-awk/FIXES @@ -25,6 +25,14 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the second edition of the AWK book was published in September 2023. +Aug 04, 2025 + Fix incorrect divisor in rand() - it was returning + even random numbers only. Thanks to Ozan Yigit. + + Fix a syntax issue with /= that caused constants to + turn into variables [eg. 42 /= 7]. Thanks to Arnold + Robbins. + Jan 14, 2025 Fix incorrect error line number issues. unput has no business managing lineno. Thanks to Ozan Yigit. diff --git a/contrib/one-true-awk/main.c b/contrib/one-true-awk/main.c index 361c23e70861..b8053af34b05 100644 --- a/contrib/one-true-awk/main.c +++ b/contrib/one-true-awk/main.c @@ -22,7 +22,7 @@ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ****************************************************************/ -const char *version = "version 20250116"; +const char *version = "version 20250804"; #define DEBUG #include <stdio.h> diff --git a/contrib/one-true-awk/run.c b/contrib/one-true-awk/run.c index eaddfdecbdd3..9bc07a517372 100644 --- a/contrib/one-true-awk/run.c +++ b/contrib/one-true-awk/run.c @@ -1567,6 +1567,8 @@ Cell *assign(Node **a, int n) /* a[0] = a[1], a[0] += a[1], etc. */ xf *= yf; break; case DIVEQ: + if ((x->tval & CON) != 0) + FATAL("non-constant required for left side of /="); if (yf == 0) FATAL("division by zero in /="); xf /= yf; @@ -2188,7 +2190,7 @@ Cell *bltin(Node **a, int n) /* builtin functions. a[0] is type, a[1] is arg lis /* random() returns numbers in [0..2^31-1] * in order to get a number in [0, 1), divide it by 2^31 */ - u = (Awkfloat) random() / (0x7fffffffL + 0x1UL); + u = (Awkfloat) random() / RAND_MAX; break; case FSRAND: if (isrec(x)) /* no argument provided */ diff --git a/contrib/tcpdump/print-pfsync.c b/contrib/tcpdump/print-pfsync.c index 6bf9abaf3903..e4f11930816c 100644 --- a/contrib/tcpdump/print-pfsync.c +++ b/contrib/tcpdump/print-pfsync.c @@ -53,8 +53,8 @@ static void pfsync_print(netdissect_options *, struct pfsync_header *, const u_char *, u_int); static void print_src_dst(netdissect_options *, - const struct pfsync_state_peer *, - const struct pfsync_state_peer *, uint8_t); + const struct pf_state_peer_export *, + const struct pf_state_peer_export *, uint8_t); static void print_state(netdissect_options *, union pfsync_state_union *, int); void @@ -330,7 +330,7 @@ print_host(netdissect_options *ndo, struct pf_addr *addr, uint16_t port, } static void -print_seq(netdissect_options *ndo, const struct pfsync_state_peer *p) +print_seq(netdissect_options *ndo, const struct pf_state_peer_export *p) { if (p->seqdiff) ND_PRINT("[%u + %u](+%u)", ntohl(p->seqlo), @@ -341,8 +341,8 @@ print_seq(netdissect_options *ndo, const struct pfsync_state_peer *p) } static void -print_src_dst(netdissect_options *ndo, const struct pfsync_state_peer *src, - const struct pfsync_state_peer *dst, uint8_t proto) +print_src_dst(netdissect_options *ndo, const struct pf_state_peer_export *src, + const struct pf_state_peer_export *dst, uint8_t proto) { if (proto == IPPROTO_TCP) { @@ -390,7 +390,7 @@ print_src_dst(netdissect_options *ndo, const struct pfsync_state_peer *src, static void print_state(netdissect_options *ndo, union pfsync_state_union *s, int version) { - struct pfsync_state_peer *src, *dst; + struct pf_state_peer_export *src, *dst; struct pfsync_state_key *sk, *nk; int min, sec; diff --git a/contrib/tzcode/localtime.c b/contrib/tzcode/localtime.c index a6ec3d8e4e21..0fe7f1ed3f64 100644 --- a/contrib/tzcode/localtime.c +++ b/contrib/tzcode/localtime.c @@ -13,37 +13,36 @@ /*LINTLIBRARY*/ #define LOCALTIME_IMPLEMENTATION +#ifdef __FreeBSD__ #include "namespace.h" +#include <pthread.h> +#endif /* __FreeBSD__ */ #ifdef DETECT_TZ_CHANGES -#ifndef DETECT_TZ_CHANGES_INTERVAL -#define DETECT_TZ_CHANGES_INTERVAL 61 -#endif +# ifndef DETECT_TZ_CHANGES_INTERVAL +# define DETECT_TZ_CHANGES_INTERVAL 61 +# endif int __tz_change_interval = DETECT_TZ_CHANGES_INTERVAL; -#include <sys/stat.h> -#endif -#include <fcntl.h> -#if THREAD_SAFE -#include <pthread.h> -#endif +# include <sys/stat.h> +#endif /* DETECT_TZ_CHANGES */ #include "private.h" -#include "un-namespace.h" #include "tzdir.h" #include "tzfile.h" - +#include <fcntl.h> +#ifdef __FreeBSD__ #include "libc_private.h" +#include "un-namespace.h" +#endif /* __FreeBSD__ */ #if defined THREAD_SAFE && THREAD_SAFE +# include <pthread.h> +#ifdef __FreeBSD__ +# define pthread_mutex_lock(l) (__isthreaded ? _pthread_mutex_lock(l) : 0) +# define pthread_mutex_unlock(l) (__isthreaded ? _pthread_mutex_unlock(l) : 0) +#endif /* __FreeBSD__ */ static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER; -static int lock(void) { - if (__isthreaded) - return _pthread_mutex_lock(&locallock); - return 0; -} -static void unlock(void) { - if (__isthreaded) - _pthread_mutex_unlock(&locallock); -} +static int lock(void) { return pthread_mutex_lock(&locallock); } +static void unlock(void) { pthread_mutex_unlock(&locallock); } #else static int lock(void) { return 0; } static void unlock(void) { } @@ -166,6 +165,9 @@ struct rule { int_fast32_t r_time; /* transition time of rule */ }; +#ifdef __FreeBSD__ +static void tzset_unlocked_name(char const *); +#endif /* __FreeBSD__ */ static struct tm *gmtsub(struct state const *, time_t const *, int_fast32_t, struct tm *); static bool increment_overflow(int *, int); @@ -194,7 +196,7 @@ static struct state *const gmtptr = &gmtmem; static char lcl_TZname[TZ_STRLEN_MAX + 1]; static int lcl_is_set; - +#ifdef __FreeBSD__ static pthread_once_t gmt_once = PTHREAD_ONCE_INIT; static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT; static pthread_key_t gmtime_key; @@ -205,6 +207,7 @@ static int offtime_key_error; static pthread_once_t localtime_once = PTHREAD_ONCE_INIT; static pthread_key_t localtime_key; static int localtime_key_error; +#endif /* __FreeBSD__ */ /* ** Section 4.12.3 of X3.159-1989 requires that @@ -398,19 +401,20 @@ scrub_abbrs(struct state *sp) #ifdef DETECT_TZ_CHANGES /* - * Determine if there's a change in the timezone since the last time we checked. + * Check whether either the time zone name or the file it refers to has + * changed since the last time we checked. * Returns: -1 on error - * 0 if the timezone has not changed - * 1 if the timezone has changed + * 0 if the time zone has not changed + * 1 if the time zone has changed */ static int -change_in_tz(const char *name) +tzfile_changed(const char *name, int fd) { static char old_name[PATH_MAX]; static struct stat old_sb; struct stat sb; - if (stat(name, &sb) != 0) + if (_fstat(fd, &sb) != 0) return -1; if (strcmp(name, old_name) != 0) { @@ -429,9 +433,7 @@ change_in_tz(const char *name) return 0; } -#else /* !DETECT_TZ_CHANGES */ -#define change_in_tz(X) 1 -#endif /* !DETECT_TZ_CHANGES */ +#endif /* DETECT_TZ_CHANGES */ /* Input buffer for data read from a compiled tz file. */ union input_buffer { @@ -444,8 +446,10 @@ union input_buffer { + 4 * TZ_MAX_TIMES]; }; +#ifndef __FreeBSD__ /* TZDIR with a trailing '/' rather than a trailing '\0'. */ static char const tzdirslash[sizeof TZDIR] = TZDIR "/"; +#endif /* !__FreeBSD__ */ /* Local storage needed for 'tzloadbody'. */ union local_storage { @@ -458,6 +462,7 @@ union local_storage { struct state st; } u; +#ifndef __FreeBSD__ /* The name of the file to be opened. Ideally this would have no size limits, to support arbitrarily long Zone names. Limiting Zone names to 1024 bytes should suffice for practical use. @@ -465,6 +470,7 @@ union local_storage { file_analysis as that struct is allocated anyway, as the other union member. */ char fullname[max(sizeof(struct file_analysis), sizeof tzdirslash + 1024)]; +#endif /* !__FreeBSD__ */ }; /* Load tz data from the file named NAME into *SP. Read extended @@ -478,6 +484,11 @@ tzloadbody(char const *name, struct state *sp, bool doextend, register int fid; register int stored; register ssize_t nread; +#ifdef __FreeBSD__ + int serrno; +#else /* !__FreeBSD__ */ + register bool doaccess; +#endif /* !__FreeBSD__ */ register union input_buffer *up = &lsp->u.u; register int tzheadsize = sizeof(struct tzhead); @@ -491,7 +502,16 @@ tzloadbody(char const *name, struct state *sp, bool doextend, if (name[0] == ':') ++name; - if (name[0] != '/') { +#ifndef __FreeBSD__ +#ifdef SUPPRESS_TZDIR + /* Do not prepend TZDIR. This is intended for specialized + applications only, due to its security implications. */ + doaccess = true; +#else + doaccess = name[0] == '/'; +#endif + if (!doaccess) { + char const *dot; if (sizeof lsp->fullname - sizeof tzdirslash <= strlen(name)) return ENAMETOOLONG; @@ -501,27 +521,59 @@ tzloadbody(char const *name, struct state *sp, bool doextend, memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash); strcpy(lsp->fullname + sizeof tzdirslash, name); + /* Set doaccess if NAME contains a ".." file name + component, as such a name could read a file outside + the TZDIR virtual subtree. */ + for (dot = name; (dot = strchr(dot, '.')); dot++) + if ((dot == name || dot[-1] == '/') && dot[1] == '.' + && (dot[2] == '/' || !dot[2])) { + doaccess = true; + break; + } + name = lsp->fullname; } - if (doextend) { - /* - * Detect if the timezone file has changed. Check - * 'doextend' to ignore TZDEFRULES; the change_in_tz() - * function can only keep state for a single file. - */ - switch (change_in_tz(name)) { - case -1: - return errno; - case 0: - return 0; - case 1: - break; - } - } + if (doaccess && access(name, R_OK) != 0) + return errno; fid = _open(name, O_RDONLY | O_BINARY); +#else /* __FreeBSD__ */ + { + const char *relname = name; + if (strncmp(relname, TZDIR "/", strlen(TZDIR) + 1) == 0) + relname += strlen(TZDIR) + 1; + int dd = _open(TZDIR, O_DIRECTORY | O_RDONLY); + if (dd < 0) + return errno; + fid = _openat(dd, relname, O_RDONLY | O_BINARY, + issetugid() ? AT_RESOLVE_BENEATH : 0); + serrno = errno; + _close(dd); + errno = serrno; + } +#endif /* __FreeBSD__ */ if (fid < 0) return errno; +#ifdef DETECT_TZ_CHANGES + if (doextend) { + /* + * Detect if the timezone file has changed. Check 'doextend' to + * ignore TZDEFRULES; the tzfile_changed() function can only + * keep state for a single file. + */ + switch (tzfile_changed(name, fid)) { + case -1: + serrno = errno; + _close(fid); + return serrno; + case 0: + _close(fid); + return 0; + case 1: + break; + } + } +#endif /* DETECT_TZ_CHANGES */ nread = _read(fid, up->buf, sizeof up->buf); if (nread < tzheadsize) { int err = nread < 0 ? errno : EINVAL; @@ -1370,8 +1422,11 @@ gmtload(struct state *const sp) } #ifdef DETECT_TZ_CHANGES +/* + * Check if the time zone data we have is still fresh. + */ static int -recheck_tzdata() +tzdata_is_fresh(void) { static time_t last_checked; struct timespec now; @@ -1387,9 +1442,7 @@ recheck_tzdata() return 0; } -#else /* !DETECT_TZ_CHANGES */ -#define recheck_tzdata() 0 -#endif /* !DETECT_TZ_CHANGES */ +#endif /* DETECT_TZ_CHANGES */ /* Initialize *SP to a value appropriate for the TZ setting NAME. Return 0 on success, an errno value on failure. */ @@ -1419,15 +1472,26 @@ zoneinit(struct state *sp, char const *name) } static void +tzset_unlocked(void) +{ +#ifdef __FreeBSD__ + tzset_unlocked_name(getenv("TZ")); +} +static void tzset_unlocked_name(char const *name) { +#else + char const *name = getenv("TZ"); +#endif struct state *sp = lclptr; int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; if (lcl < 0 ? lcl_is_set < 0 : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) - if (recheck_tzdata() == 0) - return; +#ifdef DETECT_TZ_CHANGES + if (tzdata_is_fresh() == 0) +#endif /* DETECT_TZ_CHANGES */ + return; #ifdef ALL_STATE if (! sp) lclptr = sp = malloc(sizeof *lclptr); @@ -1442,12 +1506,6 @@ tzset_unlocked_name(char const *name) lcl_is_set = lcl; } -static void -tzset_unlocked(void) -{ - tzset_unlocked_name(getenv("TZ")); -} - void tzset(void) { @@ -1457,6 +1515,7 @@ tzset(void) unlock(); } +#ifdef __FreeBSD__ void freebsd13_tzsetwall(void) { @@ -1468,7 +1527,7 @@ freebsd13_tzsetwall(void) __sym_compat(tzsetwall, freebsd13_tzsetwall, FBSD_1.0); __warn_references(tzsetwall, "warning: tzsetwall() is deprecated, use tzset() instead."); - +#endif /* __FreeBSD__ */ static void gmtcheck(void) { @@ -1485,6 +1544,9 @@ gmtcheck(void) } unlock(); } +#ifdef __FreeBSD__ +#define gmtcheck() _once(&gmt_once, gmtcheck) +#endif #if NETBSD_INSPIRED @@ -1652,45 +1714,47 @@ localtime_tzset(time_t const *timep, struct tm *tmp, bool setname) } #ifndef DETECT_TZ_CHANGES if (setname || !lcl_is_set) -#endif +#endif /* DETECT_TZ_CHANGES */ tzset_unlocked(); tmp = localsub(lclptr, timep, setname, tmp); unlock(); return tmp; } +#ifdef __FreeBSD__ static void localtime_key_init(void) { - - localtime_key_error = _pthread_key_create(&localtime_key, free); + localtime_key_error = _pthread_key_create(&localtime_key, free); } - +#endif /* __FreeBSD__ */ struct tm * localtime(const time_t *timep) { #if !SUPPORT_C89 - static struct tm tm; + static struct tm tm; #endif - struct tm *p_tm = &tm; - - if (__isthreaded != 0) { - _pthread_once(&localtime_once, localtime_key_init); - if (localtime_key_error != 0) { - errno = localtime_key_error; - return (NULL); - } - if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) { - if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { - return (NULL); - } - if (_pthread_setspecific(localtime_key, p_tm) != 0) { - free(p_tm); - return (NULL); - } - } - } - return localtime_tzset(timep, p_tm, true); +#ifdef __FreeBSD__ + struct tm *p_tm = &tm; + + if (__isthreaded != 0) { + _pthread_once(&localtime_once, localtime_key_init); + if (localtime_key_error != 0) { + errno = localtime_key_error; + return (NULL); + } + if ((p_tm = _pthread_getspecific(localtime_key)) == NULL) { + if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { + return (NULL); + } + if (_pthread_setspecific(localtime_key, p_tm) != 0) { + free(p_tm); + return (NULL); + } + } + } +#endif /* __FreeBSD__ */ + return localtime_tzset(timep, p_tm, true); } struct tm * @@ -1729,42 +1793,44 @@ gmtsub(ATTRIBUTE_MAYBE_UNUSED struct state const *sp, time_t const *timep, struct tm * gmtime_r(time_t const *restrict timep, struct tm *restrict tmp) { - _once(&gmt_once, gmtcheck); - return gmtsub(gmtptr, timep, 0, tmp); + gmtcheck(); + return gmtsub(gmtptr, timep, 0, tmp); } +#ifdef __FreeBSD__ static void gmtime_key_init(void) { - - gmtime_key_error = _pthread_key_create(&gmtime_key, free); + gmtime_key_error = _pthread_key_create(&gmtime_key, free); } - +#endif /* __FreeBSD__ */ struct tm * gmtime(const time_t *timep) { #if !SUPPORT_C89 - static struct tm tm; + static struct tm tm; #endif - struct tm *p_tm = &tm; - - if (__isthreaded != 0) { - _pthread_once(&gmtime_once, gmtime_key_init); - if (gmtime_key_error != 0) { - errno = gmtime_key_error; - return (NULL); - } - if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { - if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { - return (NULL); - } - if (_pthread_setspecific(gmtime_key, p_tm) != 0) { - free(p_tm); - return (NULL); - } - } - } - return gmtime_r(timep, p_tm); +#ifdef __FreeBSD__ + struct tm *p_tm = &tm; + + if (__isthreaded != 0) { + _pthread_once(&gmtime_once, gmtime_key_init); + if (gmtime_key_error != 0) { + errno = gmtime_key_error; + return (NULL); + } + if ((p_tm = _pthread_getspecific(gmtime_key)) == NULL) { + if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { + return (NULL); + } + if (_pthread_setspecific(gmtime_key, p_tm) != 0) { + free(p_tm); + return (NULL); + } + } + } +#endif /* __FreeBSD__ */ + return gmtime_r(timep, p_tm); } #if STD_INSPIRED @@ -1775,42 +1841,44 @@ gmtime(const time_t *timep) struct tm * offtime_r(time_t const *restrict timep, long offset, struct tm *restrict tmp) { - _once(&gmt_once, gmtcheck); - return gmtsub(gmtptr, timep, offset, tmp); + gmtcheck(); + return gmtsub(gmtptr, timep, offset, tmp); } +#ifdef __FreeBSD__ static void offtime_key_init(void) { - - offtime_key_error = _pthread_key_create(&offtime_key, free); + offtime_key_error = _pthread_key_create(&offtime_key, free); } - +#endif /* __FreeBSD__ */ struct tm * offtime(const time_t *timep, long offset) { #if !SUPPORT_C89 - static struct tm tm; + static struct tm tm; #endif - struct tm *p_tm = &tm; - - if (__isthreaded != 0) { - _pthread_once(&offtime_once, offtime_key_init); - if (offtime_key_error != 0) { - errno = offtime_key_error; - return (NULL); - } - if ((p_tm = _pthread_getspecific(offtime_key)) == NULL) { - if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { - return (NULL); - } - if (_pthread_setspecific(offtime_key, p_tm) != 0) { - free(p_tm); - return (NULL); - } - } - } - return offtime_r(timep, offset, p_tm); +#ifdef __FreeBSD__ + struct tm *p_tm = &tm; + + if (__isthreaded != 0) { + _pthread_once(&offtime_once, offtime_key_init); + if (offtime_key_error != 0) { + errno = offtime_key_error; + return (NULL); + } + if ((p_tm = _pthread_getspecific(offtime_key)) == NULL) { + if ((p_tm = malloc(sizeof(*p_tm))) == NULL) { + return (NULL); + } + if (_pthread_setspecific(offtime_key, p_tm) != 0) { + free(p_tm); + return (NULL); + } + } + } +#endif + return offtime_r(timep, offset, p_tm); } #endif @@ -2323,7 +2391,6 @@ time1(struct tm *const tmp, errno = EINVAL; return WRONG; } - if (tmp->tm_isdst > 1) tmp->tm_isdst = 1; t = time2(tmp, funcp, sp, offset, &okay); @@ -2382,7 +2449,7 @@ mktime_tzname(struct state *sp, struct tm *tmp, bool setname) if (sp) return time1(tmp, localsub, sp, setname); else { - _once(&gmt_once, gmtcheck); + gmtcheck(); return time1(tmp, gmtsub, gmtptr, 0); } } @@ -2438,7 +2505,7 @@ timeoff(struct tm *tmp, long offset) { if (tmp) tmp->tm_isdst = 0; - _once(&gmt_once, gmtcheck); + gmtcheck(); return time1(tmp, gmtsub, gmtptr, offset); } @@ -2508,7 +2575,7 @@ time2posix(time_t t) } #ifndef DETECT_TZ_CHANGES if (!lcl_is_set) -#endif +#endif /* DETECT_TZ_CHANGES */ tzset_unlocked(); if (lclptr) t = time2posix_z(lclptr, t); @@ -2555,7 +2622,7 @@ posix2time(time_t t) } #ifndef DETECT_TZ_CHANGES if (!lcl_is_set) -#endif +#endif /* DETECT_TZ_CHANGES */ tzset_unlocked(); if (lclptr) t = posix2time_z(lclptr, t); |