From 94e882db3db08b8c8e9584ea9250e7f9546f4523 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 8 Jul 2024 11:11:13 -0500 Subject: [PATCH 01/16] Adjusted use of pthreads for Android/Termux platform Android/Termux doesn't have pthread_cancel so use pthred_kill instead Ticket: CFE-4401 Changelog: title (cherry picked from commit ebd52a29238122c4bcc2f86d2313f9f4a258243c) (cherry picked from commit 1e965d3ce15697271dd554b0dafe89c320fe0fcf) --- configure.ac | 8 ++++++++ libpromises/evalfunction.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/configure.ac b/configure.ac index ae69ca1444..7d5f819685 100644 --- a/configure.ac +++ b/configure.ac @@ -181,6 +181,14 @@ CC="$PTHREAD_CC" CFLAGS="$PTHREAD_CFLAGS $CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" +dnl ###################################################################### +dnl libpromises/evalfunction.c isreadable() uses pthread_cancel so check +dnl if available and reverts to pthread_kill if not. +dnl This check must come after ACX_PTHREAD is called so that CC, CFLAGS, +dnl and LIBS are appropriately set for the local pthreads situation. +dnl ###################################################################### +AC_CHECK_FUNCS([pthread_cancel]) + dnl ###################################################################### dnl Whether to build extensions as builtin extensions or a separate dnl plugin. The default is plugin. diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 2889cc6bef..07616affc9 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -9827,7 +9827,11 @@ static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, "Read operation timed out, exceeded %ld seconds.", path, timeout); +#ifdef HAVE_PTHREAD_CANCEL ret = pthread_cancel(thread_data.thread); +#else + ret = pthread_kill(thread_data.thread, 0); +#endif if (ret != 0) { Log(LOG_LEVEL_ERR, "Failed to cancel thread"); @@ -9857,10 +9861,12 @@ static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, return FnFailure(); } +#ifdef HAVE_PTHREAD_CANCEL if (status == PTHREAD_CANCELED) { Log(LOG_LEVEL_DEBUG, "Thread was canceled"); } +#endif return FnReturnContext(success); } From d28c2f3d13a12e71898415d24da66839c50705b8 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 26 Jul 2024 10:03:59 -0500 Subject: [PATCH 02/16] Take patch in downstream termux-packages project and adjust to use HAVE_PTHREAD_CANCEL instead of __ANDROID__ https://github.com/termux/termux-packages/blob/master/packages/cfengine/pthread_cancel.patch Ticket: CFE-4401 Changelog: none (cherry picked from commit 5cebd756944c9fd49b11c822bcfcdb734589a6c7) --- libpromises/evalfunction.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 07616affc9..7d6c2e4fee 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -9672,10 +9672,27 @@ struct IsReadableThreadData bool success; }; +#ifndef HAVE_PTHREAD_CANCEL +#define PTHREAD_CANCELED ((void *)-1) +static void ThreadSignalHandler(int signum) +{ + pthread_exit(PTHREAD_CANCELED); +} +#endif + static void *IsReadableThreadRoutine(void *data) { assert(data != NULL); +#ifndef HAVE_PTHREAD_CANCEL + struct sigaction actions; + memset(&actions, 0, sizeof(actions)); + sigemptyset(&actions.sa_mask); + actions.sa_flags = 0; + actions.sa_handler = ThreadSignalHandler; + sigaction(SIGUSR2, &actions, NULL); +#endif + struct IsReadableThreadData *const thread_data = data; // Give main thread time to call pthread_cond_timedwait(3) @@ -9830,7 +9847,7 @@ static FnCallResult FnCallIsReadable(ARG_UNUSED EvalContext *const ctx, #ifdef HAVE_PTHREAD_CANCEL ret = pthread_cancel(thread_data.thread); #else - ret = pthread_kill(thread_data.thread, 0); + ret = pthread_kill(thread_data.thread, SIGUSR2); #endif if (ret != 0) { From 70e76e24deca7e285e1863cc19a2e7152a7fd553 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 29 Jul 2024 13:04:21 -0500 Subject: [PATCH 03/16] updated termux make/install instructions --- INSTALL | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index 632a6cb6bf..ec5a8c06e5 100644 --- a/INSTALL +++ b/INSTALL @@ -160,7 +160,8 @@ Note that in order for process promises to work you must install the procps pack * Termux (2020-04-24) pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml -./autogen.sh --without-pam +LDFLAGS='-landroid-glob' ./autogen.sh --without-pam +make && make install * OSX (2021-10-20) From 9face277274733e8728026e0027789a2d9c03632 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 29 Jul 2024 13:04:52 -0500 Subject: [PATCH 04/16] help compilation from source on android termux platform --- libpromises/dbm_test_api.c | 2 ++ libpromises/dbm_test_api.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libpromises/dbm_test_api.c b/libpromises/dbm_test_api.c index def4d50b92..2d8f3d4007 100644 --- a/libpromises/dbm_test_api.c +++ b/libpromises/dbm_test_api.c @@ -22,6 +22,7 @@ included file COSL.txt. */ +#ifndef __ANDROID__ #include #include /* lrand48_r() */ #include /* usleep(), syscall()/gettid() */ @@ -735,3 +736,4 @@ void RemoveFilament(DBFilament *filament) free(filament); CloseDB(db); } +#endif /* not __ANDROID__ */ diff --git a/libpromises/dbm_test_api.h b/libpromises/dbm_test_api.h index ffda177d75..a6fe0ae63d 100644 --- a/libpromises/dbm_test_api.h +++ b/libpromises/dbm_test_api.h @@ -22,6 +22,7 @@ included file COSL.txt. */ +#ifndef __ANDROID__ #ifndef CFENGINE_DBM_TEST_API_H #define CFENGINE_DBM_TEST_API_H @@ -55,3 +56,4 @@ DBFilament *FillUpDB(dbid db_id, int usage_pct); void RemoveFilament(DBFilament *filament); #endif /* CFENGINE_DBM_TEST_API_H */ +#endif /* not __ANDROID__ */ From 0f67d22ae620921827d94b70c6b2707219f42a0a Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Mon, 29 Jul 2024 13:05:24 -0500 Subject: [PATCH 05/16] transition to MaskTerminationSignalsInThread() (from libntech soon) and SIGHUP --- libpromises/evalfunction.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libpromises/evalfunction.c b/libpromises/evalfunction.c index 7d6c2e4fee..52fadc65da 100644 --- a/libpromises/evalfunction.c +++ b/libpromises/evalfunction.c @@ -86,6 +86,7 @@ #include #include /* ThreadWait */ #include +#include /* MaskTerminationSignalsInThread */ #include @@ -9685,12 +9686,14 @@ static void *IsReadableThreadRoutine(void *data) assert(data != NULL); #ifndef HAVE_PTHREAD_CANCEL + MaskTerminationSignalsInThread(); struct sigaction actions; memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags = 0; actions.sa_handler = ThreadSignalHandler; - sigaction(SIGUSR2, &actions, NULL); + sigaction(SIGHUP, &actions, NULL); + MaskTerminationSignalsInThread(); #endif struct IsReadableThreadData *const thread_data = data; From f206844a32b8268bdf472149741b9ceadc2066dd Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 11 Apr 2025 16:25:47 -0500 Subject: [PATCH 06/16] Fixed check for copy_file_range on Android AC_CHECK_FUNCS apparently doesn't take into account the __ANDROID_API__ level properly and so incorrectly determines that copy_file_range is available for termux at API 24 but copy_file_range is <= 34. Ticket: none Changelog: none --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7d5f819685..165976b222 100644 --- a/configure.ac +++ b/configure.ac @@ -1349,7 +1349,7 @@ AC_CHECK_DECLS([FALLOC_FL_PUNCH_HOLE], [], [], [ ]) AC_CHECK_HEADERS([sys/sendfile.h]) AC_CHECK_FUNCS([sendfile]) -AC_CHECK_FUNCS([copy_file_range]) +AC_CHECK_DECL([copy_file_range]) dnl ####################################################################### From 5b4d6e083b597f0f06633a140b3d042404509682 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 11 Apr 2025 16:27:11 -0500 Subject: [PATCH 07/16] build and install scripts --- i | 7 +++++++ install | 1 + 2 files changed, 8 insertions(+) create mode 100755 i create mode 100755 install diff --git a/i b/i new file mode 100755 index 0000000000..bb99339011 --- /dev/null +++ b/i @@ -0,0 +1,7 @@ +export LDFLAGS+=" -landroid-glob" +./autogen.sh \ + --with-workdir=$PREFIX/var/lib/cfengine \ + --prefix=$PREFIX/local \ + --without-pam \ + --without-selinux-policy \ + --without-systemd-service diff --git a/install b/install new file mode 100755 index 0000000000..1db87d87e2 --- /dev/null +++ b/install @@ -0,0 +1 @@ +DESTDIR=/data/data/com.termux/files make install From a86124afbcecda0f39bdfa7f10cf90b62a9666b0 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 11 Apr 2025 16:30:25 -0500 Subject: [PATCH 08/16] INSTALL version for termux but out-of-sync because based on master instead of this old CFE-4401-2/master branch --- termux.INSTALL | 148 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 termux.INSTALL diff --git a/termux.INSTALL b/termux.INSTALL new file mode 100644 index 0000000000..08707e1443 --- /dev/null +++ b/termux.INSTALL @@ -0,0 +1,148 @@ +PREREQUISITES +------------- + +In order to build CFEngine you need the following tools and libraries installed: + +* C compiler supporting C90 + selected C99 constructs: + - _Bool type + - anonymous aggregates "(MyType) { .foo = 1, .bar = 2 }" + - declarations in "for" loop + - named initializers + - uintmax_t and corresponding printf/scanf formats + The following compilers are known to work: + - gcc >= 3.0 + - clang >= 2.6 +* GNU make + +* PAM library +* OpenSSL library +* PCRE library +* POSIX threads (pthreads) library, if not provided by the operating system +* Latest available LMDB (Lightning Memory-mapped DataBase), Tokyo Cabinet or QDBM + +* MySQL client library (optional) +* PostgreSQL client library (optional) +* libacl library (optional) + +In order to build CFEngine cloned from git, you will need the +following additional tools: + +* GNU Automake >= 1.10.1 +* GNU Autoconf >= 2.60 +* GNU Libtool >= 1.5.24 +* Yacc (note: GNU Bison 2.4.2 has troubles invoking m4) +* Lex + +Latest stable versions of the tools and libraries are generally advised. + +See INSTALL DEPENDENCIES below for example of deps for various systems. + +OPERATING SYSTEMS +----------------- + +CFEngine is regularly built and tested on the following operating systems: + +* GNU/Linux (many distributions) +* Solaris +* Windows with MinGW + +HARDWARE PLATFORMS +------------------ + +CFEngine is regularly built and tested on the following CPU architectures: + +* x86 +* x86-64 +* SPARC + +OTHER CONFIGURATIONS +-------------------- + +In case you have successfully compiled CFEngine on a different OS and/or using +different tools or versions of tools, please report it to help-cfengine@ mailing +list[1]. Please consider running a testsuite (see below), and posting results to +mailing list too. + +[1] https://groups.google.com/forum/#!forum/help-cfengine + +BUILD INSTRUCTIONS +------------------ + +From tarball: + +$ ./configure [configure options] +$ make [-jN] + +From git checkout: + +$ ./autogen.sh [configure options] +$ make [-jN] + +See the available configure options: + +$ ./configure --help +or +$ ./autogen.sh --help + +INSTALLATION INSTRUCTIONS +------------------------- + +CFEngine might be installed in two configurations: + + * (default) Native CFEngine file layout. Everything is installed in + /var/cfengine, laid out as a "secondary FHS root". This layout is designed to + keep CFEngine running even if most of the system is broken (e.g. /usr is not + mounted due to NFS breakage). + +* FHS file layout, enabled by --enable-fhs. This layout follows FHS 2.3. + +After the build process has completed (see BUILD INSTRUCTIONS above), type: + +$ make install + +RUNNING TESTSUITE +----------------- + +Please refer to the instructions in tests/README file. + +INSTALL DEPENDENCIES +-------------------- + +Here we have examples of command lines for various systems to install dependencies +needed to build. The version and date checked are noted in parenthesis. Please +submit PRs with updates to this information. + +* RedHat/CentOS (rhel-8/rhel-9/centos-7 2022-11-15) + +Note that first you will need to install epel-release (https://fedoraproject.org/wiki/EPEL) for lmdb-devel to be available. + +$ sudo yum install -y gcc gdb make git libtool autoconf automake byacc flex openssl-devel pcre-devel lmdb-devel pam-devel flex-devel libyaml-devel + +For SELinux support you will need selinux-policy-devel package and specify `--with-selinux-policy` to `autogen.sh` or `configure` + +* Debian (Raspbian 10 2021-07-02) + +$ sudo apt-get install -y build-essential git libtool autoconf automake bison flex libssl-dev libpcre3-dev libbison-dev libacl1 libacl1-dev lmdb-utils liblmdb-dev libpam0g-dev libtool libyaml-dev + +* FreeBSD (12.1 2020-04-07) + +See docs/BSD.md + +* SUSE (Tumbleweed 2020-02-02) + +$ sudo zypper install gdb gcc make lmdb autoconf automake libtool git python3 pcre-devel libopenssl-devel pam-devel + +* AlpineOS (3.11.3 x86_64 2020-04-13) + +$ sudo apk add alpine-sdk lmdb-dev openssl-dev bison flex-dev acl-dev pcre-dev autoconf automake libtool git python3 gdb +$ ./autogen.sh --without-pam + +* Termux (2020-04-24) + +pkg install -y build-essential git autoconf automake bison flex liblmdb openssl pcre libacl libyaml +./autogen.sh --without-pam + +* OSX (2021-10-20) + +brew install openssl@1.1 lmdb autoconf automake libtool bison flex pcre m4 gcc make +./autogen.sh --enable-debug --with-openssl="$(brew --prefix openssl@1.1)" From b04b810c114b7d1345ea36cbe243e706db2b2f4e Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Sat, 12 Apr 2025 06:47:30 -0500 Subject: [PATCH 09/16] update install script for -j8 and sync libntech for android --- install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install b/install index 1db87d87e2..a20969575e 100755 --- a/install +++ b/install @@ -1 +1 @@ -DESTDIR=/data/data/com.termux/files make install +DESTDIR=/data/data/com.termux/files make -j8 install From 8ece6f7b8148fc99504fa5c388957ed04f54040b Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Sat, 12 Apr 2025 09:13:15 -0500 Subject: [PATCH 10/16] FP4 --- i | 8 ++++++-- install | 1 - termux.INSTALL | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) delete mode 100755 install diff --git a/i b/i index bb99339011..2e3c62eb8f 100755 --- a/i +++ b/i @@ -1,7 +1,11 @@ +#!/usr/bin/env bash +set -ex export LDFLAGS+=" -landroid-glob" ./autogen.sh \ - --with-workdir=$PREFIX/var/lib/cfengine \ - --prefix=$PREFIX/local \ + --prefix=$PREFIX \ + --with-workdir=$PREFIX/var/lib/cfengine \ --without-pam \ --without-selinux-policy \ --without-systemd-service +make -j8 install +#DESTDIR=/data/data/com.termux/files make -j8 install diff --git a/install b/install deleted file mode 100755 index a20969575e..0000000000 --- a/install +++ /dev/null @@ -1 +0,0 @@ -DESTDIR=/data/data/com.termux/files make -j8 install diff --git a/termux.INSTALL b/termux.INSTALL index 08707e1443..3ba1c29860 100644 --- a/termux.INSTALL +++ b/termux.INSTALL @@ -140,6 +140,8 @@ $ ./autogen.sh --without-pam * Termux (2020-04-24) pkg install -y build-essential git autoconf automake bison flex liblmdb openssl pcre libacl libyaml +# ld is not found with clang (from build-essential?) so add binutils +# also need rsync ./autogen.sh --without-pam * OSX (2021-10-20) From 38191982ddd6d84045a02335cd8beb3b05c4857b Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 10 Oct 2025 11:41:30 -0400 Subject: [PATCH 11/16] Added Termux Linux Environment (Android) for sys.os_name_human We already supported and included the termux class. This change removes noise when running components like cf-agent. Ticket: CFE-4427 Changelog: title --- libenv/sysinfo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libenv/sysinfo.c b/libenv/sysinfo.c index b72f5de1d1..e8c8291e00 100644 --- a/libenv/sysinfo.c +++ b/libenv/sysinfo.c @@ -3809,6 +3809,12 @@ static void SysOSNameHuman(EvalContext *ctx) "Alpine", CF_DATA_TYPE_STRING, "source=agent,derived-from=alpine"); } + else if (EvalContextClassGet(ctx, NULL, "termux") != NULL) + { + EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, + "Termux Linux Environment (Android)", CF_DATA_TYPE_STRING, + "source=agent,derived-from=termux"); + } else if (EvalContextClassGet(ctx, NULL, "gentoo") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, From f0895d0089f55854cb39b97940c2b7e8bad6eb0d Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 10 Oct 2025 14:17:03 -0500 Subject: [PATCH 12/16] with os name human --- libenv/sysinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libenv/sysinfo.c b/libenv/sysinfo.c index e8c8291e00..a41f144633 100644 --- a/libenv/sysinfo.c +++ b/libenv/sysinfo.c @@ -3812,7 +3812,7 @@ static void SysOSNameHuman(EvalContext *ctx) else if (EvalContextClassGet(ctx, NULL, "termux") != NULL) { EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, lval, - "Termux Linux Environment (Android)", CF_DATA_TYPE_STRING, + "Termux", CF_DATA_TYPE_STRING, "source=agent,derived-from=termux"); } else if (EvalContextClassGet(ctx, NULL, "gentoo") != NULL) From 318c4323915eee9c08a79806a0378462af81712d Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 10 Oct 2025 14:17:49 -0500 Subject: [PATCH 13/16] replace egrep and fgrep with grep -E and grep -F --- tests/acceptance/testall | 56 ++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/acceptance/testall b/tests/acceptance/testall index adc73a6c9d..be117e506a 100755 --- a/tests/acceptance/testall +++ b/tests/acceptance/testall @@ -519,22 +519,22 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR echo "Return code is $RETVAL." >> "$WORKDIR/$LOG" # Try to collect test metadata if any - if egrep "R: test description: " $OUTFILE > /dev/null + if grep -E "R: test description: " $OUTFILE > /dev/null then - TEST_DESCRIPTION="$(egrep "R: test description" $OUTFILE | sed -e "s,.*test description: \([A-Za-z0-9_]*\),\1,")" + TEST_DESCRIPTION="$(grep -E "R: test description" $OUTFILE | sed -e "s,.*test description: \([A-Za-z0-9_]*\),\1,")" fi - if egrep -e "R: test story_id: " $OUTFILE > /dev/null + if grep -E -e "R: test story_id: " $OUTFILE > /dev/null then - TEST_STORY="$(egrep "R: test story_id" $OUTFILE | sed -e "s,.*test story_id: \([0-9][0-9]*\),\1,")" + TEST_STORY="$(grep -E "R: test story_id" $OUTFILE | sed -e "s,.*test story_id: \([0-9][0-9]*\),\1,")" fi - if egrep -e "R: test covers: " $OUTFILE > /dev/null + if grep -E -e "R: test covers: " $OUTFILE > /dev/null then - TEST_COVERS="$(egrep "R: test covers" $OUTFILE | sed -e "s,.*test covers: \([A-Za-z0-9_]*\),\1,")" + TEST_COVERS="$(grep -E "R: test covers" $OUTFILE | sed -e "s,.*test covers: \([A-Za-z0-9_]*\),\1,")" fi if [ $TEST_TYPE = errorexit ] then - if [ $RETVAL -gt 0 ] && [ $RETVAL -lt 128 ] && egrep "error:|aborted on defined class" $OUTFILE > /dev/null + if [ $RETVAL -gt 0 ] && [ $RETVAL -lt 128 ] && grep -E "error:|aborted on defined class" $OUTFILE > /dev/null then RESULT=Pass RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}" @@ -552,7 +552,7 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (NON-ZERO EXIT CODE!)${COLOR_NORMAL}" - elif fgrep 'error: ' "$OUTFILE" > /dev/null + elif grep -F 'error: ' "$OUTFILE" > /dev/null then RESULT=Pass RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}" @@ -570,21 +570,21 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR # Some states are output by dcs.cf.sub, therefore check for both TEST # prefix and dcs.cf.sub prefix. ESCAPED_TEST="$(echo "($TEST|dcs.cf.sub)" | sed -e 's/\./\\./g')" - if egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE > /dev/null && ! egrep "R: .*$ESCAPED_TEST Wait/" $OUTFILE > /dev/null + if grep -E "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE > /dev/null && ! grep -E "R: .*$ESCAPED_TEST Wait/" $OUTFILE > /dev/null then # Check for passed outcome, which should not happen. - if egrep "R: .*$ESCAPED_TEST " $OUTFILE | egrep "R: .*$ESCAPED_TEST Pass" > /dev/null + if grep -E "R: .*$ESCAPED_TEST " $OUTFILE | grep -E "R: .*$ESCAPED_TEST Pass" > /dev/null then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (The test Passed, but failure was expected)${COLOR_NORMAL}" - elif egrep "R: .*$ESCAPED_TEST " $OUTFILE | egrep -v "R: .*$ESCAPED_TEST [XS]?FAIL" > /dev/null + elif grep -E "R: .*$ESCAPED_TEST " $OUTFILE | grep -E -v "R: .*$ESCAPED_TEST [XS]?FAIL" > /dev/null then # Other test case outcomes than fail. Should not happen. RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Failure was expected, but the test had an unexpected test outcome, check test output, Pass/FAIL need to match exactly)${COLOR_NORMAL}" else - TICKET="$(egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*[XS]FAIL/\(.*\),\1,")" - RESULT="$(egrep "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*\([XS]FAIL\).*,\1,")" + TICKET="$(grep -E "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*[XS]FAIL/\(.*\),\1,")" + RESULT="$(grep -E "R: .*$ESCAPED_TEST [XS]FAIL" $OUTFILE | sed -e "s,.*\([XS]FAIL\).*,\1,")" if [ "$RESULT" = "XFAIL" ] then RESULT_MSG="${COLOR_WARNING}FAIL (Suppressed, $TICKET)${COLOR_NORMAL}" @@ -595,38 +595,38 @@ export CFENGINE_TEST_OVERRIDE_WORKDIR TEMP CFENGINE_TEST_OVERRIDE_EXTENSION_LIBR elif [ $RETVAL -ne 0 ] then RESULT=FAIL - elif egrep "R: .*$ESCAPED_TEST FAIL/no_ticket_number" $OUTFILE > /dev/null + elif grep -E "R: .*$ESCAPED_TEST FAIL/no_ticket_number" $OUTFILE > /dev/null then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Tried to suppress failure, but no issue number is provided)${COLOR_NORMAL}" - elif egrep "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE > /dev/null + elif grep -E "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE > /dev/null then if [ -z "$NEXT_TIMEOUT_VAR" ] then RESULT=FAIL RESULT_MSG="${COLOR_FAILURE}FAIL (Test tried to wait but is not in \"timed\" directory)${COLOR_NORMAL}" else - WAIT_TIME=$(egrep "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE | sed -e 's,.*Wait/\([0-9][0-9]*\).*,\1,') + WAIT_TIME=$(grep -E "R: .*$ESCAPED_TEST Wait/[0-9]+" $OUTFILE | sed -e 's,.*Wait/\([0-9][0-9]*\).*,\1,') eval $NEXT_TIMEOUT_VAR=$(($TEST_END_TIME+$WAIT_TIME)) RESULT=Wait RESULT_MSG="Awaiting ($WAIT_TIME seconds)..." fi - elif egrep "R: .*$ESCAPED_TEST Pass" $OUTFILE > /dev/null + elif grep -E "R: .*$ESCAPED_TEST Pass" $OUTFILE > /dev/null then RESULT=Pass RESULT_MSG="${COLOR_SUCCESS}Pass${COLOR_NORMAL}" - elif egrep "R: .*$ESCAPED_TEST Skip/unsupported" $OUTFILE > /dev/null + elif grep -E "R: .*$ESCAPED_TEST Skip/unsupported" $OUTFILE > /dev/null then RESULT=Skip RESULT_MSG="${COLOR_WARNING}Skipped (No platform support)${COLOR_NORMAL}" - elif egrep "R: .*$ESCAPED_TEST Skip/needs_work" $OUTFILE > /dev/null + elif grep -E "R: .*$ESCAPED_TEST Skip/needs_work" $OUTFILE > /dev/null then RESULT=Skip RESULT_MSG="${COLOR_WARNING}Skipped (Test needs work)${COLOR_NORMAL}" - elif egrep "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE > /dev/null + elif grep -E "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE > /dev/null then RESULT=FLAKEY - TICKET="$(egrep "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE | sed -e "s,.*FLAKEY/\(.*\),\1,")" + TICKET="$(grep -E "R: .*$ESCAPED_TEST FLAKEY" $OUTFILE | sed -e "s,.*FLAKEY/\(.*\),\1,")" RESULT_MSG="${COLOR_WARNING}Flakey fail ($TICKET)${COLOR_NORMAL}" else @@ -1070,7 +1070,7 @@ fi for addtest in $ALL_TESTS do - if echo "$addtest" | fgrep "/timed/" > /dev/null + if echo "$addtest" | grep -F "/timed/" > /dev/null then if [ "$TIMED_TESTS" = 1 ] then @@ -1128,12 +1128,12 @@ print_header() { print_footer() { # Recalculate results since sub invocations may not have been recorded. - PASSED_TESTS=`egrep '^Pass ' $SUMMARY | wc -l | tr -d ' '` - FAILED_TESTS=`egrep '^(FAIL|XFAIL) ' $SUMMARY | wc -l | tr -d ' '` - SUPPRESSED_FAILURES=`egrep '^XFAIL ' $SUMMARY | wc -l | tr -d ' '` - SOFT_FAILURES=`egrep '^SFAIL ' $SUMMARY | wc -l | tr -d ' '` - FLAKEY_FAILURES=`egrep '^FLAKEY ' $SUMMARY | wc -l | tr -d ' '` - SKIPPED_TESTS=`egrep '^Skip ' $SUMMARY | wc -l | tr -d ' '` + PASSED_TESTS=`grep -E '^Pass ' $SUMMARY | wc -l | tr -d ' '` + FAILED_TESTS=`grep -E '^(FAIL|XFAIL) ' $SUMMARY | wc -l | tr -d ' '` + SUPPRESSED_FAILURES=`grep -E '^XFAIL ' $SUMMARY | wc -l | tr -d ' '` + SOFT_FAILURES=`grep -E '^SFAIL ' $SUMMARY | wc -l | tr -d ' '` + FLAKEY_FAILURES=`grep -E '^FLAKEY ' $SUMMARY | wc -l | tr -d ' '` + SKIPPED_TESTS=`grep -E '^Skip ' $SUMMARY | wc -l | tr -d ' '` ( echo echo ====================================================================== From 9ecc190d950f3c5c77cff775b9916c7d00f14d63 Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 10 Oct 2025 14:18:50 -0500 Subject: [PATCH 14/16] with fgrep --- tests/acceptance/testall | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/acceptance/testall b/tests/acceptance/testall index be117e506a..693974822c 100755 --- a/tests/acceptance/testall +++ b/tests/acceptance/testall @@ -285,9 +285,9 @@ workdir() { } # Example: fgrepvar 'word' VARNAME -# Silent fgrep for variables: search for "word" in $VARNAME -fgrepvar() { - eval echo \$$2 | fgrep "$1" > /dev/null +# Silent grep -F for variables: search for "word" in $VARNAME +fgrepvar(){ + eval echo \$$2 | grep -F "$1" > /dev/null } # Same but instead of word search for a regex From 59280b2aeb5652ad340c2d62356b2013e5f262ed Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Fri, 10 Oct 2025 14:26:00 -0500 Subject: [PATCH 15/16] termux install instructions update --- INSTALL | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index ec5a8c06e5..52b2a8e118 100644 --- a/INSTALL +++ b/INSTALL @@ -157,10 +157,11 @@ sudo apk add alpine-sdk lmdb-dev openssl-dev bison flex-dev acl-dev pcre2-dev au Note that in order for process promises to work you must install the procps package for a "proper" ps command instead of busybox. -* Termux (2020-04-24) +* Termux (2025-10-10) -pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml -LDFLAGS='-landroid-glob' ./autogen.sh --without-pam +pkg install build-essential git autoconf automake bison flex liblmdb openssl pcre2 libacl libyaml binutils librsync +# maybe binutils-is-llvm - Use llvm as binutils instead of binutils to get ld +LDFLAGS='-landroid-glob' ./autogen.sh --without-pam --prefix=$PREFIX --with-workdir=$PREFIX/var/lib/cfengine --without-systemd-service --without-selinux-policy make && make install * OSX (2021-10-20) From 9b3d91243fd05aff26b8d3f9737e8fea13e4d94c Mon Sep 17 00:00:00 2001 From: Craig Comstock Date: Sat, 22 Nov 2025 07:31:05 -0600 Subject: [PATCH 16/16] In case of too many args on command line be more clear about what was provided We have a case where in Mission Portal the Run Agent button causes a Too many arguments error from Windows agents. This change seeks to understand why. Ticket: ENT-13530 Changelog: none --- libpromises/generic_agent.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libpromises/generic_agent.c b/libpromises/generic_agent.c index 1e67f53f8d..ee516502d5 100644 --- a/libpromises/generic_agent.c +++ b/libpromises/generic_agent.c @@ -2476,6 +2476,17 @@ bool GenericAgentConfigParseArguments(GenericAgentConfig *config, int argc, char if (argc > 1) { +Log(LOG_LEVEL_ERR, "Special 1-arg expected, got %d arguments instead. See debug output for details.", argc); +for (int i=0; i