summaryrefslogtreecommitdiff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
authorMarius Bakke <marius@gnu.org>2022-10-16 00:10:07 +0200
committerMarius Bakke <marius@gnu.org>2022-10-16 00:10:07 +0200
commitc567a82a6975e70c8207a4aeed55a72b5121213c (patch)
tree8a6dfe8a78726933e4a1581a2c6ba4a84d59411f /gnu/packages/patches
parent3a84b4ec4cec1d122cb454da9d4f6a747a51e49a (diff)
parent322917aeb8e672c21378fd371a5cff4a9f0c2520 (diff)
Merge branch 'staging'
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/akonadi-not-relocatable.patch51
-rw-r--r--gnu/packages/patches/akonadi-paths.patch32
-rw-r--r--gnu/packages/patches/akonadi-timestamps.patch6
-rw-r--r--gnu/packages/patches/firebird-riscv64-support-pt1.patch42
-rw-r--r--gnu/packages/patches/firebird-riscv64-support-pt2.patch108
-rw-r--r--gnu/packages/patches/freeglut-gcc-compat.patch53
-rw-r--r--gnu/packages/patches/grantlee-merge-theme-dirs.patch163
-rw-r--r--gnu/packages/patches/gst-plugins-good-fix-test.patch94
-rw-r--r--gnu/packages/patches/kdbusaddons-kinit-file-name.patch15
-rw-r--r--gnu/packages/patches/kinit-kdeinit-extra_libs.patch21
-rw-r--r--gnu/packages/patches/kinit-kdeinit-libpath.patch37
-rw-r--r--gnu/packages/patches/kio-search-smbd-on-PATH.patch46
-rw-r--r--gnu/packages/patches/kmail-Fix-missing-link-libraries.patch41
-rw-r--r--gnu/packages/patches/kmplayer-aarch64.patch57
-rw-r--r--gnu/packages/patches/kmplayer-upstream_Fix-build-with-Qt-5.9.patch42
-rw-r--r--gnu/packages/patches/kpackage-allow-external-paths.patch13
-rw-r--r--gnu/packages/patches/kpackage-fix-KF5PackageMacros.cmake.patch25
-rw-r--r--gnu/packages/patches/libksieve-Fix-missing-link-libraries.patch76
-rw-r--r--gnu/packages/patches/mrustc-riscv64-support.patch48
-rw-r--r--gnu/packages/patches/polkit-CVE-2021-4034.patch82
-rw-r--r--gnu/packages/patches/polkit-configure-elogind.patch15
-rw-r--r--gnu/packages/patches/polkit-disable-systemd.patch30
-rw-r--r--gnu/packages/patches/polkit-use-duktape.patch5030
-rw-r--r--gnu/packages/patches/postgresql-riscv-spinlocks.patch41
-rw-r--r--gnu/packages/patches/python-dateutil-pytest-compat.patch43
-rw-r--r--gnu/packages/patches/ruby-hydra-minimal-no-byebug.patch11
-rw-r--r--gnu/packages/patches/rustc-1.39.0-src.patch99
-rw-r--r--gnu/packages/patches/rustc-1.54.0-src.patch117
-rw-r--r--gnu/packages/patches/texlive-hyph-utf8-no-byebug.patch13
29 files changed, 494 insertions, 5957 deletions
diff --git a/gnu/packages/patches/akonadi-not-relocatable.patch b/gnu/packages/patches/akonadi-not-relocatable.patch
index c3964c5c05..bd4cbee79f 100644
--- a/gnu/packages/patches/akonadi-not-relocatable.patch
+++ b/gnu/packages/patches/akonadi-not-relocatable.patch
@@ -1,19 +1,18 @@
-From bc018b4bc816a3b51deb9739bedbf8a2268d0684 Mon Sep 17 00:00:00 2001
-From: gnidorah <gnidorah@users.noreply.github.com>
-Date: Fri, 22 Dec 2017 17:36:03 +0300
-Subject: [PATCH] Revert "Make Akonadi installation properly relocatable"
+From 4b90a0bd4411a66bbe6ecf85ce89a60a58bee969 Mon Sep 17 00:00:00 2001
+From: Thomas Tuegel <ttuegel@mailbox.org>
+Date: Sun, 25 Apr 2021 08:01:21 -0500
+Subject: [PATCH 3/3] akonadi revert make relocatable
-This reverts commit b2bb55f13f2ac783f89cc414de8c39f62fa2096a.
---
CMakeLists.txt | 3 ---
KF5AkonadiConfig.cmake.in | 6 +++---
2 files changed, 3 insertions(+), 6 deletions(-)
-Index: akonadi-19.08.0/CMakeLists.txt
-===================================================================
---- akonadi-19.08.0.orig/CMakeLists.txt
-+++ akonadi-19.08.0/CMakeLists.txt
-@@ -306,9 +306,6 @@ configure_package_config_file(
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 4e8cc81..63161b7 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -368,9 +368,6 @@ configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/KF5AkonadiConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/KF5AkonadiConfig.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
@@ -21,29 +20,25 @@ Index: akonadi-19.08.0/CMakeLists.txt
- AKONADI_INCLUDE_DIR
- KF5Akonadi_DATA_DIR
)
-
+
install(FILES
-Index: akonadi-19.08.0/KF5AkonadiConfig.cmake.in
-===================================================================
---- akonadi-19.08.0.orig/KF5AkonadiConfig.cmake.in
-+++ akonadi-19.08.0/KF5AkonadiConfig.cmake.in
-@@ -26,8 +26,8 @@ if(BUILD_TESTING)
- find_dependency(Qt5Test "@QT_REQUIRED_VERSION@")
- endif()
-
+diff --git a/KF5AkonadiConfig.cmake.in b/KF5AkonadiConfig.cmake.in
+index bcf7320..1574319 100644
+--- a/KF5AkonadiConfig.cmake.in
++++ b/KF5AkonadiConfig.cmake.in
+@@ -1,10 +1,10 @@
+ @PACKAGE_INIT@
+
-set_and_check(AKONADI_DBUS_INTERFACES_DIR "@PACKAGE_AKONADI_DBUS_INTERFACES_INSTALL_DIR@")
-set_and_check(AKONADI_INCLUDE_DIR "@PACKAGE_AKONADI_INCLUDE_DIR@")
+set_and_check(AKONADI_DBUS_INTERFACES_DIR "@AKONADI_DBUS_INTERFACES_INSTALL_DIR@")
+set_and_check(AKONADI_INCLUDE_DIR "@AKONADI_INCLUDE_DIR@")
-
- find_dependency(Boost "@Boost_MINIMUM_VERSION@")
-
-@@ -35,7 +35,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/KF5Ako
- include(${CMAKE_CURRENT_LIST_DIR}/KF5AkonadiMacros.cmake)
-
+
# The directory where akonadi-xml.xsd and kcfg2dbus.xsl are installed
-set(KF5Akonadi_DATA_DIR "@PACKAGE_KF5Akonadi_DATA_DIR@")
+set(KF5Akonadi_DATA_DIR "@KF5Akonadi_DATA_DIR@")
-
- ####################################################################################
- # CMAKE_AUTOMOC
+
+ # set the directories
+ if(NOT AKONADI_INSTALL_DIR)
+--
+2.31.1
diff --git a/gnu/packages/patches/akonadi-paths.patch b/gnu/packages/patches/akonadi-paths.patch
index ac08ec5448..bb4a19ede0 100644
--- a/gnu/packages/patches/akonadi-paths.patch
+++ b/gnu/packages/patches/akonadi-paths.patch
@@ -1,26 +1,26 @@
This is based on the respectve patch from NixPkgs, but with the parts pinning
-mysql and postgresql executables removed. The our package definition on why.
+mysql and postgresql executables removed. See our package definition on why.
diff --git a/src/akonadicontrol/agentmanager.cpp b/src/akonadicontrol/agentmanager.cpp
--- a/src/akonadicontrol/agentmanager.cpp
+++ b/src/akonadicontrol/agentmanager.cpp
-@@ -61,7 +61,7 @@ public:
- []() {
- QCoreApplication::instance()->exit(255);
- });
+@@ -47,7 +47,7 @@ public:
+ connect(this, &Akonadi::ProcessControl::unableToStart, this, []() {
+ QCoreApplication::instance()->exit(255);
+ });
- start(QStringLiteral("akonadiserver"), args, RestartOnCrash);
-+ start(QLatin1String(NIX_OUT "/bin/akonadiserver"), args, RestartOnCrash);
++ start(QStringLiteral(NIX_OUT "/bin/akonadiserver"), args, RestartOnCrash);
}
-
+
~StorageProcessControl() override
-@@ -84,7 +84,7 @@ public:
- []() {
- qCCritical(AKONADICONTROL_LOG) << "Failed to start AgentServer!";
- });
+@@ -69,7 +69,7 @@ public:
+ connect(this, &Akonadi::ProcessControl::unableToStart, this, []() {
+ qCCritical(AKONADICONTROL_LOG) << "Failed to start AgentServer!";
+ });
- start(QStringLiteral("akonadi_agent_server"), args, RestartOnCrash);
-+ start(QLatin1String(NIX_OUT "/bin/akonadi_agent_server"), args, RestartOnCrash);
++ start(QStringLiteral(NIX_OUT "/bin/akonadi_agent_server"), args, RestartOnCrash);
}
-
+
~AgentServerProcessControl() override
diff --git a/src/akonadicontrol/agentprocessinstance.cpp b/src/akonadicontrol/agentprocessinstance.cpp
--- a/src/akonadicontrol/agentprocessinstance.cpp
@@ -37,12 +37,12 @@ diff --git a/src/akonadicontrol/agentprocessinstance.cpp b/src/akonadicontrol/ag
diff --git a/src/server/storage/dbconfigmysql.cpp b/src/server/storage/dbconfigmysql.cpp
--- a/src/server/storage/dbconfigmysql.cpp
+++ b/src/server/storage/dbconfigmysql.cpp
-@@ -209,7 +209,7 @@ bool DbConfigMysql::startInternalServer()
+@@ -215,7 +215,7 @@ bool DbConfigMysql::startInternalServer()
#endif
-
+
// generate config file
- const QString globalConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-global.conf"));
+ const QString globalConfig = QLatin1String(NIX_OUT "/etc/xdg/akonadi/mysql-global.conf");
- const QString localConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-local.conf"));
+ const QString localConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-local.conf"));
const QString actualConfig = StandardDirs::saveDir("data") + QLatin1String("/mysql.conf");
if (globalConfig.isEmpty()) {
diff --git a/gnu/packages/patches/akonadi-timestamps.patch b/gnu/packages/patches/akonadi-timestamps.patch
index e299a6991f..df81fdb2dc 100644
--- a/gnu/packages/patches/akonadi-timestamps.patch
+++ b/gnu/packages/patches/akonadi-timestamps.patch
@@ -2,12 +2,12 @@ Index: akonadi-19.08.0/src/server/storage/dbconfigmysql.cpp
===================================================================
--- akonadi-19.08.0.orig/src/server/storage/dbconfigmysql.cpp
+++ akonadi-19.08.0/src/server/storage/dbconfigmysql.cpp
-@@ -235,8 +235,7 @@ bool DbConfigMysql::startInternalServer(
+@@ -260,8 +260,7 @@ bool DbConfigMysql::startInternalServer(
bool confUpdate = false;
QFile actualFile(actualConfig);
// update conf only if either global (or local) is newer than actual
-- if ((QFileInfo(globalConfig).lastModified() > QFileInfo(actualFile).lastModified()) ||
-- (QFileInfo(localConfig).lastModified() > QFileInfo(actualFile).lastModified())) {
+- if ((QFileInfo(globalConfig).lastModified() > QFileInfo(actualFile).lastModified())
+- || (QFileInfo(localConfig).lastModified() > QFileInfo(actualFile).lastModified())) {
+ if (true) {
QFile globalFile(globalConfig);
QFile localFile(localConfig);
diff --git a/gnu/packages/patches/firebird-riscv64-support-pt1.patch b/gnu/packages/patches/firebird-riscv64-support-pt1.patch
new file mode 100644
index 0000000000..a46bfe208a
--- /dev/null
+++ b/gnu/packages/patches/firebird-riscv64-support-pt1.patch
@@ -0,0 +1,42 @@
+https://salsa.debian.org/firebird-team/firebird3.0/-/raw/master/debian/patches/out/riscv64-prefix.patch
+
+Description: add builds/posix/prefix.linux_riscv64, missing upstream
+ It appears the commit adding RiscV64 support
+ (1e8e7858db84750a77006d307bf28e9686f9414e) misses the build prefix file
+ Here's one submitted by Manuel A. Fernandez Montecelo
+Author: Manuel A. Fernandez Montecelo <manuel.montezelo@gmail.com>
+Bug: http://tracker.firebirdsql.org/browse/CORE-5851
+Bug-Debian: https://bugs.debian.org/895257
+Author: Manuel A. Fernandez Montecelo <manuel.montezelo@gmail.com>
+
+--- /dev/null
++++ b/builds/posix/prefix.linux_riscv64
+@@ -0,0 +1,28 @@
++# The contents of this file are subject to the Interbase Public
++# License Version 1.0 (the "License"); you may not use this file
++# except in compliance with the License. You may obtain a copy
++# of the License at http://www.Inprise.com/IPL.html
++#
++# Software distributed under the License is distributed on an
++# "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
++# or implied. See the License for the specific language governing
++# rights and limitations under the License.
++#
++# The Original Code was created by Inprise Corporation
++# and its predecessors. Portions created by Inprise Corporation are
++# Copyright (C) Inprise Corporation.
++#
++# All Rights Reserved.
++# Contributor(s): ______________________________________.
++# Start of file prefix.linux: $(VERSION) $(PLATFORM)
++# 14 Apr 2008 Alan Barclay alan AT escribe.co.uk
++# 2018, "Manuel A. Fernandez Montecelo" <manuel.montezelo@gmail.com>
++
++
++#LD=@CXX@
++
++#PROD_FLAGS=-ggdb -O3 -fno-omit-frame-pointer -DLINUX -pipe -MMD -fPIC
++#DEV_FLAGS=-ggdb -DLINUX -DDEBUG_GDS_ALLOC -pipe -MMD -p -fPIC -Wall -Wno-switch
++
++PROD_FLAGS=-O3 -DLINUX -DRISCV64 -pipe -p -MMD -fPIC -fsigned-char -fmessage-length=0 -std=gnu++03 -fno-delete-null-pointer-checks
++DEV_FLAGS=-ggdb -DLINUX -DRISCV64 -pipe -p -MMD -fPIC -Wall -fsigned-char -fmessage-length=0 -Wno-non-virtual-dtor
diff --git a/gnu/packages/patches/firebird-riscv64-support-pt2.patch b/gnu/packages/patches/firebird-riscv64-support-pt2.patch
new file mode 100644
index 0000000000..a6f93c1a50
--- /dev/null
+++ b/gnu/packages/patches/firebird-riscv64-support-pt2.patch
@@ -0,0 +1,108 @@
+https://salsa.debian.org/firebird-team/firebird3.0/-/raw/master/debian/patches/upstream/riscv64-support.patch
+
+1e8e7858db84750a77006d307bf28e9686f9414e Patch for CORE-5779: support for riscv64, also some code fixes related with prior ports
+ Minor corrections compared to the commit above due to whitespace/spelling
+ differences with 3.0 version
+Bug-Debian: https://bugs.debian.org/895257
+Bug: http://tracker.firebirdsql.org/browse/CORE-5779
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -251,6 +251,18 @@ dnl CPU_TYPE=ppc64
+ libdir=/usr/lib64
+ ;;
+
++ riscv64*-*-linux*)
++ MAKEFILE_PREFIX=linux_riscv64
++ INSTALL_PREFIX=linux
++ PLATFORM=LINUX
++ AC_DEFINE(LINUX, 1, [Define this if OS is Linux])
++ EDITLINE_FLG=Y
++ SHRLIB_EXT=so
++ STD_EDITLINE=true
++ STD_ICU=true
++ libdir=/usr/lib64
++ ;;
++
+ powerpc64le-*-linux*)
+ MAKEFILE_PREFIX=linux_powerpc64el
+ INSTALL_PREFIX=linux
+--- a/src/common/classes/DbImplementation.cpp
++++ b/src/common/classes/DbImplementation.cpp
+@@ -49,6 +49,7 @@ static const UCHAR CpuAlpha = 14;
+ static const UCHAR CpuArm64 = 15;
+ static const UCHAR CpuPowerPc64el = 16;
+ static const UCHAR CpuM68k = 17;
++static const UCHAR CpuRiscV64 = 18;
+
+ static const UCHAR OsWindows = 0;
+ static const UCHAR OsLinux = 1;
+@@ -89,7 +90,8 @@ const char* hardware[] = {
+ "Alpha",
+ "ARM64",
+ "PowerPC64el",
+- "M68k"
++ "M68k",
++ "RiscV64"
+ };
+
+ const char* operatingSystem[] = {
+@@ -116,22 +118,22 @@ const char* compiler[] = {
+ // This table lists pre-fb3 implementation codes
+ const UCHAR backwardTable[FB_NELEM(hardware) * FB_NELEM(operatingSystem)] =
+ {
+-// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el
+-/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+-/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85,
+-/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+-/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+-/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0,
+-/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+-/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+-/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+-/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
++// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PPC64el M68k RiscV64
++/* Windows */ 50, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++/* Linux */ 60, 66, 65, 69, 86, 71, 72, 75, 76, 79, 78, 80, 81, 82, 83, 84, 85, 87, 88,
++/* Darwin */ 70, 73, 0, 63, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++/* Solaris */ 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++/* HPUX */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0,
++/* AIX */ 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++/* MVS */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++/* FreeBSD */ 61, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++/* NetBSD */ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ const UCHAR backEndianess[FB_NELEM(hardware)] =
+ {
+-// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PowerPC64el M68k
+- 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1
++// Intel AMD Sparc PPC PPC64 MIPSEL MIPS ARM IA64 s390 s390x SH SHEB HPPA Alpha ARM64 PPC64el M68k RiscV64
++ 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0,
+ };
+
+ } // anonymous namespace
+--- a/src/common/common.h
++++ b/src/common/common.h
+@@ -135,6 +135,10 @@
+ #define FB_CPU CpuArm64
+ #endif /* ARM64 */
+
++#ifdef RISCV64
++#define FB_CPU CpuRiscV64
++#endif /* RISCV64 */
++
+ #ifdef sparc
+ #define FB_CPU CpuUltraSparc
+ #define RISC_ALIGNMENT
+--- a/src/jrd/inf_pub.h
++++ b/src/jrd/inf_pub.h
+@@ -247,7 +247,7 @@ enum info_db_implementations
+ isc_info_db_impl_linux_ppc64el = 85,
+ isc_info_db_impl_linux_ppc64 = 86,
+ isc_info_db_impl_linux_m68k = 87,
+-
++ isc_info_db_impl_linux_riscv64 = 88,
+
+ isc_info_db_impl_last_value // Leave this LAST!
+ };
diff --git a/gnu/packages/patches/freeglut-gcc-compat.patch b/gnu/packages/patches/freeglut-gcc-compat.patch
deleted file mode 100644
index 126bbd89f4..0000000000
--- a/gnu/packages/patches/freeglut-gcc-compat.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-Fix build failure with GCC 10.
-
-Taken from upstream:
-https://github.com/dcnieho/FreeGLUT/commit/b9998bbc1e1c329f6bf69c24606a2be7a4973b8c
-
-diff --git a/src/fg_gl2.c b/src/fg_gl2.c
---- a/src/fg_gl2.c
-+++ b/src/fg_gl2.c
-@@ -27,6 +27,20 @@
- #include "fg_internal.h"
- #include "fg_gl2.h"
-
-+#ifndef GL_ES_VERSION_2_0
-+/* GLES2 has the corresponding entry points built-in, and these fgh-prefixed
-+ * names are defined in fg_gl2.h header to reference them, for any other case,
-+ * define them as function pointers here.
-+ */
-+FGH_PFNGLGENBUFFERSPROC fghGenBuffers;
-+FGH_PFNGLDELETEBUFFERSPROC fghDeleteBuffers;
-+FGH_PFNGLBINDBUFFERPROC fghBindBuffer;
-+FGH_PFNGLBUFFERDATAPROC fghBufferData;
-+FGH_PFNGLENABLEVERTEXATTRIBARRAYPROC fghEnableVertexAttribArray;
-+FGH_PFNGLDISABLEVERTEXATTRIBARRAYPROC fghDisableVertexAttribArray;
-+FGH_PFNGLVERTEXATTRIBPOINTERPROC fghVertexAttribPointer;
-+#endif
-+
- void FGAPIENTRY glutSetVertexAttribCoord3(GLint attrib) {
- if (fgStructure.CurrentWindow != NULL)
- fgStructure.CurrentWindow->Window.attribute_v_coord = attrib;
-diff --git a/src/fg_gl2.h b/src/fg_gl2.h
---- a/src/fg_gl2.h
-+++ b/src/fg_gl2.h
-@@ -67,13 +67,13 @@ typedef void (APIENTRY *FGH_PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
- typedef void (APIENTRY *FGH_PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint);
- typedef void (APIENTRY *FGH_PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
-
--FGH_PFNGLGENBUFFERSPROC fghGenBuffers;
--FGH_PFNGLDELETEBUFFERSPROC fghDeleteBuffers;
--FGH_PFNGLBINDBUFFERPROC fghBindBuffer;
--FGH_PFNGLBUFFERDATAPROC fghBufferData;
--FGH_PFNGLENABLEVERTEXATTRIBARRAYPROC fghEnableVertexAttribArray;
--FGH_PFNGLDISABLEVERTEXATTRIBARRAYPROC fghDisableVertexAttribArray;
--FGH_PFNGLVERTEXATTRIBPOINTERPROC fghVertexAttribPointer;
-+extern FGH_PFNGLGENBUFFERSPROC fghGenBuffers;
-+extern FGH_PFNGLDELETEBUFFERSPROC fghDeleteBuffers;
-+extern FGH_PFNGLBINDBUFFERPROC fghBindBuffer;
-+extern FGH_PFNGLBUFFERDATAPROC fghBufferData;
-+extern FGH_PFNGLENABLEVERTEXATTRIBARRAYPROC fghEnableVertexAttribArray;
-+extern FGH_PFNGLDISABLEVERTEXATTRIBARRAYPROC fghDisableVertexAttribArray;
-+extern FGH_PFNGLVERTEXATTRIBPOINTERPROC fghVertexAttribPointer;
-
- # endif
-
diff --git a/gnu/packages/patches/grantlee-merge-theme-dirs.patch b/gnu/packages/patches/grantlee-merge-theme-dirs.patch
deleted file mode 100644
index 96a15a387b..0000000000
--- a/gnu/packages/patches/grantlee-merge-theme-dirs.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-Taken from nixpkgs, see
-grantleetheme: merge themes across multiple prefixes
-<https://github.com/NixOS/nixpkgs/commits/master/pkgs/applications/kde/grantleetheme/grantlee-merge-theme-dirs.patch>
-
-
-diff --git a/src/grantleetheme.cpp b/src/grantleetheme.cpp
-index 27d5bc8..8d43140 100644
---- a/src/grantleetheme.cpp
-+++ b/src/grantleetheme.cpp
-@@ -46,7 +46,7 @@ ThemePrivate::ThemePrivate(const ThemePrivate &other)
- , description(other.description)
- , name(other.name)
- , dirName(other.dirName)
-- , absolutePath(other.absolutePath)
-+ , absolutePaths(other.absolutePaths)
- , author(other.author)
- , email(other.email)
- , loader(other.loader)
-@@ -64,12 +64,15 @@ void ThemePrivate::setupEngine()
-
- void ThemePrivate::setupLoader()
- {
-- // Get the parent dir with themes, we set the theme directory separately
-- QDir dir(absolutePath);
-- dir.cdUp();
-+ QStringList templateDirs;
-+ for (const QString& path : absolutePaths) {
-+ QDir dir(path);
-+ dir.cdUp();
-+ templateDirs << dir.absolutePath();
-+ }
-
- loader = QSharedPointer<GrantleeTheme::QtResourceTemplateLoader>::create();
-- loader->setTemplateDirs({ dir.absolutePath() });
-+ loader->setTemplateDirs(templateDirs);
- loader->setTheme(dirName);
-
- if (!sEngine) {
-@@ -121,7 +124,7 @@ Theme::Theme(const QString &themePath, const QString &dirName, const QString &de
- KConfigGroup group(&config, QStringLiteral("Desktop Entry"));
- if (group.isValid()) {
- d->dirName = dirName;
-- d->absolutePath = themePath;
-+ d->absolutePaths = QStringList(themePath);
- d->name = group.readEntry("Name", QString());
- d->description = group.readEntry("Description", QString());
- d->themeFileName = group.readEntry("FileName", QString());
-@@ -140,7 +143,7 @@ Theme::~Theme()
-
- bool Theme::operator==(const Theme &other) const
- {
-- return isValid() && other.isValid() && d->absolutePath == other.absolutePath();
-+ return isValid() && other.isValid() && d->absolutePaths == other.absolutePaths();
- }
-
- Theme &Theme::operator=(const Theme &other)
-@@ -184,7 +187,15 @@ QString Theme::dirName() const
-
- QString Theme::absolutePath() const
- {
-- return d->absolutePath;
-+ if (! d->absolutePaths.isEmpty()) {
-+ return d->absolutePaths.first();
-+ };
-+ return QString();
-+}
-+
-+QStringList Theme::absolutePaths() const
-+{
-+ return d->absolutePaths;
- }
-
- QString Theme::author() const
-@@ -223,6 +231,13 @@ QString Theme::render(const QString &templateName, const QVariantHash &data, con
- return result;
- }
-
-+void Theme::addThemeDir(const QString& path)
-+{
-+ QDir dir(path);
-+ dir.cdUp();
-+ d->absolutePaths << dir.absolutePath();
-+}
-+
- void Theme::addPluginPath(const QString &path)
- {
- if (!ThemePrivate::sEngine) {
-diff --git a/src/grantleetheme.h b/src/grantleetheme.h
-index a25c27b..be38299 100644
---- a/src/grantleetheme.h
-+++ b/src/grantleetheme.h
-@@ -48,11 +48,14 @@ public:
- Q_REQUIRED_RESULT QStringList displayExtraVariables() const;
- Q_REQUIRED_RESULT QString dirName() const;
- Q_REQUIRED_RESULT QString absolutePath() const;
-+ Q_REQUIRED_RESULT QStringList absolutePaths() const;
- Q_REQUIRED_RESULT QString author() const;
- Q_REQUIRED_RESULT QString authorEmail() const;
-
- Q_REQUIRED_RESULT QString render(const QString &templateName, const QVariantHash &data, const QByteArray &applicationDomain = QByteArray());
-
-+ void addThemeDir(const QString&);
-+
- static void addPluginPath(const QString &path);
-
- private:
-diff --git a/src/grantleetheme_p.h b/src/grantleetheme_p.h
-index eb73dcb..00510e9 100644
---- a/src/grantleetheme_p.h
-+++ b/src/grantleetheme_p.h
-@@ -43,7 +43,7 @@ public:
- QString description;
- QString name;
- QString dirName;
-- QString absolutePath;
-+ QStringList absolutePaths;
- QString author;
- QString email;
-
-diff --git a/src/grantleethememanager.cpp b/src/grantleethememanager.cpp
-index 606d717..dc99041 100644
---- a/src/grantleethememanager.cpp
-+++ b/src/grantleethememanager.cpp
-@@ -125,25 +125,18 @@ public:
-
- for (const QString &directory : qAsConst(themesDirectories)) {
- QDirIterator dirIt(directory, QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
-- QStringList alreadyLoadedThemeName;
- while (dirIt.hasNext()) {
- dirIt.next();
- const QString dirName = dirIt.fileName();
- GrantleeTheme::Theme theme = q->loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName);
- if (theme.isValid()) {
- QString themeName = theme.name();
-- if (alreadyLoadedThemeName.contains(themeName)) {
-- int i = 2;
-- const QString originalName(theme.name());
-- while (alreadyLoadedThemeName.contains(themeName)) {
-- themeName = originalName + QStringLiteral(" (%1)").arg(i);
-- ++i;
-- }
-- theme.d->name = themeName;
-+ QMap<QString, GrantleeTheme::Theme>::iterator i = themes.find(dirName);
-+ if (i != themes.end()) {
-+ i.value().addThemeDir(dirIt.filePath());
-+ } else {
-+ themes.insert(dirName, theme);
- }
-- alreadyLoadedThemeName << themeName;
-- themes.insert(dirName, theme);
-- //qDebug()<<" theme.name()"<<theme.name();
- }
- }
- watch->addDir(directory);
-@@ -366,7 +359,7 @@ QString ThemeManager::pathFromThemes(const QString &themesRelativePath, const QS
- GrantleeTheme::Theme theme = loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName);
- if (theme.isValid()) {
- if (dirName == themeName) {
-- return theme.absolutePath();
-+ return theme.absolutePaths().first();
- }
- }
- }
diff --git a/gnu/packages/patches/gst-plugins-good-fix-test.patch b/gnu/packages/patches/gst-plugins-good-fix-test.patch
deleted file mode 100644
index 38ec0ba802..0000000000
--- a/gnu/packages/patches/gst-plugins-good-fix-test.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-Fix a broken test:
-
-https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/803
-
-Patches copied from upstream source repository:
-
-https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/commit/2ce5909f3a0b0da3abb7b794215d6b8b72a3b7fa
-https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/commit/f5310ce346180a717f091f2f09bcbb3ddfb15436
-
-From 2ce5909f3a0b0da3abb7b794215d6b8b72a3b7fa Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com>
-Date: Thu, 12 Nov 2020 23:38:21 +0000
-Subject: [PATCH 1/2] tests: qtdemux: fix crash on 32-bit architectures
-
-Fixes https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/803
-
-Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/815>
----
- tests/check/elements/qtdemux.c | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/tests/check/elements/qtdemux.c b/tests/check/elements/qtdemux.c
-index 5271c6576..0c748278b 100644
---- a/tests/check/elements/qtdemux.c
-+++ b/tests/check/elements/qtdemux.c
-@@ -797,9 +797,10 @@ GST_START_TEST (test_qtdemux_pad_names)
- "protection-system", G_TYPE_STRING,
- "9a04f079-9840-4286-ab92-e65be0885f95", NULL);
- caps =
-- gst_caps_new_simple ("video/quicktime", "variant", G_TYPE_STRING,
-- "mss-fragmented", "timesacle", G_TYPE_UINT64, 10000000, "media-caps",
-- GST_TYPE_CAPS, mediacaps, NULL);
-+ gst_caps_new_simple ("video/quicktime",
-+ "variant", G_TYPE_STRING, "mss-fragmented",
-+ "timesacle", G_TYPE_UINT64, G_GUINT64_CONSTANT (10000000),
-+ "media-caps", GST_TYPE_CAPS, mediacaps, NULL);
-
- /* Send segment event* */
- event = gst_event_new_caps (caps);
-@@ -852,9 +853,10 @@ GST_START_TEST (test_qtdemux_pad_names)
- "protection-system", G_TYPE_STRING,
- "9a04f079-9840-4286-ab92-e65be0885f95", NULL);
- caps =
-- gst_caps_new_simple ("video/quicktime", "variant", G_TYPE_STRING,
-- "mss-fragmented", "timesacle", G_TYPE_UINT64, 10000000, "media-caps",
-- GST_TYPE_CAPS, mediacaps, NULL);
-+ gst_caps_new_simple ("video/quicktime",
-+ "variant", G_TYPE_STRING, "mss-fragmented",
-+ "timesacle", G_TYPE_UINT64, G_GUINT64_CONSTANT (10000000),
-+ "media-caps", GST_TYPE_CAPS, mediacaps, NULL);
-
- /* Send segment event* */
- event = gst_event_new_caps (caps);
---
-2.30.0
-
-
-From f5310ce346180a717f091f2f09bcbb3ddfb15436 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com>
-Date: Thu, 12 Nov 2020 23:39:21 +0000
-Subject: [PATCH 2/2] tests: qtdemux: fix typo in caps field
-
-timesacle -> timescale
-
-Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/815>
----
- tests/check/elements/qtdemux.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/tests/check/elements/qtdemux.c b/tests/check/elements/qtdemux.c
-index 0c748278b..4a14c45c0 100644
---- a/tests/check/elements/qtdemux.c
-+++ b/tests/check/elements/qtdemux.c
-@@ -799,7 +799,7 @@ GST_START_TEST (test_qtdemux_pad_names)
- caps =
- gst_caps_new_simple ("video/quicktime",
- "variant", G_TYPE_STRING, "mss-fragmented",
-- "timesacle", G_TYPE_UINT64, G_GUINT64_CONSTANT (10000000),
-+ "timescale", G_TYPE_UINT64, G_GUINT64_CONSTANT (10000000),
- "media-caps", GST_TYPE_CAPS, mediacaps, NULL);
-
- /* Send segment event* */
-@@ -855,7 +855,7 @@ GST_START_TEST (test_qtdemux_pad_names)
- caps =
- gst_caps_new_simple ("video/quicktime",
- "variant", G_TYPE_STRING, "mss-fragmented",
-- "timesacle", G_TYPE_UINT64, G_GUINT64_CONSTANT (10000000),
-+ "timescale", G_TYPE_UINT64, G_GUINT64_CONSTANT (10000000),
- "media-caps", GST_TYPE_CAPS, mediacaps, NULL);
-
- /* Send segment event* */
---
-2.30.0
-
diff --git a/gnu/packages/patches/kdbusaddons-kinit-file-name.patch b/gnu/packages/patches/kdbusaddons-kinit-file-name.patch
deleted file mode 100644
index ffed88e043..0000000000
--- a/gnu/packages/patches/kdbusaddons-kinit-file-name.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Add placeholder for kinit's store file name.
-
-diff --git a/src/kdeinitinterface.cpp b/src/kdeinitinterface.cpp
-index 22fa5e5..3d40937 100644
---- a/src/kdeinitinterface.cpp
-+++ b/src/kdeinitinterface.cpp
-@@ -52,7 +52,7 @@ void KDEInitInterface::ensureKdeinitRunning()
- // If not found in system paths, search other paths
- if (srv.isEmpty()) {
- const QStringList searchPaths = QStringList()
-- << QCoreApplication::applicationDirPath() // then look where our application binary is located
-+ << QString::fromUtf8("@SUBSTITUTEME@/bin") // using QStringLiteral would be more efficient, but breaks guix store reference detection.
- << QLibraryInfo::location(QLibraryInfo::BinariesPath); // look where exec path is (can be set in qt.conf)
- srv = QStandardPaths::findExecutable(QStringLiteral("kdeinit5"), searchPaths);
- if (srv.isEmpty()) {
diff --git a/gnu/packages/patches/kinit-kdeinit-extra_libs.patch b/gnu/packages/patches/kinit-kdeinit-extra_libs.patch
index 1271f3df7d..b27c6ed535 100644
--- a/gnu/packages/patches/kinit-kdeinit-extra_libs.patch
+++ b/gnu/packages/patches/kinit-kdeinit-extra_libs.patch
@@ -21,27 +21,6 @@ pkgs/development/libraries/kde-frameworks/kinit/kdeinit-extra_libs.patch
#endif
};
#endif
-@@ -1533,20 +1531,6 @@ static int initXconnection()
- }
- #endif
-
--#ifndef Q_OS_OSX
--// Find a shared lib in the lib dir, e.g. libkio.so.
--// Completely unrelated to plugins.
--static QString findSharedLib(const QString &lib)
--{
-- QString path = QFile::decodeName(CMAKE_INSTALL_PREFIX "/" LIB_INSTALL_DIR "/") + lib;
-- if (QFile::exists(path)) {
-- return path;
-- }
-- // We could also look in LD_LIBRARY_PATH, but really, who installs the main libs in different prefixes?
-- return QString();
--}
--#endif
--
- extern "C" {
-
- static void secondary_child_handler(int)
@@ -1673,7 +1673,7 @@
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
if (!d.suicide && qEnvironmentVariableIsEmpty("KDE_IS_PRELINKED")) {
diff --git a/gnu/packages/patches/kinit-kdeinit-libpath.patch b/gnu/packages/patches/kinit-kdeinit-libpath.patch
deleted file mode 100644
index 6382e8804b..0000000000
--- a/gnu/packages/patches/kinit-kdeinit-libpath.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-Search libraries in GUIX_KF5INIT_LIB_PATH.
-
-Based on an idea by NixOs
-pkgs/development/libraries/kde-frameworks/kinit/kinit-libpath.patch
-
-===================================================================
---- kinit-5.32.0/src/kdeinit/kinit.cpp.orig 2017-10-22 21:02:20.908765455 +0200
-+++ kinit-5.32.0/src/kdeinit/kinit.cpp 2017-10-22 21:03:25.312818248 +0200
-@@ -623,20 +623,18 @@
- if (libpath_relative) {
- // NB: Because Qt makes the actual dlopen() call, the
- // RUNPATH of kdeinit is *not* respected - see
- // https://sourceware.org/bugzilla/show_bug.cgi?id=13945
- // - so we try hacking it in ourselves
-- QString install_lib_dir = QFile::decodeName(
-- CMAKE_INSTALL_PREFIX "/" LIB_INSTALL_DIR "/");
-- QString orig_libpath = libpath;
-- libpath = install_lib_dir + libpath;
-- l.setFileName(libpath);
-- if (!l.load()) {
-- libpath = orig_libpath;
-- l.setFileName(libpath);
-- l.load();
-- }
-+ // Try to load the library relative to the active profiles.
-+ QByteArrayList profiles = qgetenv("KDEINIT5_LIBRARY_PATH").split(':');
-+ for (const QByteArray &profile: profiles) {
-+ if (!profile.isEmpty()) {
-+ l.setFileName(QFile::decodeName(profile) + QStringLiteral("/") + libpath);
-+ if (l.load()) break;
-+ }
-+ }
- } else {
- l.load();
- }
- if (!l.isLoaded()) {
- QString ltdlError(l.errorString());
diff --git a/gnu/packages/patches/kio-search-smbd-on-PATH.patch b/gnu/packages/patches/kio-search-smbd-on-PATH.patch
index 55535ffa11..5118c9a361 100644
--- a/gnu/packages/patches/kio-search-smbd-on-PATH.patch
+++ b/gnu/packages/patches/kio-search-smbd-on-PATH.patch
@@ -1,30 +1,24 @@
-Adopted from NixOS
-pkgs/development/libraries/kde-frameworks/kio/samba-search-path.patch
+From af54a2a37655df26a33bc6783cb472c38f65322f Mon Sep 17 00:00:00 2001
+From: Thomas Tuegel <ttuegel@mailbox.org>
+Date: Sun, 28 Mar 2021 10:31:12 -0500
+Subject: [PATCH 1/2] Remove impure smbd search path
-===================================================================
---- kio-5.17.0.orig/src/core/ksambashare.cpp
-+++ kio-5.17.0/src/core/ksambashare.cpp
-@@ -67,13 +67,18 @@ KSambaSharePrivate::~KSambaSharePrivate(
-
+---
+ src/core/ksambashare.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/ksambashare.cpp b/src/core/ksambashare.cpp
+index e810ce4..7cfb4e6 100644
+--- a/src/core/ksambashare.cpp
++++ b/src/core/ksambashare.cpp
+@@ -61,7 +61,7 @@ KSambaSharePrivate::~KSambaSharePrivate()
bool KSambaSharePrivate::isSambaInstalled()
{
-- if (QFile::exists(QStringLiteral("/usr/sbin/smbd"))
-- || QFile::exists(QStringLiteral("/usr/local/sbin/smbd"))) {
-- return true;
-+ const QByteArray pathEnv = qgetenv("PATH");
-+ if (!pathEnv.isEmpty()) {
-+ QLatin1Char pathSep(':');
-+ QStringList paths = QFile::decodeName(pathEnv).split(pathSep, QString::SkipEmptyParts);
-+ for (QStringList::iterator it = paths.begin(); it != paths.end(); ++it) {
-+ it->append(QStringLiteral("/smbd"));
-+ if (QFile::exists(*it)) {
-+ return true;
-+ }
-+ }
+ const bool daemonExists =
+- !QStandardPaths::findExecutable(QStringLiteral("smbd"), {QStringLiteral("/usr/sbin/"), QStringLiteral("/usr/local/sbin/")}).isEmpty();
++ !QStandardPaths::findExecutable(QStringLiteral("smbd")).isEmpty();
+ if (!daemonExists) {
+ qCDebug(KIO_CORE_SAMBASHARE) << "KSambaShare: Could not find smbd";
}
-
-- //qDebug() << "Samba is not installed!";
--
- return false;
- }
-
+--
+2.30.1
diff --git a/gnu/packages/patches/kmail-Fix-missing-link-libraries.patch b/gnu/packages/patches/kmail-Fix-missing-link-libraries.patch
deleted file mode 100644
index fc784d63dd..0000000000
--- a/gnu/packages/patches/kmail-Fix-missing-link-libraries.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 6b0a3a60870499b20ce9ae2ea07cbc5ee53cbdd2 Mon Sep 17 00:00:00 2001
-From: Hartmut Goebel <h.goebel@crazy-compilers.com>
-Date: Tue, 21 Jan 2020 23:23:38 +0100
-Subject: [PATCH] Fix missing link libraries.
-
-See <https://phabricator.kde.org/D26821>
-
-These are only actually missing if the libraries reside in different
-prefixes, as it is the case in Guix or Nix.
----
- agents/archivemailagent/CMakeLists.txt | 1 +
- agents/followupreminderagent/CMakeLists.txt | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/agents/archivemailagent/CMakeLists.txt b/agents/archivemailagent/CMakeLists.txt
-index 95c6249de..d0ddcd475 100644
---- a/agents/archivemailagent/CMakeLists.txt
-+++ b/agents/archivemailagent/CMakeLists.txt
-@@ -22,6 +22,7 @@ ki18n_wrap_ui(libarchivemailagent_SRCS ui/archivemailwidget.ui )
- add_library(archivemailagent STATIC ${libarchivemailagent_SRCS})
- target_link_libraries(archivemailagent
- KF5::MailCommon
-+ KF5::Libkdepim
- KF5::I18n
- KF5::Notifications
- KF5::KIOWidgets
-diff --git a/agents/followupreminderagent/CMakeLists.txt b/agents/followupreminderagent/CMakeLists.txt
-index 9ae7eaa29..527044807 100644
---- a/agents/followupreminderagent/CMakeLists.txt
-+++ b/agents/followupreminderagent/CMakeLists.txt
-@@ -27,6 +27,7 @@ target_link_libraries(followupreminderagent
- KF5::AkonadiMime
- KF5::AkonadiAgentBase
- KF5::DBusAddons
-+ KF5::FollowupReminder
- KF5::XmlGui
- KF5::KIOWidgets
- KF5::Notifications
---
-2.21.1
-
diff --git a/gnu/packages/patches/kmplayer-aarch64.patch b/gnu/packages/patches/kmplayer-aarch64.patch
deleted file mode 100644
index 76f713be96..0000000000
--- a/gnu/packages/patches/kmplayer-aarch64.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-Index: b/src/moz-sdk/prcpucfg.h
-===================================================================
---- a/src/moz-sdk/prcpucfg.h
-+++ b/src/moz-sdk/prcpucfg.h
-@@ -288,6 +288,52 @@
- #define PR_BYTES_PER_WORD_LOG2 3
- #define PR_BYTES_PER_DWORD_LOG2 3
-
-+#elif defined(__aarch64__)
-+
-+#define IS_LITTLE_ENDIAN 1
-+#undef IS_BIG_ENDIAN
-+#define IS_64
-+
-+#define PR_BYTES_PER_BYTE 1
-+#define PR_BYTES_PER_SHORT 2
-+#define PR_BYTES_PER_INT 4
-+#define PR_BYTES_PER_INT64 8
-+#define PR_BYTES_PER_LONG 8
-+#define PR_BYTES_PER_FLOAT 4
-+#define PR_BYTES_PER_DOUBLE 8
-+#define PR_BYTES_PER_WORD 8
-+#define PR_BYTES_PER_DWORD 8
-+
-+#define PR_BITS_PER_BYTE 8
-+#define PR_BITS_PER_SHORT 16
-+#define PR_BITS_PER_INT 32
-+#define PR_BITS_PER_INT64 64
-+#define PR_BITS_PER_LONG 64
-+#define PR_BITS_PER_FLOAT 32
-+#define PR_BITS_PER_DOUBLE 64
-+#define PR_BITS_PER_WORD 64
-+
-+#define PR_BITS_PER_BYTE_LOG2 3
-+#define PR_BITS_PER_SHORT_LOG2 4
-+#define PR_BITS_PER_INT_LOG2 5
-+#define PR_BITS_PER_INT64_LOG2 6
-+#define PR_BITS_PER_LONG_LOG2 6
-+#define PR_BITS_PER_FLOAT_LOG2 5
-+#define PR_BITS_PER_DOUBLE_LOG2 6
-+#define PR_BITS_PER_WORD_LOG2 6
-+
-+#define PR_ALIGN_OF_SHORT 2
-+#define PR_ALIGN_OF_INT 4
-+#define PR_ALIGN_OF_LONG 8
-+#define PR_ALIGN_OF_INT64 8
-+#define PR_ALIGN_OF_FLOAT 4
-+#define PR_ALIGN_OF_DOUBLE 8
-+#define PR_ALIGN_OF_POINTER 8
-+#define PR_ALIGN_OF_WORD 8
-+
-+#define PR_BYTES_PER_WORD_LOG2 3
-+#define PR_BYTES_PER_DWORD_LOG2 3
-+
- #elif defined(__mc68000__)
-
- #undef IS_LITTLE_ENDIAN
diff --git a/gnu/packages/patches/kmplayer-upstream_Fix-build-with-Qt-5.9.patch b/gnu/packages/patches/kmplayer-upstream_Fix-build-with-Qt-5.9.patch
deleted file mode 100644
index 6a40dbe347..0000000000
--- a/gnu/packages/patches/kmplayer-upstream_Fix-build-with-Qt-5.9.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 3def65075c09af4961cd399e8e78ed78cca72e65 Mon Sep 17 00:00:00 2001
-From: Wolfgang Bauer <wbauer@tmo.at>
-Date: Wed, 11 Oct 2017 22:16:02 +0200
-Subject: [PATCH] Fix build with Qt 5.9
-
-Summary:
-moc 5.9 errors out when building:
-Error: Plugin Metadata file "" could not be opened: file to open is a directory
-
-Same issue and fix as https://phabricator.kde.org/D5392 for khtml.
-
-CCBUG: 377490
-
-Test Plan: builds fine now with Qt 5.9.0rc and also earlier versions.
-
-Reviewers: vriezen, pino
-
-Reviewed By: pino
-
-Subscribers: pino
-
-Differential Revision: https://phabricator.kde.org/D5985
----
- src/kmplayer_part.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/kmplayer_part.h b/src/kmplayer_part.h
-index f90f85d..0fddbaa 100644
---- a/src/kmplayer_part.h
-+++ b/src/kmplayer_part.h
-@@ -36,7 +36,7 @@ namespace KMPlayer {
-
- class KMPlayerFactory : public KPluginFactory {
- Q_OBJECT
-- Q_PLUGIN_METADATA(IID "org.kde.KPluginFactory" FILE "")
-+ Q_PLUGIN_METADATA(IID "org.kde.KPluginFactory")
- Q_INTERFACES(KPluginFactory)
- public:
- KMPlayerFactory();
---
-2.14.2
-
diff --git a/gnu/packages/patches/kpackage-allow-external-paths.patch b/gnu/packages/patches/kpackage-allow-external-paths.patch
deleted file mode 100644
index c1c9efde7f..0000000000
--- a/gnu/packages/patches/kpackage-allow-external-paths.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/src/kpackage/package.cpp b/src/kpackage/package.cpp
-index 5aec9fd..b15c933 100644
---- a/src/kpackage/package.cpp
-+++ b/src/kpackage/package.cpp
-@@ -820,7 +820,7 @@ PackagePrivate::PackagePrivate()
- : QSharedData(),
- fallbackPackage(nullptr),
- metadata(nullptr),
-- externalPaths(false),
-+ externalPaths(true),
- valid(false),
- checkedValid(false)
- {
diff --git a/gnu/packages/patches/kpackage-fix-KF5PackageMacros.cmake.patch b/gnu/packages/patches/kpackage-fix-KF5PackageMacros.cmake.patch
deleted file mode 100644
index d677f19a70..0000000000
--- a/gnu/packages/patches/kpackage-fix-KF5PackageMacros.cmake.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 668010ebc9fd84d9dc60f90b9a4ebf3c7054977f Mon Sep 17 00:00:00 2001
-From: Hartmut Goebel <h.goebel@crazy-compilers.com>
-Date: Sun, 25 Oct 2020 20:11:13 +0000
-Subject: [PATCH] Fix build errors if PREFIX is different from ECM's PREFIX.
-
-See <https://bugs.kde.org/424483> for details.
----
- KF5PackageMacros.cmake | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/KF5PackageMacros.cmake b/KF5PackageMacros.cmake
-index f4c1d1d..acd3798 100644
---- a/KF5PackageMacros.cmake
-+++ b/KF5PackageMacros.cmake
-@@ -1,6 +1,5 @@
-
--find_package(ECM 1.6.0 CONFIG REQUIRED)
--include(${ECM_KDE_MODULE_DIR}/KDEInstallDirs.cmake)
-+include(KDEInstallDirs)
-
- set(KPACKAGE_RELATIVE_DATA_INSTALL_DIR "kpackage")
-
---
-GitLab
-
diff --git a/gnu/packages/patches/libksieve-Fix-missing-link-libraries.patch b/gnu/packages/patches/libksieve-Fix-missing-link-libraries.patch
index 238c4ec46c..3835c2e313 100644
--- a/gnu/packages/patches/libksieve-Fix-missing-link-libraries.patch
+++ b/gnu/packages/patches/libksieve-Fix-missing-link-libraries.patch
@@ -1,59 +1,23 @@
-From 732861dda9c466841a09329a0b2c992f2b78c40a Mon Sep 17 00:00:00 2001
-From: Hartmut Goebel <h.goebel@crazy-compilers.com>
-Date: Tue, 21 Jan 2020 23:15:23 +0100
-Subject: [PATCH] Fix missing link libraries.
-
See <https://phabricator.kde.org/D26818>
-These are only actually missing if the libraries reside in different
-prefixes, as it is the case in Guix or Nix.
----
- src/ksieveui/autocreatescripts/tests/CMakeLists.txt | 2 ++
- src/ksieveui/scriptsparsing/autotests/CMakeLists.txt | 2 +-
- src/ksieveui/scriptsparsing/tests/CMakeLists.txt | 8 ++++++--
- 3 files changed, 9 insertions(+), 3 deletions(-)
-
-diff --git a/src/ksieveui/autocreatescripts/tests/CMakeLists.txt b/src/ksieveui/autocreatescripts/tests/CMakeLists.txt
-index 8a482b4..c43216c 100644
---- a/src/ksieveui/autocreatescripts/tests/CMakeLists.txt
-+++ b/src/ksieveui/autocreatescripts/tests/CMakeLists.txt
-@@ -15,6 +16,7 @@ set(parsingscript_gui_SRCS parsingscript_gui.cpp ../../tests/capability.cpp)
- add_executable(parsingscript_gui ${parsingscript_gui_SRCS})
- target_link_libraries(parsingscript_gui
- KF5::KIOCore
-+ KF5::SyntaxHighlighting
- KF5::KSieveUi
- KF5::KSieve
- KF5::PimCommon
-diff --git a/src/ksieveui/scriptsparsing/autotests/CMakeLists.txt b/src/ksieveui/scriptsparsing/autotests/CMakeLists.txt
-index e41a74e..31703ef 100644
---- a/src/ksieveui/scriptsparsing/autotests/CMakeLists.txt
-+++ b/src/ksieveui/scriptsparsing/autotests/CMakeLists.txt
-@@ -5,7 +5,7 @@ macro(add_sieveeditor_xmlprintingscriptbuilding _source _extrasource)
- ecm_add_test(${_test}
- TEST_NAME ${_name}
- NAME_PREFIX "sieveeditor-xmlprintingscriptbuilding-"
-- LINK_LIBRARIES Qt5::Test KF5::I18n KF5::KSieveUi
-+ LINK_LIBRARIES Qt5::Test KF5::I18n KF5::KSieveUi KF5::SyntaxHighlighting
- )
- endmacro()
- add_sieveeditor_xmlprintingscriptbuilding(xmlprintingscriptbuildertest.cpp "" "")
-diff --git a/src/ksieveui/scriptsparsing/tests/CMakeLists.txt b/src/ksieveui/scriptsparsing/tests/CMakeLists.txt
-index a252039..99a1aaa 100644
---- a/src/ksieveui/scriptsparsing/tests/CMakeLists.txt
-+++ b/src/ksieveui/scriptsparsing/tests/CMakeLists.txt
-@@ -9,5 +9,9 @@ set(xmlsieveparsing_SRCS
- )
-
- add_executable(xmlsieveparsing ${xmlsieveparsing_SRCS} )
--target_link_libraries(xmlsieveparsing KF5::KSieveUi KF5::KSieve KF5::I18n)
--
-+target_link_libraries(xmlsieveparsing
-+ KF5::KSieveUi
-+ KF5::SyntaxHighlighting
-+ KF5::KSieve
-+ KF5::I18n
-+)
---
-2.21.1
+diff --git a/src/ksieveui/CMakeLists.txt b/src/ksieveui/CMakeLists.txt
+--- a/src/ksieveui/CMakeLists.txt
++++ b/src/ksieveui/CMakeLists.txt
+@@ -255,6 +255,7 @@ target_link_libraries(KF5KSieveUi
+ KF5::KManageSieve
+ KF5::KSieve
+ KF5::PimCommon
++ KF5::SyntaxHighlighting
+ PRIVATE
+ KF5::Libkdepim
+ KF5::Archive
+@@ -269,7 +270,6 @@ target_link_libraries(KF5KSieveUi
+ KF5::I18n
+ KF5::SonnetUi
+ Qt::PrintSupport
+- KF5::SyntaxHighlighting
+ )
+ set_target_properties(KF5KSieveUi PROPERTIES
+--
+2.33.0
diff --git a/gnu/packages/patches/mrustc-riscv64-support.patch b/gnu/packages/patches/mrustc-riscv64-support.patch
new file mode 100644
index 0000000000..6312116585
--- /dev/null
+++ b/gnu/packages/patches/mrustc-riscv64-support.patch
@@ -0,0 +1,48 @@
+Patch sent upstream for review:
+https://github.com/thepowersgang/mrustc/pull/276
+
+diff --git a/src/trans/target.cpp b/src/trans/target.cpp
+index 420a2870..4d5eefb3 100644
+--- a/src/trans/target.cpp
++++ b/src/trans/target.cpp
+@@ -65,6 +65,13 @@ const TargetArch ARCH_POWERPC64LE = {
+ { /*atomic(u8)=*/true, true, true, true, true },
+ TargetArch::Alignments(2, 4, 8, 16, 4, 8, 8)
+ };
++// This is a guess
++const TargetArch ARCH_RISCV64 = {
++ "riscv64",
++ 64, false,
++ { /*atomic(u8)=*/true, true, true, true, true },
++ TargetArch::Alignments(2, 4, 8, 16, 4, 8, 8)
++};
+ TargetSpec g_target;
+
+
+@@ -455,6 +462,13 @@ namespace
+ ARCH_POWERPC64LE
+ };
+ }
++ else if(target_name == "riscv64-unknown-linux-gnu")
++ {
++ return TargetSpec {
++ "unix", "linux", "gnu", {CodegenMode::Gnu11, false, "riscv64-unknown-linux-gnu", BACKEND_C_OPTS_GNU},
++ ARCH_RISCV64
++ };
++ }
+ else if(target_name == "i586-pc-windows-gnu")
+ {
+ return TargetSpec {
+diff --git a/tools/common/target_detect.h b/tools/common/target_detect.h
+index a052da6b..42fea91a 100644
+--- a/tools/common/target_detect.h
++++ b/tools/common/target_detect.h
+@@ -34,6 +34,8 @@
+ # define DEFAULT_TARGET_NAME "powerpc64-unknown-linux-gnu"
+ # elif defined(__powerpc64__) && defined(__LITTLE_ENDIAN__)
+ # define DEFAULT_TARGET_NAME "powerpc64le-unknown-linux-gnu"
++# elif defined(__riscv) && __riscv_xlen == 64
++# define DEFAULT_TARGET_NAME "riscv64-unknown-linux-gnu"
+ # else
+ # warning "Unable to detect a suitable default target (linux-gnu)"
+ # endif
diff --git a/gnu/packages/patches/polkit-CVE-2021-4034.patch b/gnu/packages/patches/polkit-CVE-2021-4034.patch
deleted file mode 100644
index ca766cb3be..0000000000
--- a/gnu/packages/patches/polkit-CVE-2021-4034.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-Fixes CVE-2021-4034, local privilege escalation with 'pkexec':
-
- https://www.openwall.com/lists/oss-security/2022/01/25/11
-
-Patch from <https://gitlab.freedesktop.org/polkit/polkit/-/commit/a2bf5c9c83b6ae46cbd5c779d3055bff81ded683>.
-
-From a2bf5c9c83b6ae46cbd5c779d3055bff81ded683 Mon Sep 17 00:00:00 2001
-From: Jan Rybar <jrybar@redhat.com>
-Date: Tue, 25 Jan 2022 17:21:46 +0000
-Subject: [PATCH] pkexec: local privilege escalation (CVE-2021-4034)
-
----
- src/programs/pkcheck.c | 5 +++++
- src/programs/pkexec.c | 23 ++++++++++++++++++++---
- 2 files changed, 25 insertions(+), 3 deletions(-)
-
-diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c
-index f1bb4e1..768525c 100644
---- a/src/programs/pkcheck.c
-+++ b/src/programs/pkcheck.c
-@@ -363,6 +363,11 @@ main (int argc, char *argv[])
- local_agent_handle = NULL;
- ret = 126;
-
-+ if (argc < 1)
-+ {
-+ exit(126);
-+ }
-+
- /* Disable remote file access from GIO. */
- setenv ("GIO_USE_VFS", "local", 1);
-
-diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
-index 7698c5c..84e5ef6 100644
---- a/src/programs/pkexec.c
-+++ b/src/programs/pkexec.c
-@@ -488,6 +488,15 @@ main (int argc, char *argv[])
- pid_t pid_of_caller;
- gpointer local_agent_handle;
-
-+
-+ /*
-+ * If 'pkexec' is called THIS wrong, someone's probably evil-doing. Don't be nice, just bail out.
-+ */
-+ if (argc<1)
-+ {
-+ exit(127);
-+ }
-+
- ret = 127;
- authority = NULL;
- subject = NULL;
-@@ -614,10 +623,10 @@ main (int argc, char *argv[])
-
- path = g_strdup (pwstruct.pw_shell);
- if (!path)
-- {
-+ {
- g_printerr ("No shell configured or error retrieving pw_shell\n");
- goto out;
-- }
-+ }
- /* If you change this, be sure to change the if (!command_line)
- case below too */
- command_line = g_strdup (path);
-@@ -636,7 +645,15 @@ main (int argc, char *argv[])
- goto out;
- }
- g_free (path);
-- argv[n] = path = s;
-+ path = s;
-+
-+ /* argc<2 and pkexec runs just shell, argv is guaranteed to be null-terminated.
-+ * /-less shell shouldn't happen, but let's be defensive and don't write to null-termination
-+ */
-+ if (argv[n] != NULL)
-+ {
-+ argv[n] = path;
-+ }
- }
- if (access (path, F_OK) != 0)
- {
diff --git a/gnu/packages/patches/polkit-configure-elogind.patch b/gnu/packages/patches/polkit-configure-elogind.patch
deleted file mode 100644
index 8fefb7a0c2..0000000000
--- a/gnu/packages/patches/polkit-configure-elogind.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Even when the polkit configure script detects elogind, it does not use
-it. This patch ensures that elogind is used when it is detected.
-
-diff -ruN a/configure b/configure
---- a/configure 1969-12-31 19:00:01.000000000 -0500
-+++ b/configure 2021-11-19 00:04:55.581385020 -0500
-@@ -20390,7 +20390,7 @@
-
-
-
-- if test "$have_libsystemd" = "yes"; then
-+ if test "$have_libsystemd" = "yes" || test "$have_libelogind" = "yes"; then
- HAVE_LIBSYSTEMD_TRUE=
- HAVE_LIBSYSTEMD_FALSE='#'
- else
diff --git a/gnu/packages/patches/polkit-disable-systemd.patch b/gnu/packages/patches/polkit-disable-systemd.patch
new file mode 100644
index 0000000000..551fdf7de8
--- /dev/null
+++ b/gnu/packages/patches/polkit-disable-systemd.patch
@@ -0,0 +1,30 @@
+Don't install systemd units unless using libsystemd session tracking.
+
+Submitted upstream:
+
+ https://gitlab.freedesktop.org/polkit/polkit/-/merge_requests/134
+
+diff --git a/data/meson.build b/data/meson.build
+--- a/data/meson.build
++++ b/data/meson.build
+@@ -26,7 +26,7 @@ if enable_pam
+ )
+ endif
+
+-if enable_logind
++if session_tracking == 'libsystemd-login'
+ configure_file(
+ input: 'polkit.service.in',
+ output: '@BASENAME@',
+diff --git a/meson.build b/meson.build
+--- a/meson.build
++++ b/meson.build
+@@ -199,7 +199,7 @@ if enable_logind
+
+ # systemd unit / service files
+ systemd_systemdsystemunitdir = get_option('systemdsystemunitdir')
+- if systemd_systemdsystemunitdir == ''
++ if systemd_systemdsystemunitdir == '' and session_tracking == 'libsystemd-login'
+ systemd_dep = dependency('systemd', not_found_message: 'systemd required but not found, please provide a valid systemd user unit dir or disable it')
+ # FIXME: systemd.pc file does not use variables with relative paths, so `define_variable` cannot be used
+ systemd_systemdsystemunitdir = systemd_dep.get_pkgconfig_variable('systemdsystemunitdir')
diff --git a/gnu/packages/patches/polkit-use-duktape.patch b/gnu/packages/patches/polkit-use-duktape.patch
deleted file mode 100644
index 4eaa7963c2..0000000000
--- a/gnu/packages/patches/polkit-use-duktape.patch
+++ /dev/null
@@ -1,5030 +0,0 @@
-From 4f66a9549a393e4d74b93eb85301a04ea94bc750 Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Wed, 24 Jul 2019 15:55:17 +0800
-Subject: [PATCH 01/16] Add duktape as javascript engine.
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- configure.ac | 28 +-
- src/polkitbackend/Makefile.am | 14 +-
- .../polkitbackendduktapeauthority.c | 1402 +++++++++++++++++
- 3 files changed, 1436 insertions(+), 8 deletions(-)
- create mode 100644 src/polkitbackend/polkitbackendduktapeauthority.c
-
-diff --git a/configure.ac b/configure.ac
-index e434ca2..5a03593 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -80,11 +80,22 @@ PKG_CHECK_MODULES(GLIB, [gmodule-2.0 gio-unix-2.0 >= 2.30.0])
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-
--PKG_CHECK_MODULES(LIBJS, [mozjs-78])
--
--AC_SUBST(LIBJS_CFLAGS)
--AC_SUBST(LIBJS_CXXFLAGS)
--AC_SUBST(LIBJS_LIBS)
-+dnl ---------------------------------------------------------------------------
-+dnl - Check javascript backend
-+dnl ---------------------------------------------------------------------------
-+AC_ARG_WITH(duktape, AS_HELP_STRING([--with-duktape],[Use Duktape as javascript backend]),with_duktape=yes,with_duktape=no)
-+AS_IF([test x${with_duktape} == xyes], [
-+ PKG_CHECK_MODULES(LIBJS, [duktape >= 2.0.0 ])
-+ AC_SUBST(LIBJS_CFLAGS)
-+ AC_SUBST(LIBJS_LIBS)
-+], [
-+ PKG_CHECK_MODULES(LIBJS, [mozjs-78])
-+
-+ AC_SUBST(LIBJS_CFLAGS)
-+ AC_SUBST(LIBJS_CXXFLAGS)
-+ AC_SUBST(LIBJS_LIBS)
-+])
-+AM_CONDITIONAL(USE_DUKTAPE, [test x$with_duktape == xyes], [Using duktape as javascript engine library])
-
- EXPAT_LIB=""
- AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
-@@ -585,6 +596,13 @@ echo "
- PAM support: ${have_pam}
- systemdsystemunitdir: ${systemdsystemunitdir}
- polkitd user: ${POLKITD_USER}"
-+if test "x${with_duktape}" = xyes; then
-+echo "
-+ Javascript engine: Duktape"
-+else
-+echo "
-+ Javascript engine: Mozjs"
-+fi
-
- if test "$have_pam" = yes ; then
- echo "
-diff --git a/src/polkitbackend/Makefile.am b/src/polkitbackend/Makefile.am
-index 7e3c080..abcbc6f 100644
---- a/src/polkitbackend/Makefile.am
-+++ b/src/polkitbackend/Makefile.am
-@@ -33,7 +33,7 @@ libpolkit_backend_1_la_SOURCES = \
- polkitbackendprivate.h \
- polkitbackendauthority.h polkitbackendauthority.c \
- polkitbackendinteractiveauthority.h polkitbackendinteractiveauthority.c \
-- polkitbackendjsauthority.h polkitbackendjsauthority.cpp \
-+ polkitbackendjsauthority.h \
- polkitbackendactionpool.h polkitbackendactionpool.c \
- polkitbackendactionlookup.h polkitbackendactionlookup.c \
- $(NULL)
-@@ -51,19 +51,27 @@ libpolkit_backend_1_la_CFLAGS = \
- -D_POLKIT_BACKEND_COMPILATION \
- $(GLIB_CFLAGS) \
- $(LIBSYSTEMD_CFLAGS) \
-- $(LIBJS_CFLAGS) \
-+ $(LIBJS_CFLAGS) \
- $(NULL)
-
- libpolkit_backend_1_la_CXXFLAGS = $(libpolkit_backend_1_la_CFLAGS)
-
- libpolkit_backend_1_la_LIBADD = \
- $(GLIB_LIBS) \
-+ $(DUKTAPE_LIBS) \
- $(LIBSYSTEMD_LIBS) \
- $(top_builddir)/src/polkit/libpolkit-gobject-1.la \
- $(EXPAT_LIBS) \
-- $(LIBJS_LIBS) \
-+ $(LIBJS_LIBS) \
- $(NULL)
-
-+if USE_DUKTAPE
-+libpolkit_backend_1_la_SOURCES += polkitbackendduktapeauthority.c
-+libpolkit_backend_1_la_LIBADD += -lm
-+else
-+libpolkit_backend_1_la_SOURCES += polkitbackendjsauthority.cpp
-+endif
-+
- rulesdir = $(sysconfdir)/polkit-1/rules.d
- rules_DATA = 50-default.rules
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-new file mode 100644
-index 0000000..ae98453
---- /dev/null
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -0,0 +1,1402 @@
-+/*
-+ * Copyright (C) 2008-2012 Red Hat, Inc.
-+ * Copyright (C) 2015 Tangent Space <jstpierre@mecheye.net>
-+ * Copyright (C) 2019 Wu Xiaotian <yetist@gmail.com>
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General
-+ * Public License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-+ * Boston, MA 02111-1307, USA.
-+ *
-+ * Author: David Zeuthen <davidz@redhat.com>
-+ */
-+
-+#include "config.h"
-+#include <sys/wait.h>
-+#include <errno.h>
-+#include <pwd.h>
-+#include <grp.h>
-+#include <netdb.h>
-+#include <string.h>
-+#include <glib/gstdio.h>
-+#include <locale.h>
-+#include <glib/gi18n-lib.h>
-+
-+#include <polkit/polkit.h>
-+#include "polkitbackendjsauthority.h"
-+
-+#include <polkit/polkitprivate.h>
-+
-+#ifdef HAVE_LIBSYSTEMD
-+#include <systemd/sd-login.h>
-+#endif /* HAVE_LIBSYSTEMD */
-+
-+#include "initjs.h" /* init.js */
-+#include "duktape.h"
-+
-+/**
-+ * SECTION:polkitbackendjsauthority
-+ * @title: PolkitBackendJsAuthority
-+ * @short_description: JS Authority
-+ * @stability: Unstable
-+ *
-+ * An implementation of #PolkitBackendAuthority that reads and
-+ * evalates Javascript files and supports interaction with
-+ * authentication agents (virtue of being based on
-+ * #PolkitBackendInteractiveAuthority).
-+ */
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+struct _PolkitBackendJsAuthorityPrivate
-+{
-+ gchar **rules_dirs;
-+ GFileMonitor **dir_monitors; /* NULL-terminated array of GFileMonitor instances */
-+ duk_context *cx;
-+};
-+
-+#define WATCHDOG_TIMEOUT (15 * G_TIME_SPAN_SECOND)
-+
-+static void utils_spawn (const gchar *const *argv,
-+ guint timeout_seconds,
-+ GCancellable *cancellable,
-+ GAsyncReadyCallback callback,
-+ gpointer user_data);
-+
-+gboolean utils_spawn_finish (GAsyncResult *res,
-+ gint *out_exit_status,
-+ gchar **out_standard_output,
-+ gchar **out_standard_error,
-+ GError **error);
-+
-+static void on_dir_monitor_changed (GFileMonitor *monitor,
-+ GFile *file,
-+ GFile *other_file,
-+ GFileMonitorEvent event_type,
-+ gpointer user_data);
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+enum
-+{
-+ PROP_0,
-+ PROP_RULES_DIRS,
-+};
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static GList *polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details);
-+
-+static PolkitImplicitAuthorization polkit_backend_js_authority_check_authorization_sync (
-+ PolkitBackendInteractiveAuthority *authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details,
-+ PolkitImplicitAuthorization implicit);
-+
-+G_DEFINE_TYPE (PolkitBackendJsAuthority, polkit_backend_js_authority, POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY);
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static void
-+polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority)
-+{
-+ authority->priv = G_TYPE_INSTANCE_GET_PRIVATE (authority,
-+ POLKIT_BACKEND_TYPE_JS_AUTHORITY,
-+ PolkitBackendJsAuthorityPrivate);
-+}
-+
-+static gint
-+rules_file_name_cmp (const gchar *a,
-+ const gchar *b)
-+{
-+ gint ret;
-+ const gchar *a_base;
-+ const gchar *b_base;
-+
-+ a_base = strrchr (a, '/');
-+ b_base = strrchr (b, '/');
-+
-+ g_assert (a_base != NULL);
-+ g_assert (b_base != NULL);
-+ a_base += 1;
-+ b_base += 1;
-+
-+ ret = g_strcmp0 (a_base, b_base);
-+ if (ret == 0)
-+ {
-+ /* /etc wins over /usr */
-+ ret = g_strcmp0 (a, b);
-+ g_assert (ret != 0);
-+ }
-+
-+ return ret;
-+}
-+
-+static void
-+load_scripts (PolkitBackendJsAuthority *authority)
-+{
-+ duk_context *cx = authority->priv->cx;
-+ GList *files = NULL;
-+ GList *l;
-+ guint num_scripts = 0;
-+ GError *error = NULL;
-+ guint n;
-+
-+ files = NULL;
-+
-+ for (n = 0; authority->priv->rules_dirs != NULL && authority->priv->rules_dirs[n] != NULL; n++)
-+ {
-+ const gchar *dir_name = authority->priv->rules_dirs[n];
-+ GDir *dir = NULL;
-+
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Loading rules from directory %s",
-+ dir_name);
-+
-+ dir = g_dir_open (dir_name,
-+ 0,
-+ &error);
-+ if (dir == NULL)
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error opening rules directory: %s (%s, %d)",
-+ error->message, g_quark_to_string (error->domain), error->code);
-+ g_clear_error (&error);
-+ }
-+ else
-+ {
-+ const gchar *name;
-+ while ((name = g_dir_read_name (dir)) != NULL)
-+ {
-+ if (g_str_has_suffix (name, ".rules"))
-+ files = g_list_prepend (files, g_strdup_printf ("%s/%s", dir_name, name));
-+ }
-+ g_dir_close (dir);
-+ }
-+ }
-+
-+ files = g_list_sort (files, (GCompareFunc) rules_file_name_cmp);
-+
-+ for (l = files; l != NULL; l = l->next)
-+ {
-+ const gchar *filename = l->data;
-+
-+#if (DUK_VERSION >= 20000)
-+ gchar *contents;
-+ gsize length;
-+ GError *error = NULL;
-+ if (!g_file_get_contents (filename, &contents, &length, &error)){
-+ g_warning("Error when file contents of %s: %s\n", filename, error->message);
-+ g_error_free (error);
-+ continue;
-+ }
-+ if (duk_peval_lstring_noresult(cx, contents,length) != 0)
-+#else
-+ if (duk_peval_file_noresult (cx, filename) != 0)
-+#endif
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error compiling script %s: %s",
-+ filename, duk_safe_to_string (authority->priv->cx, -1));
-+#if (DUK_VERSION >= 20000)
-+ g_free (contents);
-+#endif
-+ continue;
-+ }
-+#if (DUK_VERSION >= 20000)
-+ g_free (contents);
-+#endif
-+ num_scripts++;
-+ }
-+
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Finished loading, compiling and executing %d rules",
-+ num_scripts);
-+ g_list_free_full (files, g_free);
-+}
-+
-+static void
-+reload_scripts (PolkitBackendJsAuthority *authority)
-+{
-+ duk_context *cx = authority->priv->cx;
-+
-+ duk_set_top (cx, 0);
-+ duk_get_global_string (cx, "polkit");
-+ duk_push_string (cx, "_deleteRules");
-+
-+ duk_call_prop (cx, 0, 0);
-+
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Collecting garbage unconditionally...");
-+
-+ load_scripts (authority);
-+
-+ /* Let applications know we have new rules... */
-+ g_signal_emit_by_name (authority, "changed");
-+}
-+
-+static void
-+on_dir_monitor_changed (GFileMonitor *monitor,
-+ GFile *file,
-+ GFile *other_file,
-+ GFileMonitorEvent event_type,
-+ gpointer user_data)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data);
-+
-+ /* TODO: maybe rate-limit so storms of events are collapsed into one with a 500ms resolution?
-+ * Because when editing a file with emacs we get 4-8 events..
-+ */
-+
-+ if (file != NULL)
-+ {
-+ gchar *name;
-+
-+ name = g_file_get_basename (file);
-+
-+ /* g_print ("event_type=%d file=%p name=%s\n", event_type, file, name); */
-+ if (!g_str_has_prefix (name, ".") &&
-+ !g_str_has_prefix (name, "#") &&
-+ g_str_has_suffix (name, ".rules") &&
-+ (event_type == G_FILE_MONITOR_EVENT_CREATED ||
-+ event_type == G_FILE_MONITOR_EVENT_DELETED ||
-+ event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Reloading rules");
-+ reload_scripts (authority);
-+ }
-+ g_free (name);
-+ }
-+}
-+
-+
-+static void
-+setup_file_monitors (PolkitBackendJsAuthority *authority)
-+{
-+ guint n;
-+ GPtrArray *p;
-+
-+ p = g_ptr_array_new ();
-+ for (n = 0; authority->priv->rules_dirs != NULL && authority->priv->rules_dirs[n] != NULL; n++)
-+ {
-+ GFile *file;
-+ GError *error;
-+ GFileMonitor *monitor;
-+
-+ file = g_file_new_for_path (authority->priv->rules_dirs[n]);
-+ error = NULL;
-+ monitor = g_file_monitor_directory (file,
-+ G_FILE_MONITOR_NONE,
-+ NULL,
-+ &error);
-+ g_object_unref (file);
-+ if (monitor == NULL)
-+ {
-+ g_warning ("Error monitoring directory %s: %s",
-+ authority->priv->rules_dirs[n],
-+ error->message);
-+ g_clear_error (&error);
-+ }
-+ else
-+ {
-+ g_signal_connect (monitor,
-+ "changed",
-+ G_CALLBACK (on_dir_monitor_changed),
-+ authority);
-+ g_ptr_array_add (p, monitor);
-+ }
-+ }
-+ g_ptr_array_add (p, NULL);
-+ authority->priv->dir_monitors = (GFileMonitor**) g_ptr_array_free (p, FALSE);
-+}
-+
-+static duk_ret_t js_polkit_log (duk_context *cx);
-+static duk_ret_t js_polkit_spawn (duk_context *cx);
-+static duk_ret_t js_polkit_user_is_in_netgroup (duk_context *cx);
-+
-+static const duk_function_list_entry js_polkit_functions[] =
-+{
-+ { "log", js_polkit_log, 1 },
-+ { "spawn", js_polkit_spawn, 1 },
-+ { "_userIsInNetGroup", js_polkit_user_is_in_netgroup, 2 },
-+ { NULL, NULL, 0 },
-+};
-+
-+static void
-+polkit_backend_js_authority_constructed (GObject *object)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
-+ duk_context *cx;
-+
-+ cx = duk_create_heap (NULL, NULL, NULL, authority, NULL);
-+ if (cx == NULL)
-+ goto fail;
-+
-+ authority->priv->cx = cx;
-+
-+ duk_push_global_object (cx);
-+ duk_push_object (cx);
-+ duk_put_function_list (cx, -1, js_polkit_functions);
-+ duk_put_prop_string (cx, -2, "polkit");
-+
-+ duk_eval_string (cx, init_js);
-+
-+ if (authority->priv->rules_dirs == NULL)
-+ {
-+ authority->priv->rules_dirs = g_new0 (gchar *, 3);
-+ authority->priv->rules_dirs[0] = g_strdup (PACKAGE_SYSCONF_DIR "/polkit-1/rules.d");
-+ authority->priv->rules_dirs[1] = g_strdup (PACKAGE_DATA_DIR "/polkit-1/rules.d");
-+ }
-+
-+ setup_file_monitors (authority);
-+ load_scripts (authority);
-+
-+ G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->constructed (object);
-+ return;
-+
-+ fail:
-+ g_critical ("Error initializing JavaScript environment");
-+ g_assert_not_reached ();
-+}
-+
-+static void
-+polkit_backend_js_authority_finalize (GObject *object)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
-+ guint n;
-+
-+ for (n = 0; authority->priv->dir_monitors != NULL && authority->priv->dir_monitors[n] != NULL; n++)
-+ {
-+ GFileMonitor *monitor = authority->priv->dir_monitors[n];
-+ g_signal_handlers_disconnect_by_func (monitor,
-+ G_CALLBACK (on_dir_monitor_changed),
-+ authority);
-+ g_object_unref (monitor);
-+ }
-+ g_free (authority->priv->dir_monitors);
-+ g_strfreev (authority->priv->rules_dirs);
-+
-+ duk_destroy_heap (authority->priv->cx);
-+
-+ G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->finalize (object);
-+}
-+
-+static void
-+polkit_backend_js_authority_set_property (GObject *object,
-+ guint property_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
-+
-+ switch (property_id)
-+ {
-+ case PROP_RULES_DIRS:
-+ g_assert (authority->priv->rules_dirs == NULL);
-+ authority->priv->rules_dirs = (gchar **) g_value_dup_boxed (value);
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-+ break;
-+ }
-+}
-+
-+static const gchar *
-+polkit_backend_js_authority_get_name (PolkitBackendAuthority *authority)
-+{
-+ return "js";
-+}
-+
-+static const gchar *
-+polkit_backend_js_authority_get_version (PolkitBackendAuthority *authority)
-+{
-+ return PACKAGE_VERSION;
-+}
-+
-+static PolkitAuthorityFeatures
-+polkit_backend_js_authority_get_features (PolkitBackendAuthority *authority)
-+{
-+ return POLKIT_AUTHORITY_FEATURES_TEMPORARY_AUTHORIZATION;
-+}
-+
-+static void
-+polkit_backend_js_authority_class_init (PolkitBackendJsAuthorityClass *klass)
-+{
-+ GObjectClass *gobject_class;
-+ PolkitBackendAuthorityClass *authority_class;
-+ PolkitBackendInteractiveAuthorityClass *interactive_authority_class;
-+
-+
-+ gobject_class = G_OBJECT_CLASS (klass);
-+ gobject_class->finalize = polkit_backend_js_authority_finalize;
-+ gobject_class->set_property = polkit_backend_js_authority_set_property;
-+ gobject_class->constructed = polkit_backend_js_authority_constructed;
-+
-+ authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
-+ authority_class->get_name = polkit_backend_js_authority_get_name;
-+ authority_class->get_version = polkit_backend_js_authority_get_version;
-+ authority_class->get_features = polkit_backend_js_authority_get_features;
-+
-+ interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass);
-+ interactive_authority_class->get_admin_identities = polkit_backend_js_authority_get_admin_auth_identities;
-+ interactive_authority_class->check_authorization_sync = polkit_backend_js_authority_check_authorization_sync;
-+
-+ g_object_class_install_property (gobject_class,
-+ PROP_RULES_DIRS,
-+ g_param_spec_boxed ("rules-dirs",
-+ NULL,
-+ NULL,
-+ G_TYPE_STRV,
-+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
-+
-+
-+ g_type_class_add_private (klass, sizeof (PolkitBackendJsAuthorityPrivate));
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static void
-+set_property_str (duk_context *cx,
-+ const gchar *name,
-+ const gchar *value)
-+{
-+ duk_push_string (cx, value);
-+ duk_put_prop_string (cx, -2, name);
-+}
-+
-+static void
-+set_property_strv (duk_context *cx,
-+ const gchar *name,
-+ GPtrArray *value)
-+{
-+ guint n;
-+ duk_push_array (cx);
-+ for (n = 0; n < value->len; n++)
-+ {
-+ duk_push_string (cx, g_ptr_array_index (value, n));
-+ duk_put_prop_index (cx, -2, n);
-+ }
-+ duk_put_prop_string (cx, -2, name);
-+}
-+
-+static void
-+set_property_int32 (duk_context *cx,
-+ const gchar *name,
-+ gint32 value)
-+{
-+ duk_push_int (cx, value);
-+ duk_put_prop_string (cx, -2, name);
-+}
-+
-+static void
-+set_property_bool (duk_context *cx,
-+ const char *name,
-+ gboolean value)
-+{
-+ duk_push_boolean (cx, value);
-+ duk_put_prop_string (cx, -2, name);
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static gboolean
-+push_subject (duk_context *cx,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ GError **error)
-+{
-+ gboolean ret = FALSE;
-+ pid_t pid;
-+ uid_t uid;
-+ gchar *user_name = NULL;
-+ GPtrArray *groups = NULL;
-+ struct passwd *passwd;
-+ char *seat_str = NULL;
-+ char *session_str = NULL;
-+
-+ duk_get_global_string (cx, "Subject");
-+ duk_new (cx, 0);
-+
-+ if (POLKIT_IS_UNIX_PROCESS (subject))
-+ {
-+ pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject));
-+ }
-+ else if (POLKIT_IS_SYSTEM_BUS_NAME (subject))
-+ {
-+ PolkitSubject *process;
-+ process = polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error);
-+ if (process == NULL)
-+ goto out;
-+ pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (process));
-+ g_object_unref (process);
-+ }
-+ else
-+ {
-+ g_assert_not_reached ();
-+ }
-+
-+#ifdef HAVE_LIBSYSTEMD
-+ if (sd_pid_get_session (pid, &session_str) == 0)
-+ {
-+ if (sd_session_get_seat (session_str, &seat_str) == 0)
-+ {
-+ /* do nothing */
-+ }
-+ }
-+#endif /* HAVE_LIBSYSTEMD */
-+
-+ g_assert (POLKIT_IS_UNIX_USER (user_for_subject));
-+ uid = polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_for_subject));
-+
-+ groups = g_ptr_array_new_with_free_func (g_free);
-+
-+ passwd = getpwuid (uid);
-+ if (passwd == NULL)
-+ {
-+ user_name = g_strdup_printf ("%d", (gint) uid);
-+ g_warning ("Error looking up info for uid %d: %m", (gint) uid);
-+ }
-+ else
-+ {
-+ gid_t gids[512];
-+ int num_gids = 512;
-+
-+ user_name = g_strdup (passwd->pw_name);
-+
-+ if (getgrouplist (passwd->pw_name,
-+ passwd->pw_gid,
-+ gids,
-+ &num_gids) < 0)
-+ {
-+ g_warning ("Error looking up groups for uid %d: %m", (gint) uid);
-+ }
-+ else
-+ {
-+ gint n;
-+ for (n = 0; n < num_gids; n++)
-+ {
-+ struct group *group;
-+ group = getgrgid (gids[n]);
-+ if (group == NULL)
-+ {
-+ g_ptr_array_add (groups, g_strdup_printf ("%d", (gint) gids[n]));
-+ }
-+ else
-+ {
-+ g_ptr_array_add (groups, g_strdup (group->gr_name));
-+ }
-+ }
-+ }
-+ }
-+
-+ set_property_int32 (cx, "pid", pid);
-+ set_property_str (cx, "user", user_name);
-+ set_property_strv (cx, "groups", groups);
-+ set_property_str (cx, "seat", seat_str);
-+ set_property_str (cx, "session", session_str);
-+ set_property_bool (cx, "local", subject_is_local);
-+ set_property_bool (cx, "active", subject_is_active);
-+
-+ ret = TRUE;
-+
-+ out:
-+ free (session_str);
-+ free (seat_str);
-+ g_free (user_name);
-+ if (groups != NULL)
-+ g_ptr_array_unref (groups);
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static gboolean
-+push_action_and_details (duk_context *cx,
-+ const gchar *action_id,
-+ PolkitDetails *details,
-+ GError **error)
-+{
-+ gchar **keys;
-+ guint n;
-+
-+ duk_get_global_string (cx, "Action");
-+ duk_new (cx, 0);
-+
-+ set_property_str (cx, "id", action_id);
-+
-+ keys = polkit_details_get_keys (details);
-+ for (n = 0; keys != NULL && keys[n] != NULL; n++)
-+ {
-+ gchar *key;
-+ const gchar *value;
-+ key = g_strdup_printf ("_detail_%s", keys[n]);
-+ value = polkit_details_lookup (details, keys[n]);
-+ set_property_str (cx, key, value);
-+ g_free (key);
-+ }
-+ g_strfreev (keys);
-+
-+ return TRUE;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static GList *
-+polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority);
-+ GList *ret = NULL;
-+ guint n;
-+ GError *error = NULL;
-+ const char *ret_str = NULL;
-+ gchar **ret_strs = NULL;
-+ duk_context *cx = authority->priv->cx;
-+
-+ duk_set_top (cx, 0);
-+ duk_get_global_string (cx, "polkit");
-+ duk_push_string (cx, "_runAdminRules");
-+
-+ if (!push_action_and_details (cx, action_id, details, &error))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error converting action and details to JS object: %s",
-+ error->message);
-+ g_clear_error (&error);
-+ goto out;
-+ }
-+
-+ if (!push_subject (cx, subject, user_for_subject, subject_is_local, subject_is_active, &error))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error converting subject to JS object: %s",
-+ error->message);
-+ g_clear_error (&error);
-+ goto out;
-+ }
-+
-+ if (duk_pcall_prop (cx, 0, 2) != DUK_ERR_NONE)
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error evaluating admin rules: ",
-+ duk_safe_to_string (cx, -1));
-+ goto out;
-+ }
-+
-+ ret_str = duk_require_string (cx, -1);
-+
-+ ret_strs = g_strsplit (ret_str, ",", -1);
-+ for (n = 0; ret_strs != NULL && ret_strs[n] != NULL; n++)
-+ {
-+ const gchar *identity_str = ret_strs[n];
-+ PolkitIdentity *identity;
-+
-+ error = NULL;
-+ identity = polkit_identity_from_string (identity_str, &error);
-+ if (identity == NULL)
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Identity `%s' is not valid, ignoring: %s",
-+ identity_str, error->message);
-+ g_clear_error (&error);
-+ }
-+ else
-+ {
-+ ret = g_list_prepend (ret, identity);
-+ }
-+ }
-+ ret = g_list_reverse (ret);
-+
-+ out:
-+ g_strfreev (ret_strs);
-+ /* fallback to root password auth */
-+ if (ret == NULL)
-+ ret = g_list_prepend (ret, polkit_unix_user_new (0));
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static PolkitImplicitAuthorization
-+polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details,
-+ PolkitImplicitAuthorization implicit)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority);
-+ PolkitImplicitAuthorization ret = implicit;
-+ GError *error = NULL;
-+ gchar *ret_str = NULL;
-+ gboolean good = FALSE;
-+ duk_context *cx = authority->priv->cx;
-+
-+ duk_set_top (cx, 0);
-+ duk_get_global_string (cx, "polkit");
-+ duk_push_string (cx, "_runRules");
-+
-+ if (!push_action_and_details (cx, action_id, details, &error))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error converting action and details to JS object: %s",
-+ error->message);
-+ g_clear_error (&error);
-+ goto out;
-+ }
-+
-+ if (!push_subject (cx, subject, user_for_subject, subject_is_local, subject_is_active, &error))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error converting subject to JS object: %s",
-+ error->message);
-+ g_clear_error (&error);
-+ goto out;
-+ }
-+
-+ if (duk_pcall_prop (cx, 0, 2) != DUK_ERR_NONE)
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error evaluating authorization rules: ",
-+ duk_safe_to_string (cx, -1));
-+ goto out;
-+ }
-+
-+ if (duk_is_null(cx, -1)) {
-+ good = TRUE;
-+ goto out;
-+ }
-+ ret_str = g_strdup (duk_require_string (cx, -1));
-+ if (!polkit_implicit_authorization_from_string (ret_str, &ret))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Returned result `%s' is not valid",
-+ ret_str);
-+ goto out;
-+ }
-+
-+ good = TRUE;
-+
-+ out:
-+ if (!good)
-+ ret = POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED;
-+ g_free (ret_str);
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static duk_ret_t
-+js_polkit_log (duk_context *cx)
-+{
-+ const char *str = duk_require_string (cx, 0);
-+ fprintf (stderr, "%s\n", str);
-+ return 0;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+static const gchar *
-+get_signal_name (gint signal_number)
-+{
-+ switch (signal_number)
-+ {
-+#define _HANDLE_SIG(sig) case sig: return #sig;
-+ _HANDLE_SIG (SIGHUP);
-+ _HANDLE_SIG (SIGINT);
-+ _HANDLE_SIG (SIGQUIT);
-+ _HANDLE_SIG (SIGILL);
-+ _HANDLE_SIG (SIGABRT);
-+ _HANDLE_SIG (SIGFPE);
-+ _HANDLE_SIG (SIGKILL);
-+ _HANDLE_SIG (SIGSEGV);
-+ _HANDLE_SIG (SIGPIPE);
-+ _HANDLE_SIG (SIGALRM);
-+ _HANDLE_SIG (SIGTERM);
-+ _HANDLE_SIG (SIGUSR1);
-+ _HANDLE_SIG (SIGUSR2);
-+ _HANDLE_SIG (SIGCHLD);
-+ _HANDLE_SIG (SIGCONT);
-+ _HANDLE_SIG (SIGSTOP);
-+ _HANDLE_SIG (SIGTSTP);
-+ _HANDLE_SIG (SIGTTIN);
-+ _HANDLE_SIG (SIGTTOU);
-+ _HANDLE_SIG (SIGBUS);
-+#ifdef SIGPOLL
-+ _HANDLE_SIG (SIGPOLL);
-+#endif
-+ _HANDLE_SIG (SIGPROF);
-+ _HANDLE_SIG (SIGSYS);
-+ _HANDLE_SIG (SIGTRAP);
-+ _HANDLE_SIG (SIGURG);
-+ _HANDLE_SIG (SIGVTALRM);
-+ _HANDLE_SIG (SIGXCPU);
-+ _HANDLE_SIG (SIGXFSZ);
-+#undef _HANDLE_SIG
-+ default:
-+ break;
-+ }
-+ return "UNKNOWN_SIGNAL";
-+}
-+
-+typedef struct
-+{
-+ GMainLoop *loop;
-+ GAsyncResult *res;
-+} SpawnData;
-+
-+static void
-+spawn_cb (GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data)
-+{
-+ SpawnData *data = user_data;
-+ data->res = g_object_ref (res);
-+ g_main_loop_quit (data->loop);
-+}
-+
-+static duk_ret_t
-+js_polkit_spawn (duk_context *cx)
-+{
-+#if (DUK_VERSION >= 20000)
-+ duk_ret_t ret = DUK_RET_ERROR;
-+#else
-+ duk_ret_t ret = DUK_RET_INTERNAL_ERROR;
-+#endif
-+ gchar *standard_output = NULL;
-+ gchar *standard_error = NULL;
-+ gint exit_status;
-+ GError *error = NULL;
-+ guint32 array_len;
-+ gchar **argv = NULL;
-+ GMainContext *context = NULL;
-+ GMainLoop *loop = NULL;
-+ SpawnData data = {0};
-+ char *err_str = NULL;
-+ guint n;
-+
-+ if (!duk_is_array (cx, 0))
-+ goto out;
-+
-+ array_len = duk_get_length (cx, 0);
-+
-+ argv = g_new0 (gchar*, array_len + 1);
-+ for (n = 0; n < array_len; n++)
-+ {
-+ duk_get_prop_index (cx, 0, n);
-+ argv[n] = g_strdup (duk_to_string (cx, -1));
-+ duk_pop (cx);
-+ }
-+
-+ context = g_main_context_new ();
-+ loop = g_main_loop_new (context, FALSE);
-+
-+ g_main_context_push_thread_default (context);
-+
-+ data.loop = loop;
-+ utils_spawn ((const gchar *const *) argv,
-+ 10, /* timeout_seconds */
-+ NULL, /* cancellable */
-+ spawn_cb,
-+ &data);
-+
-+ g_main_loop_run (loop);
-+
-+ g_main_context_pop_thread_default (context);
-+
-+ if (!utils_spawn_finish (data.res,
-+ &exit_status,
-+ &standard_output,
-+ &standard_error,
-+ &error))
-+ {
-+ err_str = g_strdup_printf ("Error spawning helper: %s (%s, %d)",
-+ error->message, g_quark_to_string (error->domain), error->code);
-+ g_clear_error (&error);
-+ goto out;
-+ }
-+
-+ if (!(WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0))
-+ {
-+ GString *gstr;
-+ gstr = g_string_new (NULL);
-+ if (WIFEXITED (exit_status))
-+ {
-+ g_string_append_printf (gstr,
-+ "Helper exited with non-zero exit status %d",
-+ WEXITSTATUS (exit_status));
-+ }
-+ else if (WIFSIGNALED (exit_status))
-+ {
-+ g_string_append_printf (gstr,
-+ "Helper was signaled with signal %s (%d)",
-+ get_signal_name (WTERMSIG (exit_status)),
-+ WTERMSIG (exit_status));
-+ }
-+ g_string_append_printf (gstr, ", stdout=`%s', stderr=`%s'",
-+ standard_output, standard_error);
-+ err_str = g_string_free (gstr, FALSE);
-+ goto out;
-+ }
-+
-+ duk_push_string (cx, standard_output);
-+ ret = 1;
-+
-+ out:
-+ g_strfreev (argv);
-+ g_free (standard_output);
-+ g_free (standard_error);
-+ g_clear_object (&data.res);
-+ if (loop != NULL)
-+ g_main_loop_unref (loop);
-+ if (context != NULL)
-+ g_main_context_unref (context);
-+
-+ if (err_str)
-+ duk_error (cx, DUK_ERR_ERROR, err_str);
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+
-+static duk_ret_t
-+js_polkit_user_is_in_netgroup (duk_context *cx)
-+{
-+ const char *user;
-+ const char *netgroup;
-+ gboolean is_in_netgroup = FALSE;
-+
-+ user = duk_require_string (cx, 0);
-+ netgroup = duk_require_string (cx, 1);
-+
-+ if (innetgr (netgroup,
-+ NULL, /* host */
-+ user,
-+ NULL)) /* domain */
-+ {
-+ is_in_netgroup = TRUE;
-+ }
-+
-+ duk_push_boolean (cx, is_in_netgroup);
-+ return 1;
-+}
-+
-+/* ---------------------------------------------------------------------------------------------------- */
-+
-+typedef struct
-+{
-+ GSimpleAsyncResult *simple; /* borrowed reference */
-+ GMainContext *main_context; /* may be NULL */
-+
-+ GCancellable *cancellable; /* may be NULL */
-+ gulong cancellable_handler_id;
-+
-+ GPid child_pid;
-+ gint child_stdout_fd;
-+ gint child_stderr_fd;
-+
-+ GIOChannel *child_stdout_channel;
-+ GIOChannel *child_stderr_channel;
-+
-+ GSource *child_watch_source;
-+ GSource *child_stdout_source;
-+ GSource *child_stderr_source;
-+
-+ guint timeout_seconds;
-+ gboolean timed_out;
-+ GSource *timeout_source;
-+
-+ GString *child_stdout;
-+ GString *child_stderr;
-+
-+ gint exit_status;
-+} UtilsSpawnData;
-+
-+static void
-+utils_child_watch_from_release_cb (GPid pid,
-+ gint status,
-+ gpointer user_data)
-+{
-+}
-+
-+static void
-+utils_spawn_data_free (UtilsSpawnData *data)
-+{
-+ if (data->timeout_source != NULL)
-+ {
-+ g_source_destroy (data->timeout_source);
-+ data->timeout_source = NULL;
-+ }
-+
-+ /* Nuke the child, if necessary */
-+ if (data->child_watch_source != NULL)
-+ {
-+ g_source_destroy (data->child_watch_source);
-+ data->child_watch_source = NULL;
-+ }
-+
-+ if (data->child_pid != 0)
-+ {
-+ GSource *source;
-+ kill (data->child_pid, SIGTERM);
-+ /* OK, we need to reap for the child ourselves - we don't want
-+ * to use waitpid() because that might block the calling
-+ * thread (the child might handle SIGTERM and use several
-+ * seconds for cleanup/rollback).
-+ *
-+ * So we use GChildWatch instead.
-+ *
-+ * Avoid taking a references to ourselves. but note that we need
-+ * to pass the GSource so we can nuke it once handled.
-+ */
-+ source = g_child_watch_source_new (data->child_pid);
-+ g_source_set_callback (source,
-+ (GSourceFunc) utils_child_watch_from_release_cb,
-+ source,
-+ (GDestroyNotify) g_source_destroy);
-+ g_source_attach (source, data->main_context);
-+ g_source_unref (source);
-+ data->child_pid = 0;
-+ }
-+
-+ if (data->child_stdout != NULL)
-+ {
-+ g_string_free (data->child_stdout, TRUE);
-+ data->child_stdout = NULL;
-+ }
-+
-+ if (data->child_stderr != NULL)
-+ {
-+ g_string_free (data->child_stderr, TRUE);
-+ data->child_stderr = NULL;
-+ }
-+
-+ if (data->child_stdout_channel != NULL)
-+ {
-+ g_io_channel_unref (data->child_stdout_channel);
-+ data->child_stdout_channel = NULL;
-+ }
-+ if (data->child_stderr_channel != NULL)
-+ {
-+ g_io_channel_unref (data->child_stderr_channel);
-+ data->child_stderr_channel = NULL;
-+ }
-+
-+ if (data->child_stdout_source != NULL)
-+ {
-+ g_source_destroy (data->child_stdout_source);
-+ data->child_stdout_source = NULL;
-+ }
-+ if (data->child_stderr_source != NULL)
-+ {
-+ g_source_destroy (data->child_stderr_source);
-+ data->child_stderr_source = NULL;
-+ }
-+
-+ if (data->child_stdout_fd != -1)
-+ {
-+ g_warn_if_fail (close (data->child_stdout_fd) == 0);
-+ data->child_stdout_fd = -1;
-+ }
-+ if (data->child_stderr_fd != -1)
-+ {
-+ g_warn_if_fail (close (data->child_stderr_fd) == 0);
-+ data->child_stderr_fd = -1;
-+ }
-+
-+ if (data->cancellable_handler_id > 0)
-+ {
-+ g_cancellable_disconnect (data->cancellable, data->cancellable_handler_id);
-+ data->cancellable_handler_id = 0;
-+ }
-+
-+ if (data->main_context != NULL)
-+ g_main_context_unref (data->main_context);
-+
-+ if (data->cancellable != NULL)
-+ g_object_unref (data->cancellable);
-+
-+ g_slice_free (UtilsSpawnData, data);
-+}
-+
-+/* called in the thread where @cancellable was cancelled */
-+static void
-+utils_on_cancelled (GCancellable *cancellable,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = user_data;
-+ GError *error;
-+
-+ error = NULL;
-+ g_warn_if_fail (g_cancellable_set_error_if_cancelled (cancellable, &error));
-+ g_simple_async_result_take_error (data->simple, error);
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+}
-+
-+static gboolean
-+utils_read_child_stderr (GIOChannel *channel,
-+ GIOCondition condition,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = user_data;
-+ gchar buf[1024];
-+ gsize bytes_read;
-+
-+ g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-+ g_string_append_len (data->child_stderr, buf, bytes_read);
-+ return TRUE;
-+}
-+
-+static gboolean
-+utils_read_child_stdout (GIOChannel *channel,
-+ GIOCondition condition,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = user_data;
-+ gchar buf[1024];
-+ gsize bytes_read;
-+
-+ g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-+ g_string_append_len (data->child_stdout, buf, bytes_read);
-+ return TRUE;
-+}
-+
-+static void
-+utils_child_watch_cb (GPid pid,
-+ gint status,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = user_data;
-+ gchar *buf;
-+ gsize buf_size;
-+
-+ if (g_io_channel_read_to_end (data->child_stdout_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-+ {
-+ g_string_append_len (data->child_stdout, buf, buf_size);
-+ g_free (buf);
-+ }
-+ if (g_io_channel_read_to_end (data->child_stderr_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-+ {
-+ g_string_append_len (data->child_stderr, buf, buf_size);
-+ g_free (buf);
-+ }
-+
-+ data->exit_status = status;
-+
-+ /* ok, child watch is history, make sure we don't free it in spawn_data_free() */
-+ data->child_pid = 0;
-+ data->child_watch_source = NULL;
-+
-+ /* we're done */
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+}
-+
-+static gboolean
-+utils_timeout_cb (gpointer user_data)
-+{
-+ UtilsSpawnData *data = user_data;
-+
-+ data->timed_out = TRUE;
-+
-+ /* ok, timeout is history, make sure we don't free it in spawn_data_free() */
-+ data->timeout_source = NULL;
-+
-+ /* we're done */
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+
-+ return FALSE; /* remove source */
-+}
-+
-+static void
-+utils_spawn (const gchar *const *argv,
-+ guint timeout_seconds,
-+ GCancellable *cancellable,
-+ GAsyncReadyCallback callback,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data;
-+ GError *error;
-+
-+ data = g_slice_new0 (UtilsSpawnData);
-+ data->timeout_seconds = timeout_seconds;
-+ data->simple = g_simple_async_result_new (NULL,
-+ callback,
-+ user_data,
-+ utils_spawn);
-+ data->main_context = g_main_context_get_thread_default ();
-+ if (data->main_context != NULL)
-+ g_main_context_ref (data->main_context);
-+
-+ data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
-+
-+ data->child_stdout = g_string_new (NULL);
-+ data->child_stderr = g_string_new (NULL);
-+ data->child_stdout_fd = -1;
-+ data->child_stderr_fd = -1;
-+
-+ /* the life-cycle of UtilsSpawnData is tied to its GSimpleAsyncResult */
-+ g_simple_async_result_set_op_res_gpointer (data->simple, data, (GDestroyNotify) utils_spawn_data_free);
-+
-+ error = NULL;
-+ if (data->cancellable != NULL)
-+ {
-+ /* could already be cancelled */
-+ error = NULL;
-+ if (g_cancellable_set_error_if_cancelled (data->cancellable, &error))
-+ {
-+ g_simple_async_result_take_error (data->simple, error);
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+ goto out;
-+ }
-+
-+ data->cancellable_handler_id = g_cancellable_connect (data->cancellable,
-+ G_CALLBACK (utils_on_cancelled),
-+ data,
-+ NULL);
-+ }
-+
-+ error = NULL;
-+ if (!g_spawn_async_with_pipes (NULL, /* working directory */
-+ (gchar **) argv,
-+ NULL, /* envp */
-+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-+ NULL, /* child_setup */
-+ NULL, /* child_setup's user_data */
-+ &(data->child_pid),
-+ NULL, /* gint *stdin_fd */
-+ &(data->child_stdout_fd),
-+ &(data->child_stderr_fd),
-+ &error))
-+ {
-+ g_prefix_error (&error, "Error spawning: ");
-+ g_simple_async_result_take_error (data->simple, error);
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+ goto out;
-+ }
-+
-+ if (timeout_seconds > 0)
-+ {
-+ data->timeout_source = g_timeout_source_new_seconds (timeout_seconds);
-+ g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT);
-+ g_source_set_callback (data->timeout_source, utils_timeout_cb, data, NULL);
-+ g_source_attach (data->timeout_source, data->main_context);
-+ g_source_unref (data->timeout_source);
-+ }
-+
-+ data->child_watch_source = g_child_watch_source_new (data->child_pid);
-+ g_source_set_callback (data->child_watch_source, (GSourceFunc) utils_child_watch_cb, data, NULL);
-+ g_source_attach (data->child_watch_source, data->main_context);
-+ g_source_unref (data->child_watch_source);
-+
-+ data->child_stdout_channel = g_io_channel_unix_new (data->child_stdout_fd);
-+ g_io_channel_set_flags (data->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL);
-+ data->child_stdout_source = g_io_create_watch (data->child_stdout_channel, G_IO_IN);
-+ g_source_set_callback (data->child_stdout_source, (GSourceFunc) utils_read_child_stdout, data, NULL);
-+ g_source_attach (data->child_stdout_source, data->main_context);
-+ g_source_unref (data->child_stdout_source);
-+
-+ data->child_stderr_channel = g_io_channel_unix_new (data->child_stderr_fd);
-+ g_io_channel_set_flags (data->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL);
-+ data->child_stderr_source = g_io_create_watch (data->child_stderr_channel, G_IO_IN);
-+ g_source_set_callback (data->child_stderr_source, (GSourceFunc) utils_read_child_stderr, data, NULL);
-+ g_source_attach (data->child_stderr_source, data->main_context);
-+ g_source_unref (data->child_stderr_source);
-+
-+ out:
-+ ;
-+}
-+
-+gboolean
-+utils_spawn_finish (GAsyncResult *res,
-+ gint *out_exit_status,
-+ gchar **out_standard_output,
-+ gchar **out_standard_error,
-+ GError **error)
-+{
-+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-+ UtilsSpawnData *data;
-+ gboolean ret = FALSE;
-+
-+ g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
-+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-+
-+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == utils_spawn);
-+
-+ if (g_simple_async_result_propagate_error (simple, error))
-+ goto out;
-+
-+ data = g_simple_async_result_get_op_res_gpointer (simple);
-+
-+ if (data->timed_out)
-+ {
-+ g_set_error (error,
-+ G_IO_ERROR,
-+ G_IO_ERROR_TIMED_OUT,
-+ "Timed out after %d seconds",
-+ data->timeout_seconds);
-+ goto out;
-+ }
-+
-+ if (out_exit_status != NULL)
-+ *out_exit_status = data->exit_status;
-+
-+ if (out_standard_output != NULL)
-+ *out_standard_output = g_strdup (data->child_stdout->str);
-+
-+ if (out_standard_error != NULL)
-+ *out_standard_error = g_strdup (data->child_stderr->str);
-+
-+ ret = TRUE;
-+
-+ out:
-+ return ret;
-+}
---
-GitLab
-
-
-From d74aad8152a7c51999fffa9abe28e4306a052399 Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 13:15:17 +0800
-Subject: [PATCH 02/16] check netgroup.h header file
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index ae98453..543d6fd 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -26,7 +26,11 @@
- #include <errno.h>
- #include <pwd.h>
- #include <grp.h>
-+#ifdef HAVE_NETGROUP_H
-+#include <netgroup.h>
-+#else
- #include <netdb.h>
-+#endif
- #include <string.h>
- #include <glib/gstdio.h>
- #include <locale.h>
---
-GitLab
-
-
-From 69c761506cbe458807e4ae2742c9e05bc60dad3d Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 10:59:03 +0800
-Subject: [PATCH 03/16] check return value
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 543d6fd..a54ed5b 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -249,7 +249,11 @@ reload_scripts (PolkitBackendJsAuthority *authority)
- duk_context *cx = authority->priv->cx;
-
- duk_set_top (cx, 0);
-- duk_get_global_string (cx, "polkit");
-+ if (!duk_get_global_string (cx, "polkit")) {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error deleting old rules, not loading new ones");
-+ return;
-+ }
- duk_push_string (cx, "_deleteRules");
-
- duk_call_prop (cx, 0, 0);
---
-GitLab
-
-
-From f1536c4899934fd3c8243fda2d084a472fe57d2e Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 11:22:39 +0800
-Subject: [PATCH 04/16] check return value
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 12 ++++++++++--
- 1 file changed, 10 insertions(+), 2 deletions(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index a54ed5b..1a7e6d3 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -656,7 +656,10 @@ push_action_and_details (duk_context *cx,
- gchar **keys;
- guint n;
-
-- duk_get_global_string (cx, "Action");
-+ if (!duk_get_global_string (cx, "Action")) {
-+ return FALSE;
-+ }
-+
- duk_new (cx, 0);
-
- set_property_str (cx, "id", action_id);
-@@ -699,7 +702,12 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA
- duk_context *cx = authority->priv->cx;
-
- duk_set_top (cx, 0);
-- duk_get_global_string (cx, "polkit");
-+ if (!duk_get_global_string (cx, "polkit")) {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error deleting old rules, not loading new ones");
-+ goto out;
-+ }
-+
- duk_push_string (cx, "_runAdminRules");
-
- if (!push_action_and_details (cx, action_id, details, &error))
---
-GitLab
-
-
-From ca15eecf5dc7755947515c1bfc651fd8770aaf8f Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 13:17:16 +0800
-Subject: [PATCH 05/16] check return value
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 1a7e6d3..3f1b32d 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -550,7 +550,10 @@ push_subject (duk_context *cx,
- char *seat_str = NULL;
- char *session_str = NULL;
-
-- duk_get_global_string (cx, "Subject");
-+ if (!duk_get_global_string (cx, "Subject")) {
-+ return FALSE;
-+ }
-+
- duk_new (cx, 0);
-
- if (POLKIT_IS_UNIX_PROCESS (subject))
-@@ -789,8 +792,11 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu
- gboolean good = FALSE;
- duk_context *cx = authority->priv->cx;
-
-+ if (!duk_get_global_string (cx, "polkit")) {
-+ goto out;
-+ }
-+
- duk_set_top (cx, 0);
-- duk_get_global_string (cx, "polkit");
- duk_push_string (cx, "_runRules");
-
- if (!push_action_and_details (cx, action_id, details, &error))
---
-GitLab
-
-
-From 870348365cc0166e14f28e0d144ed552bba4d794 Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 13:18:13 +0800
-Subject: [PATCH 06/16] check return value
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 3f1b32d..6294ad9 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -843,7 +843,8 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu
- out:
- if (!good)
- ret = POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED;
-- g_free (ret_str);
-+ if (ret_str != NULL)
-+ g_free (ret_str);
-
- return ret;
- }
---
-GitLab
-
-
-From 81c916ff08fdcee3c7340c4b2d4632086b89666c Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 11:23:04 +0800
-Subject: [PATCH 07/16] fix typecase
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 6294ad9..d466c9d 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -1191,7 +1191,7 @@ static void
- utils_on_cancelled (GCancellable *cancellable,
- gpointer user_data)
- {
-- UtilsSpawnData *data = user_data;
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
- GError *error;
-
- error = NULL;
-@@ -1206,7 +1206,7 @@ utils_read_child_stderr (GIOChannel *channel,
- GIOCondition condition,
- gpointer user_data)
- {
-- UtilsSpawnData *data = user_data;
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
- gchar buf[1024];
- gsize bytes_read;
-
-@@ -1220,7 +1220,7 @@ utils_read_child_stdout (GIOChannel *channel,
- GIOCondition condition,
- gpointer user_data)
- {
-- UtilsSpawnData *data = user_data;
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
- gchar buf[1024];
- gsize bytes_read;
-
-@@ -1234,7 +1234,7 @@ utils_child_watch_cb (GPid pid,
- gint status,
- gpointer user_data)
- {
-- UtilsSpawnData *data = user_data;
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
- gchar *buf;
- gsize buf_size;
-
-@@ -1263,7 +1263,7 @@ utils_child_watch_cb (GPid pid,
- static gboolean
- utils_timeout_cb (gpointer user_data)
- {
-- UtilsSpawnData *data = user_data;
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-
- data->timed_out = TRUE;
-
---
-GitLab
-
-
-From acb956bf52f0a78bf7aaf925876f96e97a146995 Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 18:04:27 +0800
-Subject: [PATCH 08/16] typecase
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index d466c9d..237b1ad 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -915,8 +915,8 @@ spawn_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
- {
-- SpawnData *data = user_data;
-- data->res = g_object_ref (res);
-+ SpawnData *data = (SpawnData *)user_data;
-+ data->res = (GAsyncResult*)g_object_ref (res);
- g_main_loop_quit (data->loop);
- }
-
-@@ -1292,12 +1292,12 @@ utils_spawn (const gchar *const *argv,
- data->simple = g_simple_async_result_new (NULL,
- callback,
- user_data,
-- utils_spawn);
-+ (gpointer*)utils_spawn);
- data->main_context = g_main_context_get_thread_default ();
- if (data->main_context != NULL)
- g_main_context_ref (data->main_context);
-
-- data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
-+ data->cancellable = cancellable != NULL ? (GCancellable*)g_object_ref (cancellable) : NULL;
-
- data->child_stdout = g_string_new (NULL);
- data->child_stderr = g_string_new (NULL);
-@@ -1397,7 +1397,7 @@ utils_spawn_finish (GAsyncResult *res,
- if (g_simple_async_result_propagate_error (simple, error))
- goto out;
-
-- data = g_simple_async_result_get_op_res_gpointer (simple);
-+ data = (UtilsSpawnData*)g_simple_async_result_get_op_res_gpointer (simple);
-
- if (data->timed_out)
- {
---
-GitLab
-
-
-From be060e4d48aceb09af34868b555b6c73c7afdabb Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 13:53:23 +0800
-Subject: [PATCH 09/16] some change
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- .../polkitbackendduktapeauthority.c | 26 +++++++++++--------
- 1 file changed, 15 insertions(+), 11 deletions(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 237b1ad..fad9017 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -207,18 +207,22 @@ load_scripts (PolkitBackendJsAuthority *authority)
-
- for (l = files; l != NULL; l = l->next)
- {
-- const gchar *filename = l->data;
--
-+ const gchar *filename = (gchar *)l->data;
- #if (DUK_VERSION >= 20000)
-- gchar *contents;
-- gsize length;
-- GError *error = NULL;
-- if (!g_file_get_contents (filename, &contents, &length, &error)){
-- g_warning("Error when file contents of %s: %s\n", filename, error->message);
-- g_error_free (error);
-- continue;
-- }
-- if (duk_peval_lstring_noresult(cx, contents,length) != 0)
-+ GFile *file = g_file_new_for_path (filename);
-+ char *contents;
-+ gsize len;
-+ if (!g_file_load_contents (file, NULL, &contents, &len, NULL, NULL))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Error compiling script %s",
-+ filename);
-+ g_object_unref (file);
-+ continue;
-+ }
-+
-+ g_object_unref (file);
-+ if (duk_peval_lstring_noresult(cx, contents,len) != 0)
- #else
- if (duk_peval_file_noresult (cx, filename) != 0)
- #endif
---
-GitLab
-
-
-From 2ffb62048a5ebedfe3bb053feb7385c7270ede28 Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 15:25:45 +0800
-Subject: [PATCH 10/16] some change
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- .../polkitbackendduktapeauthority.c | 24 +++++++++----------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index fad9017..6fac3be 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -125,6 +125,18 @@ G_DEFINE_TYPE (PolkitBackendJsAuthority, polkit_backend_js_authority, POLKIT_BAC
-
- /* ---------------------------------------------------------------------------------------------------- */
-
-+static duk_ret_t js_polkit_log (duk_context *cx);
-+static duk_ret_t js_polkit_spawn (duk_context *cx);
-+static duk_ret_t js_polkit_user_is_in_netgroup (duk_context *cx);
-+
-+static const duk_function_list_entry js_polkit_functions[] =
-+{
-+ { "log", js_polkit_log, 1 },
-+ { "spawn", js_polkit_spawn, 1 },
-+ { "_userIsInNetGroup", js_polkit_user_is_in_netgroup, 2 },
-+ { NULL, NULL, 0 },
-+};
-+
- static void
- polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority)
- {
-@@ -347,18 +359,6 @@ setup_file_monitors (PolkitBackendJsAuthority *authority)
- authority->priv->dir_monitors = (GFileMonitor**) g_ptr_array_free (p, FALSE);
- }
-
--static duk_ret_t js_polkit_log (duk_context *cx);
--static duk_ret_t js_polkit_spawn (duk_context *cx);
--static duk_ret_t js_polkit_user_is_in_netgroup (duk_context *cx);
--
--static const duk_function_list_entry js_polkit_functions[] =
--{
-- { "log", js_polkit_log, 1 },
-- { "spawn", js_polkit_spawn, 1 },
-- { "_userIsInNetGroup", js_polkit_user_is_in_netgroup, 2 },
-- { NULL, NULL, 0 },
--};
--
- static void
- polkit_backend_js_authority_constructed (GObject *object)
- {
---
-GitLab
-
-
-From edb70ef69eed3275f5654510d135e680eb46c85d Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 15:25:35 +0800
-Subject: [PATCH 11/16] remove WATCHDOG_TIMEOUT define
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 6fac3be..51e03fd 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -69,7 +69,6 @@ struct _PolkitBackendJsAuthorityPrivate
- duk_context *cx;
- };
-
--#define WATCHDOG_TIMEOUT (15 * G_TIME_SPAN_SECOND)
-
- static void utils_spawn (const gchar *const *argv,
- guint timeout_seconds,
---
-GitLab
-
-
-From 906ae404f29f15ef8c529b999bf091b5d18ed7ac Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 12:46:40 +0800
-Subject: [PATCH 12/16] add meson build system support
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- meson.build | 11 ++++++++++-
- meson_options.txt | 1 +
- src/polkitbackend/meson.build | 10 ++++++++--
- 3 files changed, 19 insertions(+), 3 deletions(-)
-
-diff --git a/meson.build b/meson.build
-index 858078d..4e44723 100644
---- a/meson.build
-+++ b/meson.build
-@@ -133,7 +133,13 @@ expat_dep = dependency('expat')
- assert(cc.has_header('expat.h', dependencies: expat_dep), 'Can\'t find expat.h. Please install expat.')
- assert(cc.has_function('XML_ParserCreate', dependencies: expat_dep), 'Can\'t find expat library. Please install expat.')
-
--mozjs_dep = dependency('mozjs-78')
-+js_engine = get_option('js_engine')
-+if js_engine == 'duktape'
-+ js_dep = dependency('duktape')
-+ libm_dep = cc.find_library('m')
-+elif js_engine == 'mozjs'
-+ js_dep = dependency('mozjs-78')
-+endif
-
- dbus_dep = dependency('dbus-1', required: false)
- dbus_policydir = pk_prefix / pk_datadir / 'dbus-1/system.d'
-@@ -361,6 +367,9 @@ if enable_logind
- output += ' systemdsystemunitdir: ' + systemd_systemdsystemunitdir + '\n'
- endif
- output += ' polkitd user: ' + polkitd_user + ' \n'
-+output += ' Javascript engine: ' + js_engine + '\n'
-+if enable_logind
-+endif
- output += ' PAM support: ' + enable_pam.to_string() + '\n\n'
- if enable_pam
- output += ' PAM file auth: ' + pam_conf['PAM_FILE_INCLUDE_AUTH'] + '\n'
-diff --git a/meson_options.txt b/meson_options.txt
-index 25e3e77..76aa311 100644
---- a/meson_options.txt
-+++ b/meson_options.txt
-@@ -16,3 +16,4 @@ option('introspection', type: 'boolean', value: true, description: 'Enable intro
-
- option('gtk_doc', type: 'boolean', value: false, description: 'use gtk-doc to build documentation')
- option('man', type: 'boolean', value: false, description: 'build manual pages')
-+option('js_engine', type: 'combo', choices: ['mozjs', 'duktape'], value: 'duktape', description: 'javascript engine')
-diff --git a/src/polkitbackend/meson.build b/src/polkitbackend/meson.build
-index 64f0e4a..489897d 100644
---- a/src/polkitbackend/meson.build
-+++ b/src/polkitbackend/meson.build
-@@ -5,7 +5,6 @@ sources = files(
- 'polkitbackendactionpool.c',
- 'polkitbackendauthority.c',
- 'polkitbackendinteractiveauthority.c',
-- 'polkitbackendjsauthority.cpp',
- )
-
- output = 'initjs.h'
-@@ -21,7 +20,7 @@ sources += custom_target(
- deps = [
- expat_dep,
- libpolkit_gobject_dep,
-- mozjs_dep,
-+ js_dep,
- ]
-
- c_flags = [
-@@ -31,6 +30,13 @@ c_flags = [
- '-DPACKAGE_SYSCONF_DIR="@0@"'.format(pk_prefix / pk_sysconfdir),
- ]
-
-+if js_engine == 'duktape'
-+ sources += files('polkitbackendduktapeauthority.c')
-+ deps += libm_dep
-+elif js_engine == 'mozjs'
-+ sources += files('polkitbackendjsauthority.cpp')
-+endif
-+
- if enable_logind
- sources += files('polkitbackendsessionmonitor-systemd.c')
-
---
-GitLab
-
-
-From 1380b505c25be4aebe54b1b4223a570d64af83cc Mon Sep 17 00:00:00 2001
-From: Wu Xiaotian <yetist@gmail.com>
-Date: Sun, 22 Nov 2020 18:49:14 +0800
-Subject: [PATCH 13/16] fix run error
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/polkitbackendduktapeauthority.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 51e03fd..4b4f8fd 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -795,11 +795,11 @@ polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAu
- gboolean good = FALSE;
- duk_context *cx = authority->priv->cx;
-
-+ duk_set_top (cx, 0);
- if (!duk_get_global_string (cx, "polkit")) {
- goto out;
- }
-
-- duk_set_top (cx, 0);
- duk_push_string (cx, "_runRules");
-
- if (!push_action_and_details (cx, action_id, details, &error))
---
-GitLab
-
-
-From 6856a704b70378948ef5f66e9b09555d97d4070b Mon Sep 17 00:00:00 2001
-From: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
-Date: Fri, 10 Sep 2021 15:17:58 -0700
-Subject: [PATCH 14/16] Deduplicate code for "Add duktape as JS engine backend"
- effort/MR
-
-This leverages Wu Xiaotian (@yetist)'s original MR
-(https://gitlab.freedesktop.org/polkit/polkit/-/merge_requests/35), in
-an effort to complete said work.
-
-This is the first of the requests from maintainers--to reduce
-eliminate code duplication.
-
-The runaway-killer missing functionality will come in the sequence.
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- src/polkitbackend/Makefile.am | 1 +
- src/polkitbackend/meson.build | 1 +
- src/polkitbackend/polkitbackendcommon.c | 530 +++++++++++++
- src/polkitbackend/polkitbackendcommon.h | 156 ++++
- .../polkitbackendduktapeauthority.c | 714 ++----------------
- .../polkitbackendjsauthority.cpp | 711 ++---------------
- 6 files changed, 790 insertions(+), 1323 deletions(-)
- create mode 100644 src/polkitbackend/polkitbackendcommon.c
- create mode 100644 src/polkitbackend/polkitbackendcommon.h
-
-diff --git a/src/polkitbackend/Makefile.am b/src/polkitbackend/Makefile.am
-index abcbc6f..6a8b4ae 100644
---- a/src/polkitbackend/Makefile.am
-+++ b/src/polkitbackend/Makefile.am
-@@ -31,6 +31,7 @@ libpolkit_backend_1_la_SOURCES = \
- polkitbackend.h \
- polkitbackendtypes.h \
- polkitbackendprivate.h \
-+ polkitbackendcommon.h polkitbackendcommon.c \
- polkitbackendauthority.h polkitbackendauthority.c \
- polkitbackendinteractiveauthority.h polkitbackendinteractiveauthority.c \
- polkitbackendjsauthority.h \
-diff --git a/src/polkitbackend/meson.build b/src/polkitbackend/meson.build
-index 489897d..9ec01b2 100644
---- a/src/polkitbackend/meson.build
-+++ b/src/polkitbackend/meson.build
-@@ -4,6 +4,7 @@ sources = files(
- 'polkitbackendactionlookup.c',
- 'polkitbackendactionpool.c',
- 'polkitbackendauthority.c',
-+ 'polkitbackendcommon.c',
- 'polkitbackendinteractiveauthority.c',
- )
-
-diff --git a/src/polkitbackend/polkitbackendcommon.c b/src/polkitbackend/polkitbackendcommon.c
-new file mode 100644
-index 0000000..6783dff
---- /dev/null
-+++ b/src/polkitbackend/polkitbackendcommon.c
-@@ -0,0 +1,530 @@
-+/*
-+ * Copyright (C) 2008 Red Hat, Inc.
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General
-+ * Public License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-+ * Boston, MA 02111-1307, USA.
-+ *
-+ * Author: David Zeuthen <davidz@redhat.com>
-+ */
-+
-+#include "polkitbackendcommon.h"
-+
-+static void
-+utils_child_watch_from_release_cb (GPid pid,
-+ gint status,
-+ gpointer user_data)
-+{
-+}
-+
-+static void
-+utils_spawn_data_free (UtilsSpawnData *data)
-+{
-+ if (data->timeout_source != NULL)
-+ {
-+ g_source_destroy (data->timeout_source);
-+ data->timeout_source = NULL;
-+ }
-+
-+ /* Nuke the child, if necessary */
-+ if (data->child_watch_source != NULL)
-+ {
-+ g_source_destroy (data->child_watch_source);
-+ data->child_watch_source = NULL;
-+ }
-+
-+ if (data->child_pid != 0)
-+ {
-+ GSource *source;
-+ kill (data->child_pid, SIGTERM);
-+ /* OK, we need to reap for the child ourselves - we don't want
-+ * to use waitpid() because that might block the calling
-+ * thread (the child might handle SIGTERM and use several
-+ * seconds for cleanup/rollback).
-+ *
-+ * So we use GChildWatch instead.
-+ *
-+ * Avoid taking a references to ourselves. but note that we need
-+ * to pass the GSource so we can nuke it once handled.
-+ */
-+ source = g_child_watch_source_new (data->child_pid);
-+ g_source_set_callback (source,
-+ (GSourceFunc) utils_child_watch_from_release_cb,
-+ source,
-+ (GDestroyNotify) g_source_destroy);
-+ g_source_attach (source, data->main_context);
-+ g_source_unref (source);
-+ data->child_pid = 0;
-+ }
-+
-+ if (data->child_stdout != NULL)
-+ {
-+ g_string_free (data->child_stdout, TRUE);
-+ data->child_stdout = NULL;
-+ }
-+
-+ if (data->child_stderr != NULL)
-+ {
-+ g_string_free (data->child_stderr, TRUE);
-+ data->child_stderr = NULL;
-+ }
-+
-+ if (data->child_stdout_channel != NULL)
-+ {
-+ g_io_channel_unref (data->child_stdout_channel);
-+ data->child_stdout_channel = NULL;
-+ }
-+ if (data->child_stderr_channel != NULL)
-+ {
-+ g_io_channel_unref (data->child_stderr_channel);
-+ data->child_stderr_channel = NULL;
-+ }
-+
-+ if (data->child_stdout_source != NULL)
-+ {
-+ g_source_destroy (data->child_stdout_source);
-+ data->child_stdout_source = NULL;
-+ }
-+ if (data->child_stderr_source != NULL)
-+ {
-+ g_source_destroy (data->child_stderr_source);
-+ data->child_stderr_source = NULL;
-+ }
-+
-+ if (data->child_stdout_fd != -1)
-+ {
-+ g_warn_if_fail (close (data->child_stdout_fd) == 0);
-+ data->child_stdout_fd = -1;
-+ }
-+ if (data->child_stderr_fd != -1)
-+ {
-+ g_warn_if_fail (close (data->child_stderr_fd) == 0);
-+ data->child_stderr_fd = -1;
-+ }
-+
-+ if (data->cancellable_handler_id > 0)
-+ {
-+ g_cancellable_disconnect (data->cancellable, data->cancellable_handler_id);
-+ data->cancellable_handler_id = 0;
-+ }
-+
-+ if (data->main_context != NULL)
-+ g_main_context_unref (data->main_context);
-+
-+ if (data->cancellable != NULL)
-+ g_object_unref (data->cancellable);
-+
-+ g_slice_free (UtilsSpawnData, data);
-+}
-+
-+/* called in the thread where @cancellable was cancelled */
-+static void
-+utils_on_cancelled (GCancellable *cancellable,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-+ GError *error;
-+
-+ error = NULL;
-+ g_warn_if_fail (g_cancellable_set_error_if_cancelled (cancellable, &error));
-+ g_simple_async_result_take_error (data->simple, error);
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+}
-+
-+static gboolean
-+utils_timeout_cb (gpointer user_data)
-+{
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-+
-+ data->timed_out = TRUE;
-+
-+ /* ok, timeout is history, make sure we don't free it in spawn_data_free() */
-+ data->timeout_source = NULL;
-+
-+ /* we're done */
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+
-+ return FALSE; /* remove source */
-+}
-+
-+static void
-+utils_child_watch_cb (GPid pid,
-+ gint status,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-+ gchar *buf;
-+ gsize buf_size;
-+
-+ if (g_io_channel_read_to_end (data->child_stdout_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-+ {
-+ g_string_append_len (data->child_stdout, buf, buf_size);
-+ g_free (buf);
-+ }
-+ if (g_io_channel_read_to_end (data->child_stderr_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-+ {
-+ g_string_append_len (data->child_stderr, buf, buf_size);
-+ g_free (buf);
-+ }
-+
-+ data->exit_status = status;
-+
-+ /* ok, child watch is history, make sure we don't free it in spawn_data_free() */
-+ data->child_pid = 0;
-+ data->child_watch_source = NULL;
-+
-+ /* we're done */
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+}
-+
-+static gboolean
-+utils_read_child_stderr (GIOChannel *channel,
-+ GIOCondition condition,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-+ gchar buf[1024];
-+ gsize bytes_read;
-+
-+ g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-+ g_string_append_len (data->child_stderr, buf, bytes_read);
-+ return TRUE;
-+}
-+
-+static gboolean
-+utils_read_child_stdout (GIOChannel *channel,
-+ GIOCondition condition,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-+ gchar buf[1024];
-+ gsize bytes_read;
-+
-+ g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-+ g_string_append_len (data->child_stdout, buf, bytes_read);
-+ return TRUE;
-+}
-+
-+void
-+polkit_backend_common_spawn (const gchar *const *argv,
-+ guint timeout_seconds,
-+ GCancellable *cancellable,
-+ GAsyncReadyCallback callback,
-+ gpointer user_data)
-+{
-+ UtilsSpawnData *data;
-+ GError *error;
-+
-+ data = g_slice_new0 (UtilsSpawnData);
-+ data->timeout_seconds = timeout_seconds;
-+ data->simple = g_simple_async_result_new (NULL,
-+ callback,
-+ user_data,
-+ (gpointer*)polkit_backend_common_spawn);
-+ data->main_context = g_main_context_get_thread_default ();
-+ if (data->main_context != NULL)
-+ g_main_context_ref (data->main_context);
-+
-+ data->cancellable = cancellable != NULL ? (GCancellable*)g_object_ref (cancellable) : NULL;
-+
-+ data->child_stdout = g_string_new (NULL);
-+ data->child_stderr = g_string_new (NULL);
-+ data->child_stdout_fd = -1;
-+ data->child_stderr_fd = -1;
-+
-+ /* the life-cycle of UtilsSpawnData is tied to its GSimpleAsyncResult */
-+ g_simple_async_result_set_op_res_gpointer (data->simple, data, (GDestroyNotify) utils_spawn_data_free);
-+
-+ error = NULL;
-+ if (data->cancellable != NULL)
-+ {
-+ /* could already be cancelled */
-+ error = NULL;
-+ if (g_cancellable_set_error_if_cancelled (data->cancellable, &error))
-+ {
-+ g_simple_async_result_take_error (data->simple, error);
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+ goto out;
-+ }
-+
-+ data->cancellable_handler_id = g_cancellable_connect (data->cancellable,
-+ G_CALLBACK (utils_on_cancelled),
-+ data,
-+ NULL);
-+ }
-+
-+ error = NULL;
-+ if (!g_spawn_async_with_pipes (NULL, /* working directory */
-+ (gchar **) argv,
-+ NULL, /* envp */
-+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-+ NULL, /* child_setup */
-+ NULL, /* child_setup's user_data */
-+ &(data->child_pid),
-+ NULL, /* gint *stdin_fd */
-+ &(data->child_stdout_fd),
-+ &(data->child_stderr_fd),
-+ &error))
-+ {
-+ g_prefix_error (&error, "Error spawning: ");
-+ g_simple_async_result_take_error (data->simple, error);
-+ g_simple_async_result_complete_in_idle (data->simple);
-+ g_object_unref (data->simple);
-+ goto out;
-+ }
-+
-+ if (timeout_seconds > 0)
-+ {
-+ data->timeout_source = g_timeout_source_new_seconds (timeout_seconds);
-+ g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT);
-+ g_source_set_callback (data->timeout_source, utils_timeout_cb, data, NULL);
-+ g_source_attach (data->timeout_source, data->main_context);
-+ g_source_unref (data->timeout_source);
-+ }
-+
-+ data->child_watch_source = g_child_watch_source_new (data->child_pid);
-+ g_source_set_callback (data->child_watch_source, (GSourceFunc) utils_child_watch_cb, data, NULL);
-+ g_source_attach (data->child_watch_source, data->main_context);
-+ g_source_unref (data->child_watch_source);
-+
-+ data->child_stdout_channel = g_io_channel_unix_new (data->child_stdout_fd);
-+ g_io_channel_set_flags (data->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL);
-+ data->child_stdout_source = g_io_create_watch (data->child_stdout_channel, G_IO_IN);
-+ g_source_set_callback (data->child_stdout_source, (GSourceFunc) utils_read_child_stdout, data, NULL);
-+ g_source_attach (data->child_stdout_source, data->main_context);
-+ g_source_unref (data->child_stdout_source);
-+
-+ data->child_stderr_channel = g_io_channel_unix_new (data->child_stderr_fd);
-+ g_io_channel_set_flags (data->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL);
-+ data->child_stderr_source = g_io_create_watch (data->child_stderr_channel, G_IO_IN);
-+ g_source_set_callback (data->child_stderr_source, (GSourceFunc) utils_read_child_stderr, data, NULL);
-+ g_source_attach (data->child_stderr_source, data->main_context);
-+ g_source_unref (data->child_stderr_source);
-+
-+ out:
-+ ;
-+}
-+
-+void
-+polkit_backend_common_on_dir_monitor_changed (GFileMonitor *monitor,
-+ GFile *file,
-+ GFile *other_file,
-+ GFileMonitorEvent event_type,
-+ gpointer user_data)
-+{
-+ PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data);
-+
-+ /* TODO: maybe rate-limit so storms of events are collapsed into one with a 500ms resolution?
-+ * Because when editing a file with emacs we get 4-8 events..
-+ */
-+
-+ if (file != NULL)
-+ {
-+ gchar *name;
-+
-+ name = g_file_get_basename (file);
-+
-+ /* g_print ("event_type=%d file=%p name=%s\n", event_type, file, name); */
-+ if (!g_str_has_prefix (name, ".") &&
-+ !g_str_has_prefix (name, "#") &&
-+ g_str_has_suffix (name, ".rules") &&
-+ (event_type == G_FILE_MONITOR_EVENT_CREATED ||
-+ event_type == G_FILE_MONITOR_EVENT_DELETED ||
-+ event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT))
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "Reloading rules");
-+ polkit_backend_common_reload_scripts (authority);
-+ }
-+ g_free (name);
-+ }
-+}
-+
-+gboolean
-+polkit_backend_common_spawn_finish (GAsyncResult *res,
-+ gint *out_exit_status,
-+ gchar **out_standard_output,
-+ gchar **out_standard_error,
-+ GError **error)
-+{
-+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-+ UtilsSpawnData *data;
-+ gboolean ret = FALSE;
-+
-+ g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
-+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-+
-+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_backend_common_spawn);
-+
-+ if (g_simple_async_result_propagate_error (simple, error))
-+ goto out;
-+
-+ data = (UtilsSpawnData*)g_simple_async_result_get_op_res_gpointer (simple);
-+
-+ if (data->timed_out)
-+ {
-+ g_set_error (error,
-+ G_IO_ERROR,
-+ G_IO_ERROR_TIMED_OUT,
-+ "Timed out after %d seconds",
-+ data->timeout_seconds);
-+ goto out;
-+ }
-+
-+ if (out_exit_status != NULL)
-+ *out_exit_status = data->exit_status;
-+
-+ if (out_standard_output != NULL)
-+ *out_standard_output = g_strdup (data->child_stdout->str);
-+
-+ if (out_standard_error != NULL)
-+ *out_standard_error = g_strdup (data->child_stderr->str);
-+
-+ ret = TRUE;
-+
-+ out:
-+ return ret;
-+}
-+
-+static const gchar *
-+polkit_backend_js_authority_get_name (PolkitBackendAuthority *authority)
-+{
-+ return "js";
-+}
-+
-+static const gchar *
-+polkit_backend_js_authority_get_version (PolkitBackendAuthority *authority)
-+{
-+ return PACKAGE_VERSION;
-+}
-+
-+static PolkitAuthorityFeatures
-+polkit_backend_js_authority_get_features (PolkitBackendAuthority *authority)
-+{
-+ return POLKIT_AUTHORITY_FEATURES_TEMPORARY_AUTHORIZATION;
-+}
-+
-+void
-+polkit_backend_common_js_authority_class_init_common (PolkitBackendJsAuthorityClass *klass)
-+{
-+ GObjectClass *gobject_class;
-+ PolkitBackendAuthorityClass *authority_class;
-+ PolkitBackendInteractiveAuthorityClass *interactive_authority_class;
-+
-+ gobject_class = G_OBJECT_CLASS (klass);
-+ gobject_class->finalize = polkit_backend_common_js_authority_finalize;
-+ gobject_class->set_property = polkit_backend_common_js_authority_set_property;
-+ gobject_class->constructed = polkit_backend_common_js_authority_constructed;
-+
-+ authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
-+ authority_class->get_name = polkit_backend_js_authority_get_name;
-+ authority_class->get_version = polkit_backend_js_authority_get_version;
-+ authority_class->get_features = polkit_backend_js_authority_get_features;
-+
-+ interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass);
-+ interactive_authority_class->get_admin_identities = polkit_backend_common_js_authority_get_admin_auth_identities;
-+ interactive_authority_class->check_authorization_sync = polkit_backend_common_js_authority_check_authorization_sync;
-+
-+ g_object_class_install_property (gobject_class,
-+ PROP_RULES_DIRS,
-+ g_param_spec_boxed ("rules-dirs",
-+ NULL,
-+ NULL,
-+ G_TYPE_STRV,
-+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
-+}
-+
-+gint
-+polkit_backend_common_rules_file_name_cmp (const gchar *a,
-+ const gchar *b)
-+{
-+ gint ret;
-+ const gchar *a_base;
-+ const gchar *b_base;
-+
-+ a_base = strrchr (a, '/');
-+ b_base = strrchr (b, '/');
-+
-+ g_assert (a_base != NULL);
-+ g_assert (b_base != NULL);
-+ a_base += 1;
-+ b_base += 1;
-+
-+ ret = g_strcmp0 (a_base, b_base);
-+ if (ret == 0)
-+ {
-+ /* /etc wins over /usr */
-+ ret = g_strcmp0 (a, b);
-+ g_assert (ret != 0);
-+ }
-+
-+ return ret;
-+}
-+
-+const gchar *
-+polkit_backend_common_get_signal_name (gint signal_number)
-+{
-+ switch (signal_number)
-+ {
-+#define _HANDLE_SIG(sig) case sig: return #sig;
-+ _HANDLE_SIG (SIGHUP);
-+ _HANDLE_SIG (SIGINT);
-+ _HANDLE_SIG (SIGQUIT);
-+ _HANDLE_SIG (SIGILL);
-+ _HANDLE_SIG (SIGABRT);
-+ _HANDLE_SIG (SIGFPE);
-+ _HANDLE_SIG (SIGKILL);
-+ _HANDLE_SIG (SIGSEGV);
-+ _HANDLE_SIG (SIGPIPE);
-+ _HANDLE_SIG (SIGALRM);
-+ _HANDLE_SIG (SIGTERM);
-+ _HANDLE_SIG (SIGUSR1);
-+ _HANDLE_SIG (SIGUSR2);
-+ _HANDLE_SIG (SIGCHLD);
-+ _HANDLE_SIG (SIGCONT);
-+ _HANDLE_SIG (SIGSTOP);
-+ _HANDLE_SIG (SIGTSTP);
-+ _HANDLE_SIG (SIGTTIN);
-+ _HANDLE_SIG (SIGTTOU);
-+ _HANDLE_SIG (SIGBUS);
-+#ifdef SIGPOLL
-+ _HANDLE_SIG (SIGPOLL);
-+#endif
-+ _HANDLE_SIG (SIGPROF);
-+ _HANDLE_SIG (SIGSYS);
-+ _HANDLE_SIG (SIGTRAP);
-+ _HANDLE_SIG (SIGURG);
-+ _HANDLE_SIG (SIGVTALRM);
-+ _HANDLE_SIG (SIGXCPU);
-+ _HANDLE_SIG (SIGXFSZ);
-+#undef _HANDLE_SIG
-+ default:
-+ break;
-+ }
-+ return "UNKNOWN_SIGNAL";
-+}
-+
-+void
-+polkit_backend_common_spawn_cb (GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data)
-+{
-+ SpawnData *data = (SpawnData *)user_data;
-+ data->res = (GAsyncResult*)g_object_ref (res);
-+ g_main_loop_quit (data->loop);
-+}
-diff --git a/src/polkitbackend/polkitbackendcommon.h b/src/polkitbackend/polkitbackendcommon.h
-new file mode 100644
-index 0000000..6d0d267
---- /dev/null
-+++ b/src/polkitbackend/polkitbackendcommon.h
-@@ -0,0 +1,156 @@
-+/*
-+ * Copyright (C) 2008 Red Hat, Inc.
-+ *
-+ * This library is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU Lesser General Public
-+ * License as published by the Free Software Foundation; either
-+ * version 2 of the License, or (at your option) any later version.
-+ *
-+ * This library is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * Lesser General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU Lesser General
-+ * Public License along with this library; if not, write to the
-+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
-+ * Boston, MA 02111-1307, USA.
-+ *
-+ * Author: David Zeuthen <davidz@redhat.com>
-+ */
-+
-+#if !defined (_POLKIT_BACKEND_COMPILATION) && !defined(_POLKIT_BACKEND_INSIDE_POLKIT_BACKEND_H)
-+#error "Only <polkitbackend/polkitbackend.h> can be included directly, this file may disappear or change contents."
-+#endif
-+
-+#ifndef __POLKIT_BACKEND_COMMON_H
-+#define __POLKIT_BACKEND_COMMON_H
-+
-+#include "config.h"
-+#include <sys/wait.h>
-+#include <errno.h>
-+#include <pwd.h>
-+#include <grp.h>
-+#ifdef HAVE_NETGROUP_H
-+#include <netgroup.h>
-+#else
-+#include <netdb.h>
-+#endif
-+#include <string.h>
-+#include <glib/gstdio.h>
-+#include <locale.h>
-+#include <glib/gi18n-lib.h> //here, all things glib via glib.h (including -> gspawn.h)
-+
-+#include <polkit/polkit.h>
-+#include "polkitbackendjsauthority.h"
-+
-+#include <polkit/polkitprivate.h>
-+
-+#ifdef HAVE_LIBSYSTEMD
-+#include <systemd/sd-login.h>
-+#endif /* HAVE_LIBSYSTEMD */
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+enum
-+{
-+ PROP_0,
-+ PROP_RULES_DIRS,
-+};
-+
-+typedef struct
-+{
-+ GSimpleAsyncResult *simple; /* borrowed reference */
-+ GMainContext *main_context; /* may be NULL */
-+
-+ GCancellable *cancellable; /* may be NULL */
-+ gulong cancellable_handler_id;
-+
-+ GPid child_pid;
-+ gint child_stdout_fd;
-+ gint child_stderr_fd;
-+
-+ GIOChannel *child_stdout_channel;
-+ GIOChannel *child_stderr_channel;
-+
-+ GSource *child_watch_source;
-+ GSource *child_stdout_source;
-+ GSource *child_stderr_source;
-+
-+ guint timeout_seconds;
-+ gboolean timed_out;
-+ GSource *timeout_source;
-+
-+ GString *child_stdout;
-+ GString *child_stderr;
-+
-+ gint exit_status;
-+} UtilsSpawnData;
-+
-+typedef struct
-+{
-+ GMainLoop *loop;
-+ GAsyncResult *res;
-+} SpawnData;
-+
-+void polkit_backend_common_spawn (const gchar *const *argv,
-+ guint timeout_seconds,
-+ GCancellable *cancellable,
-+ GAsyncReadyCallback callback,
-+ gpointer user_data);
-+void polkit_backend_common_spawn_cb (GObject *source_object,
-+ GAsyncResult *res,
-+ gpointer user_data);
-+gboolean polkit_backend_common_spawn_finish (GAsyncResult *res,
-+ gint *out_exit_status,
-+ gchar **out_standard_output,
-+ gchar **out_standard_error,
-+ GError **error);
-+
-+void polkit_backend_common_on_dir_monitor_changed (GFileMonitor *monitor,
-+ GFile *file,
-+ GFile *other_file,
-+ GFileMonitorEvent event_type,
-+ gpointer user_data);
-+
-+void polkit_backend_common_js_authority_class_init_common (PolkitBackendJsAuthorityClass *klass);
-+
-+gint polkit_backend_common_rules_file_name_cmp (const gchar *a,
-+ const gchar *b);
-+
-+const gchar *polkit_backend_common_get_signal_name (gint signal_number);
-+
-+/* To be provided by each JS backend, from here onwards ---------------------------------------------- */
-+
-+void polkit_backend_common_reload_scripts (PolkitBackendJsAuthority *authority);
-+void polkit_backend_common_js_authority_finalize (GObject *object);
-+void polkit_backend_common_js_authority_constructed (GObject *object);
-+GList *polkit_backend_common_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details);
-+void polkit_backend_common_js_authority_set_property (GObject *object,
-+ guint property_id,
-+ const GValue *value,
-+ GParamSpec *pspec);
-+PolkitImplicitAuthorization polkit_backend_common_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details,
-+ PolkitImplicitAuthorization implicit);
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __POLKIT_BACKEND_COMMON_H */
-+
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index 4b4f8fd..a2b4420 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -21,32 +21,12 @@
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
--#include "config.h"
--#include <sys/wait.h>
--#include <errno.h>
--#include <pwd.h>
--#include <grp.h>
--#ifdef HAVE_NETGROUP_H
--#include <netgroup.h>
--#else
--#include <netdb.h>
--#endif
--#include <string.h>
--#include <glib/gstdio.h>
--#include <locale.h>
--#include <glib/gi18n-lib.h>
--
--#include <polkit/polkit.h>
--#include "polkitbackendjsauthority.h"
--
--#include <polkit/polkitprivate.h>
-+#include "polkitbackendcommon.h"
-
--#ifdef HAVE_LIBSYSTEMD
--#include <systemd/sd-login.h>
--#endif /* HAVE_LIBSYSTEMD */
-+#include "duktape.h"
-
-+/* Built source and not too big to worry about deduplication */
- #include "initjs.h" /* init.js */
--#include "duktape.h"
-
- /**
- * SECTION:polkitbackendjsauthority
-@@ -54,10 +34,9 @@
- * @short_description: JS Authority
- * @stability: Unstable
- *
-- * An implementation of #PolkitBackendAuthority that reads and
-- * evalates Javascript files and supports interaction with
-- * authentication agents (virtue of being based on
-- * #PolkitBackendInteractiveAuthority).
-+ * An (Duktape-based) implementation of #PolkitBackendAuthority that reads and
-+ * evaluates Javascript files and supports interaction with authentication
-+ * agents (virtue of being based on #PolkitBackendInteractiveAuthority).
- */
-
- /* ---------------------------------------------------------------------------------------------------- */
-@@ -66,64 +45,16 @@ struct _PolkitBackendJsAuthorityPrivate
- {
- gchar **rules_dirs;
- GFileMonitor **dir_monitors; /* NULL-terminated array of GFileMonitor instances */
-- duk_context *cx;
--};
--
--
--static void utils_spawn (const gchar *const *argv,
-- guint timeout_seconds,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--
--gboolean utils_spawn_finish (GAsyncResult *res,
-- gint *out_exit_status,
-- gchar **out_standard_output,
-- gchar **out_standard_error,
-- GError **error);
-
--static void on_dir_monitor_changed (GFileMonitor *monitor,
-- GFile *file,
-- GFile *other_file,
-- GFileMonitorEvent event_type,
-- gpointer user_data);
--
--/* ---------------------------------------------------------------------------------------------------- */
--
--enum
--{
-- PROP_0,
-- PROP_RULES_DIRS,
-+ duk_context *cx;
- };
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static GList *polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details);
--
--static PolkitImplicitAuthorization polkit_backend_js_authority_check_authorization_sync (
-- PolkitBackendInteractiveAuthority *authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details,
-- PolkitImplicitAuthorization implicit);
--
- G_DEFINE_TYPE (PolkitBackendJsAuthority, polkit_backend_js_authority, POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY);
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--/* ---------------------------------------------------------------------------------------------------- */
--
- static duk_ret_t js_polkit_log (duk_context *cx);
- static duk_ret_t js_polkit_spawn (duk_context *cx);
- static duk_ret_t js_polkit_user_is_in_netgroup (duk_context *cx);
-@@ -144,33 +75,6 @@ polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority)
- PolkitBackendJsAuthorityPrivate);
- }
-
--static gint
--rules_file_name_cmp (const gchar *a,
-- const gchar *b)
--{
-- gint ret;
-- const gchar *a_base;
-- const gchar *b_base;
--
-- a_base = strrchr (a, '/');
-- b_base = strrchr (b, '/');
--
-- g_assert (a_base != NULL);
-- g_assert (b_base != NULL);
-- a_base += 1;
-- b_base += 1;
--
-- ret = g_strcmp0 (a_base, b_base);
-- if (ret == 0)
-- {
-- /* /etc wins over /usr */
-- ret = g_strcmp0 (a, b);
-- g_assert (ret != 0);
-- }
--
-- return ret;
--}
--
- static void
- load_scripts (PolkitBackendJsAuthority *authority)
- {
-@@ -214,7 +118,7 @@ load_scripts (PolkitBackendJsAuthority *authority)
- }
- }
-
-- files = g_list_sort (files, (GCompareFunc) rules_file_name_cmp);
-+ files = g_list_sort (files, (GCompareFunc) polkit_backend_common_rules_file_name_cmp);
-
- for (l = files; l != NULL; l = l->next)
- {
-@@ -258,8 +162,8 @@ load_scripts (PolkitBackendJsAuthority *authority)
- g_list_free_full (files, g_free);
- }
-
--static void
--reload_scripts (PolkitBackendJsAuthority *authority)
-+void
-+polkit_backend_common_reload_scripts (PolkitBackendJsAuthority *authority)
- {
- duk_context *cx = authority->priv->cx;
-
-@@ -282,42 +186,6 @@ reload_scripts (PolkitBackendJsAuthority *authority)
- g_signal_emit_by_name (authority, "changed");
- }
-
--static void
--on_dir_monitor_changed (GFileMonitor *monitor,
-- GFile *file,
-- GFile *other_file,
-- GFileMonitorEvent event_type,
-- gpointer user_data)
--{
-- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data);
--
-- /* TODO: maybe rate-limit so storms of events are collapsed into one with a 500ms resolution?
-- * Because when editing a file with emacs we get 4-8 events..
-- */
--
-- if (file != NULL)
-- {
-- gchar *name;
--
-- name = g_file_get_basename (file);
--
-- /* g_print ("event_type=%d file=%p name=%s\n", event_type, file, name); */
-- if (!g_str_has_prefix (name, ".") &&
-- !g_str_has_prefix (name, "#") &&
-- g_str_has_suffix (name, ".rules") &&
-- (event_type == G_FILE_MONITOR_EVENT_CREATED ||
-- event_type == G_FILE_MONITOR_EVENT_DELETED ||
-- event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT))
-- {
-- polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-- "Reloading rules");
-- reload_scripts (authority);
-- }
-- g_free (name);
-- }
--}
--
--
- static void
- setup_file_monitors (PolkitBackendJsAuthority *authority)
- {
-@@ -349,7 +217,7 @@ setup_file_monitors (PolkitBackendJsAuthority *authority)
- {
- g_signal_connect (monitor,
- "changed",
-- G_CALLBACK (on_dir_monitor_changed),
-+ G_CALLBACK (polkit_backend_common_on_dir_monitor_changed),
- authority);
- g_ptr_array_add (p, monitor);
- }
-@@ -358,8 +226,8 @@ setup_file_monitors (PolkitBackendJsAuthority *authority)
- authority->priv->dir_monitors = (GFileMonitor**) g_ptr_array_free (p, FALSE);
- }
-
--static void
--polkit_backend_js_authority_constructed (GObject *object)
-+void
-+polkit_backend_common_js_authority_constructed (GObject *object)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
- duk_context *cx;
-@@ -395,8 +263,8 @@ polkit_backend_js_authority_constructed (GObject *object)
- g_assert_not_reached ();
- }
-
--static void
--polkit_backend_js_authority_finalize (GObject *object)
-+void
-+polkit_backend_common_js_authority_finalize (GObject *object)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
- guint n;
-@@ -405,7 +273,7 @@ polkit_backend_js_authority_finalize (GObject *object)
- {
- GFileMonitor *monitor = authority->priv->dir_monitors[n];
- g_signal_handlers_disconnect_by_func (monitor,
-- G_CALLBACK (on_dir_monitor_changed),
-+ G_CALLBACK (polkit_backend_common_on_dir_monitor_changed),
- authority);
- g_object_unref (monitor);
- }
-@@ -417,11 +285,11 @@ polkit_backend_js_authority_finalize (GObject *object)
- G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->finalize (object);
- }
-
--static void
--polkit_backend_js_authority_set_property (GObject *object,
-- guint property_id,
-- const GValue *value,
-- GParamSpec *pspec)
-+void
-+polkit_backend_common_js_authority_set_property (GObject *object,
-+ guint property_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
-
-@@ -438,55 +306,10 @@ polkit_backend_js_authority_set_property (GObject *object,
- }
- }
-
--static const gchar *
--polkit_backend_js_authority_get_name (PolkitBackendAuthority *authority)
--{
-- return "js";
--}
--
--static const gchar *
--polkit_backend_js_authority_get_version (PolkitBackendAuthority *authority)
--{
-- return PACKAGE_VERSION;
--}
--
--static PolkitAuthorityFeatures
--polkit_backend_js_authority_get_features (PolkitBackendAuthority *authority)
--{
-- return POLKIT_AUTHORITY_FEATURES_TEMPORARY_AUTHORIZATION;
--}
--
- static void
- polkit_backend_js_authority_class_init (PolkitBackendJsAuthorityClass *klass)
- {
-- GObjectClass *gobject_class;
-- PolkitBackendAuthorityClass *authority_class;
-- PolkitBackendInteractiveAuthorityClass *interactive_authority_class;
--
--
-- gobject_class = G_OBJECT_CLASS (klass);
-- gobject_class->finalize = polkit_backend_js_authority_finalize;
-- gobject_class->set_property = polkit_backend_js_authority_set_property;
-- gobject_class->constructed = polkit_backend_js_authority_constructed;
--
-- authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
-- authority_class->get_name = polkit_backend_js_authority_get_name;
-- authority_class->get_version = polkit_backend_js_authority_get_version;
-- authority_class->get_features = polkit_backend_js_authority_get_features;
--
-- interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass);
-- interactive_authority_class->get_admin_identities = polkit_backend_js_authority_get_admin_auth_identities;
-- interactive_authority_class->check_authorization_sync = polkit_backend_js_authority_check_authorization_sync;
--
-- g_object_class_install_property (gobject_class,
-- PROP_RULES_DIRS,
-- g_param_spec_boxed ("rules-dirs",
-- NULL,
-- NULL,
-- G_TYPE_STRV,
-- G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
--
--
-+ polkit_backend_common_js_authority_class_init_common (klass);
- g_type_class_add_private (klass, sizeof (PolkitBackendJsAuthorityPrivate));
- }
-
-@@ -689,15 +512,15 @@ push_action_and_details (duk_context *cx,
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static GList *
--polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details)
-+GList *
-+polkit_backend_common_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority);
- GList *ret = NULL;
-@@ -777,16 +600,16 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static PolkitImplicitAuthorization
--polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details,
-- PolkitImplicitAuthorization implicit)
-+PolkitImplicitAuthorization
-+polkit_backend_common_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details,
-+ PolkitImplicitAuthorization implicit)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority);
- PolkitImplicitAuthorization ret = implicit;
-@@ -864,65 +687,6 @@ js_polkit_log (duk_context *cx)
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static const gchar *
--get_signal_name (gint signal_number)
--{
-- switch (signal_number)
-- {
--#define _HANDLE_SIG(sig) case sig: return #sig;
-- _HANDLE_SIG (SIGHUP);
-- _HANDLE_SIG (SIGINT);
-- _HANDLE_SIG (SIGQUIT);
-- _HANDLE_SIG (SIGILL);
-- _HANDLE_SIG (SIGABRT);
-- _HANDLE_SIG (SIGFPE);
-- _HANDLE_SIG (SIGKILL);
-- _HANDLE_SIG (SIGSEGV);
-- _HANDLE_SIG (SIGPIPE);
-- _HANDLE_SIG (SIGALRM);
-- _HANDLE_SIG (SIGTERM);
-- _HANDLE_SIG (SIGUSR1);
-- _HANDLE_SIG (SIGUSR2);
-- _HANDLE_SIG (SIGCHLD);
-- _HANDLE_SIG (SIGCONT);
-- _HANDLE_SIG (SIGSTOP);
-- _HANDLE_SIG (SIGTSTP);
-- _HANDLE_SIG (SIGTTIN);
-- _HANDLE_SIG (SIGTTOU);
-- _HANDLE_SIG (SIGBUS);
--#ifdef SIGPOLL
-- _HANDLE_SIG (SIGPOLL);
--#endif
-- _HANDLE_SIG (SIGPROF);
-- _HANDLE_SIG (SIGSYS);
-- _HANDLE_SIG (SIGTRAP);
-- _HANDLE_SIG (SIGURG);
-- _HANDLE_SIG (SIGVTALRM);
-- _HANDLE_SIG (SIGXCPU);
-- _HANDLE_SIG (SIGXFSZ);
--#undef _HANDLE_SIG
-- default:
-- break;
-- }
-- return "UNKNOWN_SIGNAL";
--}
--
--typedef struct
--{
-- GMainLoop *loop;
-- GAsyncResult *res;
--} SpawnData;
--
--static void
--spawn_cb (GObject *source_object,
-- GAsyncResult *res,
-- gpointer user_data)
--{
-- SpawnData *data = (SpawnData *)user_data;
-- data->res = (GAsyncResult*)g_object_ref (res);
-- g_main_loop_quit (data->loop);
--}
--
- static duk_ret_t
- js_polkit_spawn (duk_context *cx)
- {
-@@ -962,21 +726,21 @@ js_polkit_spawn (duk_context *cx)
- g_main_context_push_thread_default (context);
-
- data.loop = loop;
-- utils_spawn ((const gchar *const *) argv,
-- 10, /* timeout_seconds */
-- NULL, /* cancellable */
-- spawn_cb,
-- &data);
-+ polkit_backend_common_spawn ((const gchar *const *) argv,
-+ 10, /* timeout_seconds */
-+ NULL, /* cancellable */
-+ polkit_backend_common_spawn_cb,
-+ &data);
-
- g_main_loop_run (loop);
-
- g_main_context_pop_thread_default (context);
-
-- if (!utils_spawn_finish (data.res,
-- &exit_status,
-- &standard_output,
-- &standard_error,
-- &error))
-+ if (!polkit_backend_common_spawn_finish (data.res,
-+ &exit_status,
-+ &standard_output,
-+ &standard_error,
-+ &error))
- {
- err_str = g_strdup_printf ("Error spawning helper: %s (%s, %d)",
- error->message, g_quark_to_string (error->domain), error->code);
-@@ -998,7 +762,7 @@ js_polkit_spawn (duk_context *cx)
- {
- g_string_append_printf (gstr,
- "Helper was signaled with signal %s (%d)",
-- get_signal_name (WTERMSIG (exit_status)),
-+ polkit_backend_common_get_signal_name (WTERMSIG (exit_status)),
- WTERMSIG (exit_status));
- }
- g_string_append_printf (gstr, ", stdout=`%s', stderr=`%s'",
-@@ -1052,377 +816,3 @@ js_polkit_user_is_in_netgroup (duk_context *cx)
- }
-
- /* ---------------------------------------------------------------------------------------------------- */
--
--typedef struct
--{
-- GSimpleAsyncResult *simple; /* borrowed reference */
-- GMainContext *main_context; /* may be NULL */
--
-- GCancellable *cancellable; /* may be NULL */
-- gulong cancellable_handler_id;
--
-- GPid child_pid;
-- gint child_stdout_fd;
-- gint child_stderr_fd;
--
-- GIOChannel *child_stdout_channel;
-- GIOChannel *child_stderr_channel;
--
-- GSource *child_watch_source;
-- GSource *child_stdout_source;
-- GSource *child_stderr_source;
--
-- guint timeout_seconds;
-- gboolean timed_out;
-- GSource *timeout_source;
--
-- GString *child_stdout;
-- GString *child_stderr;
--
-- gint exit_status;
--} UtilsSpawnData;
--
--static void
--utils_child_watch_from_release_cb (GPid pid,
-- gint status,
-- gpointer user_data)
--{
--}
--
--static void
--utils_spawn_data_free (UtilsSpawnData *data)
--{
-- if (data->timeout_source != NULL)
-- {
-- g_source_destroy (data->timeout_source);
-- data->timeout_source = NULL;
-- }
--
-- /* Nuke the child, if necessary */
-- if (data->child_watch_source != NULL)
-- {
-- g_source_destroy (data->child_watch_source);
-- data->child_watch_source = NULL;
-- }
--
-- if (data->child_pid != 0)
-- {
-- GSource *source;
-- kill (data->child_pid, SIGTERM);
-- /* OK, we need to reap for the child ourselves - we don't want
-- * to use waitpid() because that might block the calling
-- * thread (the child might handle SIGTERM and use several
-- * seconds for cleanup/rollback).
-- *
-- * So we use GChildWatch instead.
-- *
-- * Avoid taking a references to ourselves. but note that we need
-- * to pass the GSource so we can nuke it once handled.
-- */
-- source = g_child_watch_source_new (data->child_pid);
-- g_source_set_callback (source,
-- (GSourceFunc) utils_child_watch_from_release_cb,
-- source,
-- (GDestroyNotify) g_source_destroy);
-- g_source_attach (source, data->main_context);
-- g_source_unref (source);
-- data->child_pid = 0;
-- }
--
-- if (data->child_stdout != NULL)
-- {
-- g_string_free (data->child_stdout, TRUE);
-- data->child_stdout = NULL;
-- }
--
-- if (data->child_stderr != NULL)
-- {
-- g_string_free (data->child_stderr, TRUE);
-- data->child_stderr = NULL;
-- }
--
-- if (data->child_stdout_channel != NULL)
-- {
-- g_io_channel_unref (data->child_stdout_channel);
-- data->child_stdout_channel = NULL;
-- }
-- if (data->child_stderr_channel != NULL)
-- {
-- g_io_channel_unref (data->child_stderr_channel);
-- data->child_stderr_channel = NULL;
-- }
--
-- if (data->child_stdout_source != NULL)
-- {
-- g_source_destroy (data->child_stdout_source);
-- data->child_stdout_source = NULL;
-- }
-- if (data->child_stderr_source != NULL)
-- {
-- g_source_destroy (data->child_stderr_source);
-- data->child_stderr_source = NULL;
-- }
--
-- if (data->child_stdout_fd != -1)
-- {
-- g_warn_if_fail (close (data->child_stdout_fd) == 0);
-- data->child_stdout_fd = -1;
-- }
-- if (data->child_stderr_fd != -1)
-- {
-- g_warn_if_fail (close (data->child_stderr_fd) == 0);
-- data->child_stderr_fd = -1;
-- }
--
-- if (data->cancellable_handler_id > 0)
-- {
-- g_cancellable_disconnect (data->cancellable, data->cancellable_handler_id);
-- data->cancellable_handler_id = 0;
-- }
--
-- if (data->main_context != NULL)
-- g_main_context_unref (data->main_context);
--
-- if (data->cancellable != NULL)
-- g_object_unref (data->cancellable);
--
-- g_slice_free (UtilsSpawnData, data);
--}
--
--/* called in the thread where @cancellable was cancelled */
--static void
--utils_on_cancelled (GCancellable *cancellable,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- GError *error;
--
-- error = NULL;
-- g_warn_if_fail (g_cancellable_set_error_if_cancelled (cancellable, &error));
-- g_simple_async_result_take_error (data->simple, error);
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
--}
--
--static gboolean
--utils_read_child_stderr (GIOChannel *channel,
-- GIOCondition condition,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- gchar buf[1024];
-- gsize bytes_read;
--
-- g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-- g_string_append_len (data->child_stderr, buf, bytes_read);
-- return TRUE;
--}
--
--static gboolean
--utils_read_child_stdout (GIOChannel *channel,
-- GIOCondition condition,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- gchar buf[1024];
-- gsize bytes_read;
--
-- g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-- g_string_append_len (data->child_stdout, buf, bytes_read);
-- return TRUE;
--}
--
--static void
--utils_child_watch_cb (GPid pid,
-- gint status,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- gchar *buf;
-- gsize buf_size;
--
-- if (g_io_channel_read_to_end (data->child_stdout_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-- {
-- g_string_append_len (data->child_stdout, buf, buf_size);
-- g_free (buf);
-- }
-- if (g_io_channel_read_to_end (data->child_stderr_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-- {
-- g_string_append_len (data->child_stderr, buf, buf_size);
-- g_free (buf);
-- }
--
-- data->exit_status = status;
--
-- /* ok, child watch is history, make sure we don't free it in spawn_data_free() */
-- data->child_pid = 0;
-- data->child_watch_source = NULL;
--
-- /* we're done */
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
--}
--
--static gboolean
--utils_timeout_cb (gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
--
-- data->timed_out = TRUE;
--
-- /* ok, timeout is history, make sure we don't free it in spawn_data_free() */
-- data->timeout_source = NULL;
--
-- /* we're done */
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
--
-- return FALSE; /* remove source */
--}
--
--static void
--utils_spawn (const gchar *const *argv,
-- guint timeout_seconds,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- UtilsSpawnData *data;
-- GError *error;
--
-- data = g_slice_new0 (UtilsSpawnData);
-- data->timeout_seconds = timeout_seconds;
-- data->simple = g_simple_async_result_new (NULL,
-- callback,
-- user_data,
-- (gpointer*)utils_spawn);
-- data->main_context = g_main_context_get_thread_default ();
-- if (data->main_context != NULL)
-- g_main_context_ref (data->main_context);
--
-- data->cancellable = cancellable != NULL ? (GCancellable*)g_object_ref (cancellable) : NULL;
--
-- data->child_stdout = g_string_new (NULL);
-- data->child_stderr = g_string_new (NULL);
-- data->child_stdout_fd = -1;
-- data->child_stderr_fd = -1;
--
-- /* the life-cycle of UtilsSpawnData is tied to its GSimpleAsyncResult */
-- g_simple_async_result_set_op_res_gpointer (data->simple, data, (GDestroyNotify) utils_spawn_data_free);
--
-- error = NULL;
-- if (data->cancellable != NULL)
-- {
-- /* could already be cancelled */
-- error = NULL;
-- if (g_cancellable_set_error_if_cancelled (data->cancellable, &error))
-- {
-- g_simple_async_result_take_error (data->simple, error);
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
-- goto out;
-- }
--
-- data->cancellable_handler_id = g_cancellable_connect (data->cancellable,
-- G_CALLBACK (utils_on_cancelled),
-- data,
-- NULL);
-- }
--
-- error = NULL;
-- if (!g_spawn_async_with_pipes (NULL, /* working directory */
-- (gchar **) argv,
-- NULL, /* envp */
-- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-- NULL, /* child_setup */
-- NULL, /* child_setup's user_data */
-- &(data->child_pid),
-- NULL, /* gint *stdin_fd */
-- &(data->child_stdout_fd),
-- &(data->child_stderr_fd),
-- &error))
-- {
-- g_prefix_error (&error, "Error spawning: ");
-- g_simple_async_result_take_error (data->simple, error);
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
-- goto out;
-- }
--
-- if (timeout_seconds > 0)
-- {
-- data->timeout_source = g_timeout_source_new_seconds (timeout_seconds);
-- g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT);
-- g_source_set_callback (data->timeout_source, utils_timeout_cb, data, NULL);
-- g_source_attach (data->timeout_source, data->main_context);
-- g_source_unref (data->timeout_source);
-- }
--
-- data->child_watch_source = g_child_watch_source_new (data->child_pid);
-- g_source_set_callback (data->child_watch_source, (GSourceFunc) utils_child_watch_cb, data, NULL);
-- g_source_attach (data->child_watch_source, data->main_context);
-- g_source_unref (data->child_watch_source);
--
-- data->child_stdout_channel = g_io_channel_unix_new (data->child_stdout_fd);
-- g_io_channel_set_flags (data->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL);
-- data->child_stdout_source = g_io_create_watch (data->child_stdout_channel, G_IO_IN);
-- g_source_set_callback (data->child_stdout_source, (GSourceFunc) utils_read_child_stdout, data, NULL);
-- g_source_attach (data->child_stdout_source, data->main_context);
-- g_source_unref (data->child_stdout_source);
--
-- data->child_stderr_channel = g_io_channel_unix_new (data->child_stderr_fd);
-- g_io_channel_set_flags (data->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL);
-- data->child_stderr_source = g_io_create_watch (data->child_stderr_channel, G_IO_IN);
-- g_source_set_callback (data->child_stderr_source, (GSourceFunc) utils_read_child_stderr, data, NULL);
-- g_source_attach (data->child_stderr_source, data->main_context);
-- g_source_unref (data->child_stderr_source);
--
-- out:
-- ;
--}
--
--gboolean
--utils_spawn_finish (GAsyncResult *res,
-- gint *out_exit_status,
-- gchar **out_standard_output,
-- gchar **out_standard_error,
-- GError **error)
--{
-- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-- UtilsSpawnData *data;
-- gboolean ret = FALSE;
--
-- g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
-- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
--
-- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == utils_spawn);
--
-- if (g_simple_async_result_propagate_error (simple, error))
-- goto out;
--
-- data = (UtilsSpawnData*)g_simple_async_result_get_op_res_gpointer (simple);
--
-- if (data->timed_out)
-- {
-- g_set_error (error,
-- G_IO_ERROR,
-- G_IO_ERROR_TIMED_OUT,
-- "Timed out after %d seconds",
-- data->timeout_seconds);
-- goto out;
-- }
--
-- if (out_exit_status != NULL)
-- *out_exit_status = data->exit_status;
--
-- if (out_standard_output != NULL)
-- *out_standard_output = g_strdup (data->child_stdout->str);
--
-- if (out_standard_error != NULL)
-- *out_standard_error = g_strdup (data->child_stderr->str);
--
-- ret = TRUE;
--
-- out:
-- return ret;
--}
-diff --git a/src/polkitbackend/polkitbackendjsauthority.cpp b/src/polkitbackend/polkitbackendjsauthority.cpp
-index ca17108..e28091d 100644
---- a/src/polkitbackend/polkitbackendjsauthority.cpp
-+++ b/src/polkitbackend/polkitbackendjsauthority.cpp
-@@ -19,29 +19,7 @@
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
--#include "config.h"
--#include <sys/wait.h>
--#include <errno.h>
--#include <pwd.h>
--#include <grp.h>
--#ifdef HAVE_NETGROUP_H
--#include <netgroup.h>
--#else
--#include <netdb.h>
--#endif
--#include <string.h>
--#include <glib/gstdio.h>
--#include <locale.h>
--#include <glib/gi18n-lib.h>
--
--#include <polkit/polkit.h>
--#include "polkitbackendjsauthority.h"
--
--#include <polkit/polkitprivate.h>
--
--#ifdef HAVE_LIBSYSTEMD
--#include <systemd/sd-login.h>
--#endif /* HAVE_LIBSYSTEMD */
-+#include "polkitbackendcommon.h"
-
- #include <js/CompilationAndEvaluation.h>
- #include <js/ContextOptions.h>
-@@ -52,6 +30,7 @@
- #include <js/Array.h>
- #include <jsapi.h>
-
-+/* Built source and not too big to worry about deduplication */
- #include "initjs.h" /* init.js */
-
- #ifdef JSGC_USE_EXACT_ROOTING
-@@ -67,10 +46,9 @@
- * @short_description: JS Authority
- * @stability: Unstable
- *
-- * An implementation of #PolkitBackendAuthority that reads and
-- * evalates Javascript files and supports interaction with
-- * authentication agents (virtue of being based on
-- * #PolkitBackendInteractiveAuthority).
-+ * An (SpiderMonkey-based) implementation of #PolkitBackendAuthority that reads
-+ * and evaluates Javascript files and supports interaction with authentication
-+ * agents (virtue of being based on #PolkitBackendInteractiveAuthority).
- */
-
- /* ---------------------------------------------------------------------------------------------------- */
-@@ -100,57 +78,11 @@ static bool execute_script_with_runaway_killer (PolkitBackendJsAuthority *author
- JS::HandleScript script,
- JS::MutableHandleValue rval);
-
--static void utils_spawn (const gchar *const *argv,
-- guint timeout_seconds,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--
--gboolean utils_spawn_finish (GAsyncResult *res,
-- gint *out_exit_status,
-- gchar **out_standard_output,
-- gchar **out_standard_error,
-- GError **error);
--
--static void on_dir_monitor_changed (GFileMonitor *monitor,
-- GFile *file,
-- GFile *other_file,
-- GFileMonitorEvent event_type,
-- gpointer user_data);
--
--/* ---------------------------------------------------------------------------------------------------- */
--
--enum
--{
-- PROP_0,
-- PROP_RULES_DIRS,
--};
--
- /* ---------------------------------------------------------------------------------------------------- */
-
- static gpointer runaway_killer_thread_func (gpointer user_data);
- static void runaway_killer_terminate (PolkitBackendJsAuthority *authority);
-
--static GList *polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details);
--
--static PolkitImplicitAuthorization polkit_backend_js_authority_check_authorization_sync (
-- PolkitBackendInteractiveAuthority *authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details,
-- PolkitImplicitAuthorization implicit);
--
- G_DEFINE_TYPE (PolkitBackendJsAuthority, polkit_backend_js_authority, POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY);
-
- /* ---------------------------------------------------------------------------------------------------- */
-@@ -229,33 +161,6 @@ polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority)
- PolkitBackendJsAuthorityPrivate);
- }
-
--static gint
--rules_file_name_cmp (const gchar *a,
-- const gchar *b)
--{
-- gint ret;
-- const gchar *a_base;
-- const gchar *b_base;
--
-- a_base = strrchr (a, '/');
-- b_base = strrchr (b, '/');
--
-- g_assert (a_base != NULL);
-- g_assert (b_base != NULL);
-- a_base += 1;
-- b_base += 1;
--
-- ret = g_strcmp0 (a_base, b_base);
-- if (ret == 0)
-- {
-- /* /etc wins over /usr */
-- ret = g_strcmp0 (a, b);
-- g_assert (ret != 0);
-- }
--
-- return ret;
--}
--
- /* authority->priv->cx must be within a request */
- static void
- load_scripts (PolkitBackendJsAuthority *authority)
-@@ -299,7 +204,7 @@ load_scripts (PolkitBackendJsAuthority *authority)
- }
- }
-
-- files = g_list_sort (files, (GCompareFunc) rules_file_name_cmp);
-+ files = g_list_sort (files, (GCompareFunc) polkit_backend_common_rules_file_name_cmp);
-
- for (l = files; l != NULL; l = l->next)
- {
-@@ -365,8 +270,8 @@ load_scripts (PolkitBackendJsAuthority *authority)
- g_list_free_full (files, g_free);
- }
-
--static void
--reload_scripts (PolkitBackendJsAuthority *authority)
-+void
-+polkit_backend_common_reload_scripts (PolkitBackendJsAuthority *authority)
- {
- JS::RootedValueArray<1> args(authority->priv->cx);
- JS::RootedValue rval(authority->priv->cx);
-@@ -395,42 +300,6 @@ reload_scripts (PolkitBackendJsAuthority *authority)
- g_signal_emit_by_name (authority, "changed");
- }
-
--static void
--on_dir_monitor_changed (GFileMonitor *monitor,
-- GFile *file,
-- GFile *other_file,
-- GFileMonitorEvent event_type,
-- gpointer user_data)
--{
-- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (user_data);
--
-- /* TODO: maybe rate-limit so storms of events are collapsed into one with a 500ms resolution?
-- * Because when editing a file with emacs we get 4-8 events..
-- */
--
-- if (file != NULL)
-- {
-- gchar *name;
--
-- name = g_file_get_basename (file);
--
-- /* g_print ("event_type=%d file=%p name=%s\n", event_type, file, name); */
-- if (!g_str_has_prefix (name, ".") &&
-- !g_str_has_prefix (name, "#") &&
-- g_str_has_suffix (name, ".rules") &&
-- (event_type == G_FILE_MONITOR_EVENT_CREATED ||
-- event_type == G_FILE_MONITOR_EVENT_DELETED ||
-- event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT))
-- {
-- polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-- "Reloading rules");
-- reload_scripts (authority);
-- }
-- g_free (name);
-- }
--}
--
--
- static void
- setup_file_monitors (PolkitBackendJsAuthority *authority)
- {
-@@ -462,7 +331,7 @@ setup_file_monitors (PolkitBackendJsAuthority *authority)
- {
- g_signal_connect (monitor,
- "changed",
-- G_CALLBACK (on_dir_monitor_changed),
-+ G_CALLBACK (polkit_backend_common_on_dir_monitor_changed),
- authority);
- g_ptr_array_add (p, monitor);
- }
-@@ -471,8 +340,8 @@ setup_file_monitors (PolkitBackendJsAuthority *authority)
- authority->priv->dir_monitors = (GFileMonitor**) g_ptr_array_free (p, FALSE);
- }
-
--static void
--polkit_backend_js_authority_constructed (GObject *object)
-+void
-+polkit_backend_common_js_authority_constructed (GObject *object)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
-
-@@ -561,8 +430,8 @@ polkit_backend_js_authority_constructed (GObject *object)
- g_assert_not_reached ();
- }
-
--static void
--polkit_backend_js_authority_finalize (GObject *object)
-+void
-+polkit_backend_common_js_authority_finalize (GObject *object)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
- guint n;
-@@ -577,7 +446,7 @@ polkit_backend_js_authority_finalize (GObject *object)
- {
- GFileMonitor *monitor = authority->priv->dir_monitors[n];
- g_signal_handlers_disconnect_by_func (monitor,
-- (gpointer*)G_CALLBACK (on_dir_monitor_changed),
-+ (gpointer*)G_CALLBACK (polkit_backend_common_on_dir_monitor_changed),
- authority);
- g_object_unref (monitor);
- }
-@@ -594,11 +463,11 @@ polkit_backend_js_authority_finalize (GObject *object)
- G_OBJECT_CLASS (polkit_backend_js_authority_parent_class)->finalize (object);
- }
-
--static void
--polkit_backend_js_authority_set_property (GObject *object,
-- guint property_id,
-- const GValue *value,
-- GParamSpec *pspec)
-+void
-+polkit_backend_common_js_authority_set_property (GObject *object,
-+ guint property_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
-
-@@ -615,57 +484,12 @@ polkit_backend_js_authority_set_property (GObject *object,
- }
- }
-
--static const gchar *
--polkit_backend_js_authority_get_name (PolkitBackendAuthority *authority)
--{
-- return "js";
--}
--
--static const gchar *
--polkit_backend_js_authority_get_version (PolkitBackendAuthority *authority)
--{
-- return PACKAGE_VERSION;
--}
--
--static PolkitAuthorityFeatures
--polkit_backend_js_authority_get_features (PolkitBackendAuthority *authority)
--{
-- return POLKIT_AUTHORITY_FEATURES_TEMPORARY_AUTHORIZATION;
--}
--
- static void
- polkit_backend_js_authority_class_init (PolkitBackendJsAuthorityClass *klass)
- {
-- GObjectClass *gobject_class;
-- PolkitBackendAuthorityClass *authority_class;
-- PolkitBackendInteractiveAuthorityClass *interactive_authority_class;
--
--
-- gobject_class = G_OBJECT_CLASS (klass);
-- gobject_class->finalize = polkit_backend_js_authority_finalize;
-- gobject_class->set_property = polkit_backend_js_authority_set_property;
-- gobject_class->constructed = polkit_backend_js_authority_constructed;
--
-- authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
-- authority_class->get_name = polkit_backend_js_authority_get_name;
-- authority_class->get_version = polkit_backend_js_authority_get_version;
-- authority_class->get_features = polkit_backend_js_authority_get_features;
--
-- interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass);
-- interactive_authority_class->get_admin_identities = polkit_backend_js_authority_get_admin_auth_identities;
-- interactive_authority_class->check_authorization_sync = polkit_backend_js_authority_check_authorization_sync;
--
-- g_object_class_install_property (gobject_class,
-- PROP_RULES_DIRS,
-- g_param_spec_boxed ("rules-dirs",
-- NULL,
-- NULL,
-- G_TYPE_STRV,
-- GParamFlags(G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE)));
--
-+ polkit_backend_common_js_authority_class_init_common (klass);
-
- g_type_class_add_private (klass, sizeof (PolkitBackendJsAuthorityPrivate));
--
- JS_Init ();
- }
-
-@@ -1099,15 +923,15 @@ call_js_function_with_runaway_killer (PolkitBackendJsAuthority *authority,
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static GList *
--polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details)
-+GList *
-+polkit_backend_common_js_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority);
- GList *ret = NULL;
-@@ -1202,16 +1026,16 @@ polkit_backend_js_authority_get_admin_auth_identities (PolkitBackendInteractiveA
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static PolkitImplicitAuthorization
--polkit_backend_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority,
-- PolkitSubject *caller,
-- PolkitSubject *subject,
-- PolkitIdentity *user_for_subject,
-- gboolean subject_is_local,
-- gboolean subject_is_active,
-- const gchar *action_id,
-- PolkitDetails *details,
-- PolkitImplicitAuthorization implicit)
-+PolkitImplicitAuthorization
-+polkit_backend_common_js_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *_authority,
-+ PolkitSubject *caller,
-+ PolkitSubject *subject,
-+ PolkitIdentity *user_for_subject,
-+ gboolean subject_is_local,
-+ gboolean subject_is_active,
-+ const gchar *action_id,
-+ PolkitDetails *details,
-+ PolkitImplicitAuthorization implicit)
- {
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (_authority);
- PolkitImplicitAuthorization ret = implicit;
-@@ -1324,65 +1148,6 @@ js_polkit_log (JSContext *cx,
-
- /* ---------------------------------------------------------------------------------------------------- */
-
--static const gchar *
--get_signal_name (gint signal_number)
--{
-- switch (signal_number)
-- {
--#define _HANDLE_SIG(sig) case sig: return #sig;
-- _HANDLE_SIG (SIGHUP);
-- _HANDLE_SIG (SIGINT);
-- _HANDLE_SIG (SIGQUIT);
-- _HANDLE_SIG (SIGILL);
-- _HANDLE_SIG (SIGABRT);
-- _HANDLE_SIG (SIGFPE);
-- _HANDLE_SIG (SIGKILL);
-- _HANDLE_SIG (SIGSEGV);
-- _HANDLE_SIG (SIGPIPE);
-- _HANDLE_SIG (SIGALRM);
-- _HANDLE_SIG (SIGTERM);
-- _HANDLE_SIG (SIGUSR1);
-- _HANDLE_SIG (SIGUSR2);
-- _HANDLE_SIG (SIGCHLD);
-- _HANDLE_SIG (SIGCONT);
-- _HANDLE_SIG (SIGSTOP);
-- _HANDLE_SIG (SIGTSTP);
-- _HANDLE_SIG (SIGTTIN);
-- _HANDLE_SIG (SIGTTOU);
-- _HANDLE_SIG (SIGBUS);
--#ifdef SIGPOLL
-- _HANDLE_SIG (SIGPOLL);
--#endif
-- _HANDLE_SIG (SIGPROF);
-- _HANDLE_SIG (SIGSYS);
-- _HANDLE_SIG (SIGTRAP);
-- _HANDLE_SIG (SIGURG);
-- _HANDLE_SIG (SIGVTALRM);
-- _HANDLE_SIG (SIGXCPU);
-- _HANDLE_SIG (SIGXFSZ);
--#undef _HANDLE_SIG
-- default:
-- break;
-- }
-- return "UNKNOWN_SIGNAL";
--}
--
--typedef struct
--{
-- GMainLoop *loop;
-- GAsyncResult *res;
--} SpawnData;
--
--static void
--spawn_cb (GObject *source_object,
-- GAsyncResult *res,
-- gpointer user_data)
--{
-- SpawnData *data = (SpawnData *)user_data;
-- data->res = (GAsyncResult*)g_object_ref (res);
-- g_main_loop_quit (data->loop);
--}
--
- static bool
- js_polkit_spawn (JSContext *cx,
- unsigned js_argc,
-@@ -1440,21 +1205,21 @@ js_polkit_spawn (JSContext *cx,
- g_main_context_push_thread_default (context);
-
- data.loop = loop;
-- utils_spawn ((const gchar *const *) argv,
-- 10, /* timeout_seconds */
-- NULL, /* cancellable */
-- spawn_cb,
-- &data);
-+ polkit_backend_common_spawn ((const gchar *const *) argv,
-+ 10, /* timeout_seconds */
-+ NULL, /* cancellable */
-+ polkit_backend_common_spawn_cb,
-+ &data);
-
- g_main_loop_run (loop);
-
- g_main_context_pop_thread_default (context);
-
-- if (!utils_spawn_finish (data.res,
-- &exit_status,
-- &standard_output,
-- &standard_error,
-- &error))
-+ if (!polkit_backend_common_spawn_finish (data.res,
-+ &exit_status,
-+ &standard_output,
-+ &standard_error,
-+ &error))
- {
- JS_ReportErrorUTF8 (cx,
- "Error spawning helper: %s (%s, %d)",
-@@ -1477,7 +1242,7 @@ js_polkit_spawn (JSContext *cx,
- {
- g_string_append_printf (gstr,
- "Helper was signaled with signal %s (%d)",
-- get_signal_name (WTERMSIG (exit_status)),
-+ polkit_backend_common_get_signal_name (WTERMSIG (exit_status)),
- WTERMSIG (exit_status));
- }
- g_string_append_printf (gstr, ", stdout=`%s', stderr=`%s'",
-@@ -1542,381 +1307,5 @@ js_polkit_user_is_in_netgroup (JSContext *cx,
- return ret;
- }
-
--
--
- /* ---------------------------------------------------------------------------------------------------- */
-
--typedef struct
--{
-- GSimpleAsyncResult *simple; /* borrowed reference */
-- GMainContext *main_context; /* may be NULL */
--
-- GCancellable *cancellable; /* may be NULL */
-- gulong cancellable_handler_id;
--
-- GPid child_pid;
-- gint child_stdout_fd;
-- gint child_stderr_fd;
--
-- GIOChannel *child_stdout_channel;
-- GIOChannel *child_stderr_channel;
--
-- GSource *child_watch_source;
-- GSource *child_stdout_source;
-- GSource *child_stderr_source;
--
-- guint timeout_seconds;
-- gboolean timed_out;
-- GSource *timeout_source;
--
-- GString *child_stdout;
-- GString *child_stderr;
--
-- gint exit_status;
--} UtilsSpawnData;
--
--static void
--utils_child_watch_from_release_cb (GPid pid,
-- gint status,
-- gpointer user_data)
--{
--}
--
--static void
--utils_spawn_data_free (UtilsSpawnData *data)
--{
-- if (data->timeout_source != NULL)
-- {
-- g_source_destroy (data->timeout_source);
-- data->timeout_source = NULL;
-- }
--
-- /* Nuke the child, if necessary */
-- if (data->child_watch_source != NULL)
-- {
-- g_source_destroy (data->child_watch_source);
-- data->child_watch_source = NULL;
-- }
--
-- if (data->child_pid != 0)
-- {
-- GSource *source;
-- kill (data->child_pid, SIGTERM);
-- /* OK, we need to reap for the child ourselves - we don't want
-- * to use waitpid() because that might block the calling
-- * thread (the child might handle SIGTERM and use several
-- * seconds for cleanup/rollback).
-- *
-- * So we use GChildWatch instead.
-- *
-- * Avoid taking a references to ourselves. but note that we need
-- * to pass the GSource so we can nuke it once handled.
-- */
-- source = g_child_watch_source_new (data->child_pid);
-- g_source_set_callback (source,
-- (GSourceFunc) utils_child_watch_from_release_cb,
-- source,
-- (GDestroyNotify) g_source_destroy);
-- /* attach source to the global default main context */
-- g_source_attach (source, NULL);
-- g_source_unref (source);
-- data->child_pid = 0;
-- }
--
-- if (data->child_stdout != NULL)
-- {
-- g_string_free (data->child_stdout, TRUE);
-- data->child_stdout = NULL;
-- }
--
-- if (data->child_stderr != NULL)
-- {
-- g_string_free (data->child_stderr, TRUE);
-- data->child_stderr = NULL;
-- }
--
-- if (data->child_stdout_channel != NULL)
-- {
-- g_io_channel_unref (data->child_stdout_channel);
-- data->child_stdout_channel = NULL;
-- }
-- if (data->child_stderr_channel != NULL)
-- {
-- g_io_channel_unref (data->child_stderr_channel);
-- data->child_stderr_channel = NULL;
-- }
--
-- if (data->child_stdout_source != NULL)
-- {
-- g_source_destroy (data->child_stdout_source);
-- data->child_stdout_source = NULL;
-- }
-- if (data->child_stderr_source != NULL)
-- {
-- g_source_destroy (data->child_stderr_source);
-- data->child_stderr_source = NULL;
-- }
--
-- if (data->child_stdout_fd != -1)
-- {
-- g_warn_if_fail (close (data->child_stdout_fd) == 0);
-- data->child_stdout_fd = -1;
-- }
-- if (data->child_stderr_fd != -1)
-- {
-- g_warn_if_fail (close (data->child_stderr_fd) == 0);
-- data->child_stderr_fd = -1;
-- }
--
-- if (data->cancellable_handler_id > 0)
-- {
-- g_cancellable_disconnect (data->cancellable, data->cancellable_handler_id);
-- data->cancellable_handler_id = 0;
-- }
--
-- if (data->main_context != NULL)
-- g_main_context_unref (data->main_context);
--
-- if (data->cancellable != NULL)
-- g_object_unref (data->cancellable);
--
-- g_slice_free (UtilsSpawnData, data);
--}
--
--/* called in the thread where @cancellable was cancelled */
--static void
--utils_on_cancelled (GCancellable *cancellable,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- GError *error;
--
-- error = NULL;
-- g_warn_if_fail (g_cancellable_set_error_if_cancelled (cancellable, &error));
-- g_simple_async_result_take_error (data->simple, error);
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
--}
--
--static gboolean
--utils_read_child_stderr (GIOChannel *channel,
-- GIOCondition condition,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- gchar buf[1024];
-- gsize bytes_read;
--
-- g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-- g_string_append_len (data->child_stderr, buf, bytes_read);
-- return TRUE;
--}
--
--static gboolean
--utils_read_child_stdout (GIOChannel *channel,
-- GIOCondition condition,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- gchar buf[1024];
-- gsize bytes_read;
--
-- g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL);
-- g_string_append_len (data->child_stdout, buf, bytes_read);
-- return TRUE;
--}
--
--static void
--utils_child_watch_cb (GPid pid,
-- gint status,
-- gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
-- gchar *buf;
-- gsize buf_size;
--
-- if (g_io_channel_read_to_end (data->child_stdout_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-- {
-- g_string_append_len (data->child_stdout, buf, buf_size);
-- g_free (buf);
-- }
-- if (g_io_channel_read_to_end (data->child_stderr_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL)
-- {
-- g_string_append_len (data->child_stderr, buf, buf_size);
-- g_free (buf);
-- }
--
-- data->exit_status = status;
--
-- /* ok, child watch is history, make sure we don't free it in spawn_data_free() */
-- data->child_pid = 0;
-- data->child_watch_source = NULL;
--
-- /* we're done */
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
--}
--
--static gboolean
--utils_timeout_cb (gpointer user_data)
--{
-- UtilsSpawnData *data = (UtilsSpawnData *)user_data;
--
-- data->timed_out = TRUE;
--
-- /* ok, timeout is history, make sure we don't free it in spawn_data_free() */
-- data->timeout_source = NULL;
--
-- /* we're done */
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
--
-- return FALSE; /* remove source */
--}
--
--static void
--utils_spawn (const gchar *const *argv,
-- guint timeout_seconds,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- UtilsSpawnData *data;
-- GError *error;
--
-- data = g_slice_new0 (UtilsSpawnData);
-- data->timeout_seconds = timeout_seconds;
-- data->simple = g_simple_async_result_new (NULL,
-- callback,
-- user_data,
-- (gpointer*)utils_spawn);
-- data->main_context = g_main_context_get_thread_default ();
-- if (data->main_context != NULL)
-- g_main_context_ref (data->main_context);
--
-- data->cancellable = cancellable != NULL ? (GCancellable*)g_object_ref (cancellable) : NULL;
--
-- data->child_stdout = g_string_new (NULL);
-- data->child_stderr = g_string_new (NULL);
-- data->child_stdout_fd = -1;
-- data->child_stderr_fd = -1;
--
-- /* the life-cycle of UtilsSpawnData is tied to its GSimpleAsyncResult */
-- g_simple_async_result_set_op_res_gpointer (data->simple, data, (GDestroyNotify) utils_spawn_data_free);
--
-- error = NULL;
-- if (data->cancellable != NULL)
-- {
-- /* could already be cancelled */
-- error = NULL;
-- if (g_cancellable_set_error_if_cancelled (data->cancellable, &error))
-- {
-- g_simple_async_result_take_error (data->simple, error);
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
-- goto out;
-- }
--
-- data->cancellable_handler_id = g_cancellable_connect (data->cancellable,
-- G_CALLBACK (utils_on_cancelled),
-- data,
-- NULL);
-- }
--
-- error = NULL;
-- if (!g_spawn_async_with_pipes (NULL, /* working directory */
-- (gchar **) argv,
-- NULL, /* envp */
-- GSpawnFlags(G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD),
-- NULL, /* child_setup */
-- NULL, /* child_setup's user_data */
-- &(data->child_pid),
-- NULL, /* gint *stdin_fd */
-- &(data->child_stdout_fd),
-- &(data->child_stderr_fd),
-- &error))
-- {
-- g_prefix_error (&error, "Error spawning: ");
-- g_simple_async_result_take_error (data->simple, error);
-- g_simple_async_result_complete_in_idle (data->simple);
-- g_object_unref (data->simple);
-- goto out;
-- }
--
-- if (timeout_seconds > 0)
-- {
-- data->timeout_source = g_timeout_source_new_seconds (timeout_seconds);
-- g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT);
-- g_source_set_callback (data->timeout_source, utils_timeout_cb, data, NULL);
-- g_source_attach (data->timeout_source, data->main_context);
-- g_source_unref (data->timeout_source);
-- }
--
-- data->child_watch_source = g_child_watch_source_new (data->child_pid);
-- g_source_set_callback (data->child_watch_source, (GSourceFunc) utils_child_watch_cb, data, NULL);
-- g_source_attach (data->child_watch_source, data->main_context);
-- g_source_unref (data->child_watch_source);
--
-- data->child_stdout_channel = g_io_channel_unix_new (data->child_stdout_fd);
-- g_io_channel_set_flags (data->child_stdout_channel, G_IO_FLAG_NONBLOCK, NULL);
-- data->child_stdout_source = g_io_create_watch (data->child_stdout_channel, G_IO_IN);
-- g_source_set_callback (data->child_stdout_source, (GSourceFunc) utils_read_child_stdout, data, NULL);
-- g_source_attach (data->child_stdout_source, data->main_context);
-- g_source_unref (data->child_stdout_source);
--
-- data->child_stderr_channel = g_io_channel_unix_new (data->child_stderr_fd);
-- g_io_channel_set_flags (data->child_stderr_channel, G_IO_FLAG_NONBLOCK, NULL);
-- data->child_stderr_source = g_io_create_watch (data->child_stderr_channel, G_IO_IN);
-- g_source_set_callback (data->child_stderr_source, (GSourceFunc) utils_read_child_stderr, data, NULL);
-- g_source_attach (data->child_stderr_source, data->main_context);
-- g_source_unref (data->child_stderr_source);
--
-- out:
-- ;
--}
--
--gboolean
--utils_spawn_finish (GAsyncResult *res,
-- gint *out_exit_status,
-- gchar **out_standard_output,
-- gchar **out_standard_error,
-- GError **error)
--{
-- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
-- UtilsSpawnData *data;
-- gboolean ret = FALSE;
--
-- g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
-- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
--
-- g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == utils_spawn);
--
-- if (g_simple_async_result_propagate_error (simple, error))
-- goto out;
--
-- data = (UtilsSpawnData*)g_simple_async_result_get_op_res_gpointer (simple);
--
-- if (data->timed_out)
-- {
-- g_set_error (error,
-- G_IO_ERROR,
-- G_IO_ERROR_TIMED_OUT,
-- "Timed out after %d seconds",
-- data->timeout_seconds);
-- goto out;
-- }
--
-- if (out_exit_status != NULL)
-- *out_exit_status = data->exit_status;
--
-- if (out_standard_output != NULL)
-- *out_standard_output = g_strdup (data->child_stdout->str);
--
-- if (out_standard_error != NULL)
-- *out_standard_error = g_strdup (data->child_stderr->str);
--
-- ret = TRUE;
--
-- out:
-- return ret;
--}
---
-GitLab
-
-
-From 4858128107be9c3ab11828ee8f35c5e26efd36ce Mon Sep 17 00:00:00 2001
-From: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
-Date: Tue, 14 Sep 2021 14:38:15 -0700
-Subject: [PATCH 15/16] Gitlab CI: add duktape pkgconfig dependency
-
-Make way for the CI to be able to build with duktape too
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- .gitlab-ci.yml | 1 +
- 1 file changed, 1 insertion(+)
-
-GitLab
-
-
-From cd5d6da837fce95f8831a355dad88c83347c7337 Mon Sep 17 00:00:00 2001
-From: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
-Date: Mon, 20 Sep 2021 17:17:26 -0700
-Subject: [PATCH 16/16] duktape: implement runaway scripts killer timeout
-
-This was missing on Duktape's JS backend proposal, now in. As
-discussed in
-https://gitlab.freedesktop.org/polkit/polkit/-/merge_requests/35 and
-verified by the commit author, Duktape has no interrupt injection
-mechanism (it has no thread-safe API entry whatsoever, even). Using
-DUK_USE_EXEC_TIMEOUT_CHECK is also not feasible, because:
-
- i) It must be enabled at build time and shared object builds of the
- lib on distros go with the default options, something we cannot
- change/control
-
- ii) That does not account for non-ECMAScript explicit execution
- contexts, like regex execution, native C calls, etc.
-
-It has been agreed, on that thread, that pthread_cond_timedwait()-ing
-and having proper Duktape evaluation/execution calls take place in a
-separate thread, to be killed after the runaway script killer's
-accorded timeout value, a reasonable approach. We have considered
-using glib wrappers for direct pthread usage, but that way would make
-it impossible to issue
-pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, ...) and we want to
-be paranoid in that regard.
-
-On Duktape, we don't get to err from the JS context (to be captured by
-the offending script), but to be forcibly killed on timeout scenarios,
-leading to null returns, thus polkit negation, by definition. It's a
-reasonable design/compromise.
-
-A fatal error handler routine, for the Duktape context, has also been
-added, using the polkit_backend_authority_log() logging infra to
-better assist users on what went wrong.
-
-Finally, the script evaluation routine has been made to use
-duk_peval_lstring() (previously using _noresult variant), so to able
-to present the user with proper error messages, should any occur.
-
-The original runaway script killer test has been adjusted to please
-both JS backends.
-
-Signed-off-by: Gustavo Lima Chaves <gustavo.chaves@microsoft.com>
----
- meson.build | 1 +
- src/polkitbackend/meson.build | 1 +
- src/polkitbackend/polkitbackendcommon.h | 2 +
- .../polkitbackendduktapeauthority.c | 236 ++++++++++++++----
- .../polkitbackendjsauthority.cpp | 10 +-
- .../etc/polkit-1/rules.d/10-testing.rules | 6 +-
- .../test-polkitbackendjsauthority.c | 2 +-
- 7 files changed, 209 insertions(+), 49 deletions(-)
-
-diff --git a/meson.build b/meson.build
-index 4e44723..46956e3 100644
---- a/meson.build
-+++ b/meson.build
-@@ -137,6 +137,7 @@ js_engine = get_option('js_engine')
- if js_engine == 'duktape'
- js_dep = dependency('duktape')
- libm_dep = cc.find_library('m')
-+ libpthread_dep = cc.find_library('pthread')
- elif js_engine == 'mozjs'
- js_dep = dependency('mozjs-78')
- endif
-diff --git a/src/polkitbackend/meson.build b/src/polkitbackend/meson.build
-index 9ec01b2..4dfea39 100644
---- a/src/polkitbackend/meson.build
-+++ b/src/polkitbackend/meson.build
-@@ -34,6 +34,7 @@ c_flags = [
- if js_engine == 'duktape'
- sources += files('polkitbackendduktapeauthority.c')
- deps += libm_dep
-+ deps += libpthread_dep
- elif js_engine == 'mozjs'
- sources += files('polkitbackendjsauthority.cpp')
- endif
-diff --git a/src/polkitbackend/polkitbackendcommon.h b/src/polkitbackend/polkitbackendcommon.h
-index 6d0d267..dd700fc 100644
---- a/src/polkitbackend/polkitbackendcommon.h
-+++ b/src/polkitbackend/polkitbackendcommon.h
-@@ -50,6 +50,8 @@
- #include <systemd/sd-login.h>
- #endif /* HAVE_LIBSYSTEMD */
-
-+#define RUNAWAY_KILLER_TIMEOUT (15)
-+
- #ifdef __cplusplus
- extern "C" {
- #endif
-diff --git a/src/polkitbackend/polkitbackendduktapeauthority.c b/src/polkitbackend/polkitbackendduktapeauthority.c
-index a2b4420..80f1976 100644
---- a/src/polkitbackend/polkitbackendduktapeauthority.c
-+++ b/src/polkitbackend/polkitbackendduktapeauthority.c
-@@ -47,8 +47,20 @@ struct _PolkitBackendJsAuthorityPrivate
- GFileMonitor **dir_monitors; /* NULL-terminated array of GFileMonitor instances */
-
- duk_context *cx;
-+
-+ pthread_t runaway_killer_thread;
-+};
-+
-+enum
-+{
-+ RUNAWAY_KILLER_THREAD_EXIT_STATUS_UNSET,
-+ RUNAWAY_KILLER_THREAD_EXIT_STATUS_SUCCESS,
-+ RUNAWAY_KILLER_THREAD_EXIT_STATUS_FAILURE,
- };
-
-+static gboolean execute_script_with_runaway_killer(PolkitBackendJsAuthority *authority,
-+ const gchar *filename);
-+
- /* ---------------------------------------------------------------------------------------------------- */
-
- G_DEFINE_TYPE (PolkitBackendJsAuthority, polkit_backend_js_authority, POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY);
-@@ -67,6 +79,15 @@ static const duk_function_list_entry js_polkit_functions[] =
- { NULL, NULL, 0 },
- };
-
-+static void report_error (void *udata,
-+ const char *msg)
-+{
-+ PolkitBackendJsAuthority *authority = udata;
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-+ "fatal Duktape JS backend error: %s",
-+ (msg ? msg : "no message"));
-+}
-+
- static void
- polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority)
- {
-@@ -78,7 +99,6 @@ polkit_backend_js_authority_init (PolkitBackendJsAuthority *authority)
- static void
- load_scripts (PolkitBackendJsAuthority *authority)
- {
-- duk_context *cx = authority->priv->cx;
- GList *files = NULL;
- GList *l;
- guint num_scripts = 0;
-@@ -123,36 +143,9 @@ load_scripts (PolkitBackendJsAuthority *authority)
- for (l = files; l != NULL; l = l->next)
- {
- const gchar *filename = (gchar *)l->data;
--#if (DUK_VERSION >= 20000)
-- GFile *file = g_file_new_for_path (filename);
-- char *contents;
-- gsize len;
-- if (!g_file_load_contents (file, NULL, &contents, &len, NULL, NULL))
-- {
-- polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-- "Error compiling script %s",
-- filename);
-- g_object_unref (file);
-- continue;
-- }
-
-- g_object_unref (file);
-- if (duk_peval_lstring_noresult(cx, contents,len) != 0)
--#else
-- if (duk_peval_file_noresult (cx, filename) != 0)
--#endif
-- {
-- polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-- "Error compiling script %s: %s",
-- filename, duk_safe_to_string (authority->priv->cx, -1));
--#if (DUK_VERSION >= 20000)
-- g_free (contents);
--#endif
-+ if (!execute_script_with_runaway_killer(authority, filename))
- continue;
-- }
--#if (DUK_VERSION >= 20000)
-- g_free (contents);
--#endif
- num_scripts++;
- }
-
-@@ -232,7 +225,7 @@ polkit_backend_common_js_authority_constructed (GObject *object)
- PolkitBackendJsAuthority *authority = POLKIT_BACKEND_JS_AUTHORITY (object);
- duk_context *cx;
-
-- cx = duk_create_heap (NULL, NULL, NULL, authority, NULL);
-+ cx = duk_create_heap (NULL, NULL, NULL, authority, report_error);
- if (cx == NULL)
- goto fail;
-
-@@ -243,6 +236,9 @@ polkit_backend_common_js_authority_constructed (GObject *object)
- duk_put_function_list (cx, -1, js_polkit_functions);
- duk_put_prop_string (cx, -2, "polkit");
-
-+ /* load polkit objects/functions into JS context (e.g. addRule(),
-+ * _deleteRules(), _runRules() et al)
-+ */
- duk_eval_string (cx, init_js);
-
- if (authority->priv->rules_dirs == NULL)
-@@ -510,6 +506,167 @@ push_action_and_details (duk_context *cx,
-
- /* ---------------------------------------------------------------------------------------------------- */
-
-+typedef struct {
-+ PolkitBackendJsAuthority *authority;
-+ const gchar *filename;
-+ pthread_cond_t cond;
-+ pthread_mutex_t mutex;
-+ gint ret;
-+} RunawayKillerCtx;
-+
-+static gpointer
-+runaway_killer_thread_execute_js (gpointer user_data)
-+{
-+ RunawayKillerCtx *ctx = user_data;
-+ duk_context *cx = ctx->authority->priv->cx;
-+
-+ int oldtype;
-+
-+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-+
-+#if (DUK_VERSION >= 20000)
-+ GFile *file = g_file_new_for_path(ctx->filename);
-+ char *contents;
-+ gsize len;
-+
-+ if (!g_file_load_contents(file, NULL, &contents, &len, NULL, NULL)) {
-+ polkit_backend_authority_log(POLKIT_BACKEND_AUTHORITY(ctx->authority),
-+ "Error compiling script %s", ctx->filename);
-+ g_object_unref(file);
-+ goto err;
-+ }
-+
-+ g_object_unref(file);
-+
-+ /* evaluate the script, trying to print context in any syntax errors
-+ found */
-+ if (duk_peval_lstring(cx, contents, len) != 0)
-+#else
-+ if (duk_peval_file(cx, ctx->filename) != 0)
-+#endif
-+ {
-+ polkit_backend_authority_log(POLKIT_BACKEND_AUTHORITY(ctx->authority),
-+ "Error compiling script %s: %s", ctx->filename,
-+ duk_safe_to_string(cx, -1));
-+ duk_pop(cx);
-+ goto free_err;
-+ }
-+#if (DUK_VERSION >= 20000)
-+ g_free(contents);
-+#endif
-+
-+ ctx->ret = RUNAWAY_KILLER_THREAD_EXIT_STATUS_SUCCESS;
-+ goto end;
-+
-+free_err:
-+#if (DUK_VERSION >= 20000)
-+ g_free(contents);
-+#endif
-+err:
-+ ctx->ret = RUNAWAY_KILLER_THREAD_EXIT_STATUS_FAILURE;
-+end:
-+ pthread_cond_signal(&ctx->cond);
-+ return NULL;
-+}
-+
-+static gpointer
-+runaway_killer_thread_call_js (gpointer user_data)
-+{
-+ RunawayKillerCtx *ctx = user_data;
-+ duk_context *cx = ctx->authority->priv->cx;
-+ int oldtype;
-+
-+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-+
-+ if (duk_pcall_prop (cx, 0, 2) != DUK_EXEC_SUCCESS)
-+ {
-+ polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (ctx->authority),
-+ "Error evaluating admin rules: ",
-+ duk_safe_to_string (cx, -1));
-+ goto err;
-+ }
-+
-+ ctx->ret = RUNAWAY_KILLER_THREAD_EXIT_STATUS_SUCCESS;
-+ goto end;
-+
-+err:
-+ ctx->ret = RUNAWAY_KILLER_THREAD_EXIT_STATUS_FAILURE;
-+end:
-+ pthread_cond_signal(&ctx->cond);
-+ return NULL;
-+}
-+
-+/* Blocking for at most for RUNAWAY_KILLER_TIMEOUT */
-+static gboolean
-+execute_script_with_runaway_killer(PolkitBackendJsAuthority *authority,
-+ const gchar *filename)
-+{
-+ gint64 end_time;
-+ gboolean cancel = FALSE;
-+ RunawayKillerCtx ctx = {.authority = authority, .filename = filename,
-+ .ret = RUNAWAY_KILLER_THREAD_EXIT_STATUS_UNSET,
-+ .mutex = PTHREAD_MUTEX_INITIALIZER,
-+ .cond = PTHREAD_COND_INITIALIZER};
-+ struct timespec abs_time;
-+
-+ pthread_mutex_lock(&ctx.mutex);
-+
-+ clock_gettime(CLOCK_REALTIME, &abs_time);
-+ abs_time.tv_sec += RUNAWAY_KILLER_TIMEOUT;
-+
-+ pthread_create(&authority->priv->runaway_killer_thread, NULL, runaway_killer_thread_execute_js, &ctx);
-+
-+ while (ctx.ret == RUNAWAY_KILLER_THREAD_EXIT_STATUS_UNSET) /* loop to treat spurious wakeups */
-+ if (pthread_cond_timedwait(&ctx.cond, &ctx.mutex, &abs_time) == ETIMEDOUT) {
-+ cancel = TRUE;
-+ break;
-+ }
-+
-+ pthread_mutex_unlock(&ctx.mutex);
-+
-+ if (cancel)
-+ pthread_cancel (authority->priv->runaway_killer_thread);
-+ pthread_join (authority->priv->runaway_killer_thread, NULL);
-+
-+ return ctx.ret == RUNAWAY_KILLER_THREAD_EXIT_STATUS_SUCCESS;
-+}
-+
-+/* Calls already stacked function and args. Blocking for at most for
-+ * RUNAWAY_KILLER_TIMEOUT
-+ */
-+static gboolean
-+call_js_function_with_runaway_killer(PolkitBackendJsAuthority *authority)
-+{
-+ gint64 end_time;
-+ gboolean cancel = FALSE;
-+ RunawayKillerCtx ctx = {.authority = authority,
-+ .ret = RUNAWAY_KILLER_THREAD_EXIT_STATUS_UNSET,
-+ .mutex = PTHREAD_MUTEX_INITIALIZER,
-+ .cond = PTHREAD_COND_INITIALIZER};
-+ struct timespec abs_time;
-+
-+ pthread_mutex_lock(&ctx.mutex);
-+
-+ clock_gettime(CLOCK_REALTIME, &abs_time);
-+ abs_time.tv_sec += RUNAWAY_KILLER_TIMEOUT;
-+
-+ pthread_create(&authority->priv->runaway_killer_thread, NULL, runaway_killer_thread_call_js, &ctx);
-+
-+ while (ctx.ret == RUNAWAY_KILLER_THREAD_EXIT_STATUS_UNSET) /* loop to treat spurious wakeups */
-+ if (pthread_cond_timedwait(&ctx.cond, &ctx.mutex, &abs_time) == ETIMEDOUT) {
-+ cancel = TRUE;
-+ break;
-+ }
-+
-+ pthread_mutex_unlock(&ctx.mutex);
-+
-+ if (cancel)
-+ pthread_cancel (authority->priv->runaway_killer_thread);
-+ pthread_join (authority->priv->runaway_killer_thread, NULL);
-+
-+ return ctx.ret == RUNAWAY_KILLER_THREAD_EXIT_STATUS_SUCCESS;
-+}
-+
- /* ---------------------------------------------------------------------------------------------------- */
-
- GList *
-@@ -557,13 +714,8 @@ polkit_backend_common_js_authority_get_admin_auth_identities (PolkitBackendInter
- goto out;
- }
-
-- if (duk_pcall_prop (cx, 0, 2) != DUK_ERR_NONE)
-- {
-- polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-- "Error evaluating admin rules: ",
-- duk_safe_to_string (cx, -1));
-- goto out;
-- }
-+ if (!call_js_function_with_runaway_killer (authority))
-+ goto out;
-
- ret_str = duk_require_string (cx, -1);
-
-@@ -643,15 +795,11 @@ polkit_backend_common_js_authority_check_authorization_sync (PolkitBackendIntera
- goto out;
- }
-
-- if (duk_pcall_prop (cx, 0, 2) != DUK_ERR_NONE)
-- {
-- polkit_backend_authority_log (POLKIT_BACKEND_AUTHORITY (authority),
-- "Error evaluating authorization rules: ",
-- duk_safe_to_string (cx, -1));
-- goto out;
-- }
-+ if (!call_js_function_with_runaway_killer (authority))
-+ goto out;
-
- if (duk_is_null(cx, -1)) {
-+ /* this fine, means there was no match, use implicit authorizations */
- good = TRUE;
- goto out;
- }
-diff --git a/src/polkitbackend/polkitbackendjsauthority.cpp b/src/polkitbackend/polkitbackendjsauthority.cpp
-index e28091d..11e91c0 100644
---- a/src/polkitbackend/polkitbackendjsauthority.cpp
-+++ b/src/polkitbackend/polkitbackendjsauthority.cpp
-@@ -829,11 +829,14 @@ runaway_killer_setup (PolkitBackendJsAuthority *authority)
- {
- g_assert (authority->priv->rkt_source == NULL);
-
-- /* set-up timer for runaway scripts, will be executed in runaway_killer_thread */
-+ /* set-up timer for runaway scripts, will be executed in
-+ runaway_killer_thread, that is one, permanent thread running a glib
-+ mainloop (rkt_loop) whose context (rkt_context) has a timeout source
-+ (rkt_source) */
- g_mutex_lock (&authority->priv->rkt_timeout_pending_mutex);
- authority->priv->rkt_timeout_pending = FALSE;
- g_mutex_unlock (&authority->priv->rkt_timeout_pending_mutex);
-- authority->priv->rkt_source = g_timeout_source_new_seconds (15);
-+ authority->priv->rkt_source = g_timeout_source_new_seconds (RUNAWAY_KILLER_TIMEOUT);
- g_source_set_callback (authority->priv->rkt_source, rkt_on_timeout, authority, NULL);
- g_source_attach (authority->priv->rkt_source, authority->priv->rkt_context);
-
-@@ -893,6 +896,9 @@ execute_script_with_runaway_killer (PolkitBackendJsAuthority *authority,
- {
- bool ret;
-
-+ // tries to JS_ExecuteScript(), may hang for > RUNAWAY_KILLER_TIMEOUT,
-+ // runaway_killer_thread makes sure the call returns, due to exception
-+ // injection
- runaway_killer_setup (authority);
- ret = JS_ExecuteScript (authority->priv->cx,
- script,
-diff --git a/test/data/etc/polkit-1/rules.d/10-testing.rules b/test/data/etc/polkit-1/rules.d/10-testing.rules
-index 98bf062..e346b5d 100644
---- a/test/data/etc/polkit-1/rules.d/10-testing.rules
-+++ b/test/data/etc/polkit-1/rules.d/10-testing.rules
-@@ -189,8 +189,10 @@ polkit.addRule(function(action, subject) {
- ;
- } catch (error) {
- if (error == "Terminating runaway script")
-- return polkit.Result.YES;
-- return polkit.Result.NO;
-+ // Inverted logic to accomodate Duktape's model as well, which
-+ // will always fail with negation, on timeouts
-+ return polkit.Result.NO;
-+ return polkit.Result.YES;
- }
- }
- });
-diff --git a/test/polkitbackend/test-polkitbackendjsauthority.c b/test/polkitbackend/test-polkitbackendjsauthority.c
-index f97e0e0..2103b17 100644
---- a/test/polkitbackend/test-polkitbackendjsauthority.c
-+++ b/test/polkitbackend/test-polkitbackendjsauthority.c
-@@ -328,7 +328,7 @@ static const RulesTestCase rules_test_cases[] = {
- "net.company.run_away_script",
- "unix-user:root",
- NULL,
-- POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED,
-+ POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED,
- },
-
- {
---
-GitLab
-
diff --git a/gnu/packages/patches/postgresql-riscv-spinlocks.patch b/gnu/packages/patches/postgresql-riscv-spinlocks.patch
deleted file mode 100644
index 984a573642..0000000000
--- a/gnu/packages/patches/postgresql-riscv-spinlocks.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-https://www.postgresql.org/message-id/dea97b6d-f55f-1f6d-9109-504aa7dfa421@gentoo.org
-
-The attached patch adds native spinlock support to PostgreSQL on RISC-V
-systems. As suspected by Richard W.M. Jones of Red Hat back in 2016, the
-__sync_lock_test_and_set() approach applied on arm and arm64 works here
-as well.
-
-
-Tested against PostgreSQL 13.3 on a physical rv64gc system (BeagleV
-Starlight beta board) - builds and installs fine, all tests pass. From
-what I can see in gcc documentation this should in theory work on rv32
-(and possibly rv128) as well, therefore the patch as it stands covers
-all RISC-V systems (i.e. doesn't check the value of __risc_xlen) - but I
-haven't confirmed this experimentally.
-
---- a/src/include/storage/s_lock.h
-+++ b/src/include/storage/s_lock.h
-@@ -315,12 +315,12 @@
- #endif /* __ia64__ || __ia64 */
-
- /*
-- * On ARM and ARM64, we use __sync_lock_test_and_set(int *, int) if available.
-+ * On ARM, ARM64 and RISC-V, we use __sync_lock_test_and_set(int *, int) if available.
- *
- * We use the int-width variant of the builtin because it works on more chips
- * than other widths.
- */
--#if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64)
-+#if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64) || defined(__riscv)
- #ifdef HAVE_GCC__SYNC_INT32_TAS
- #define HAS_TEST_AND_SET
-
-@@ -337,7 +337,7 @@
- #define S_UNLOCK(lock) __sync_lock_release(lock)
-
- #endif /* HAVE_GCC__SYNC_INT32_TAS */
--#endif /* __arm__ || __arm || __aarch64__ || __aarch64 */
-+#endif /* __arm__ || __arm || __aarch64__ || __aarch64 || __riscv */
-
-
- /* S/390 and S/390x Linux (32- and 64-bit zSeries) */
diff --git a/gnu/packages/patches/python-dateutil-pytest-compat.patch b/gnu/packages/patches/python-dateutil-pytest-compat.patch
new file mode 100644
index 0000000000..5cff57e94c
--- /dev/null
+++ b/gnu/packages/patches/python-dateutil-pytest-compat.patch
@@ -0,0 +1,43 @@
+Add compatibility with newer versions of pytest.
+
+Taken from upstream:
+
+ https://github.com/dateutil/dateutil/commit/2bdd63158b7f981fc6d70a869680451bdfd8d848
+
+diff --git a/dateutil/test/test_internals.py b/dateutil/test/test_internals.py
+index 53081314..b32e6723 100644
+--- a/dateutil/test/test_internals.py
++++ b/dateutil/test/test_internals.py
+@@ -9,6 +9,7 @@
+
+ import sys
+ import pytest
++import warnings
+
+ from dateutil.parser._parser import _ymd
+ from dateutil import tz
+@@ -65,18 +66,17 @@ def test_parser_parser_private_not_warns():
+ from dateutil.parser._parser import _timelex, _tzparser
+ from dateutil.parser._parser import _parsetz
+
+- with pytest.warns(None) as recorder:
++ with warnings.catch_warnings():
++ warnings.simplefilter("error")
+ _tzparser()
+- assert len(recorder) == 0
+
+- with pytest.warns(None) as recorder:
++ with warnings.catch_warnings():
++ warnings.simplefilter("error")
+ _timelex('2014-03-03')
+
+- assert len(recorder) == 0
+-
+- with pytest.warns(None) as recorder:
++ with warnings.catch_warnings():
++ warnings.simplefilter("error")
+ _parsetz('+05:00')
+- assert len(recorder) == 0
+
+
+ @pytest.mark.tzstr
diff --git a/gnu/packages/patches/ruby-hydra-minimal-no-byebug.patch b/gnu/packages/patches/ruby-hydra-minimal-no-byebug.patch
new file mode 100644
index 0000000000..7b338ca03e
--- /dev/null
+++ b/gnu/packages/patches/ruby-hydra-minimal-no-byebug.patch
@@ -0,0 +1,11 @@
+Description: Avoid dependency on byebug to reduce package closure
+ significantly, see https://issues.guix.gnu.org/55997
+diff --git a/lib/hydra.rb b/lib/hydra.rb
+index 29fbad2..6b5058a 100644
+--- a/lib/hydra.rb
++++ b/lib/hydra.rb
+@@ -1,4 +1,3 @@
+-require 'byebug' unless ENV['RACK_ENV'] == "production"
+ require 'pp'
+
+ module CoreExt
diff --git a/gnu/packages/patches/rustc-1.39.0-src.patch b/gnu/packages/patches/rustc-1.39.0-src.patch
deleted file mode 100644
index 7859bd44d5..0000000000
--- a/gnu/packages/patches/rustc-1.39.0-src.patch
+++ /dev/null
@@ -1,99 +0,0 @@
-# This modified patch is to disable the hunk applying to LLVM, unbundled in Guix.
-
-# Add mrustc slice length intrinsics
---- src/libcore/intrinsics.rs
-+++ src/libcore/intrinsics.rs
-@@ -685,4 +685,8 @@
- pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
-
-+ /// Obtain the length of a slice pointer
-+ #[cfg(rust_compiler="mrustc")]
-+ pub fn mrustc_slice_len<T>(pointer: *const [T]) -> usize;
-+
- /// Gets a static string slice containing the name of a type.
- pub fn type_name<T: ?Sized>() -> &'static str;
-
---- src/libcore/slice/mod.rs
-+++ src/libcore/slice/mod.rs
-@@ -68,5 +68,8 @@
- pub const fn len(&self) -> usize {
-- unsafe {
-- crate::ptr::Repr { rust: self }.raw.len
-- }
-+ #[cfg(not(rust_compiler="mrustc"))]
-+ #[cfg_attr(not(bootstrap), allow_internal_unstable(const_fn_union))]
-+ const fn len_inner<T>(s: &[T]) -> usize { unsafe { crate::ptr::Repr { rust: s }.raw.len } };
-+ #[cfg(rust_compiler="mrustc")]
-+ const fn len_inner<T>(s: &[T]) -> usize { unsafe { crate::intrinsics::mrustc_slice_len(s) } }
-+ len_inner(self)
- }
-#
-# Static-link rustc_codegen_llvm so the generated rustc is standalone
-# > Note: Interacts with `rustc-1.39.0-overrides.toml`
-#
---- src/librustc_interface/util.rs
-+++ src/librustc_interface/util.rs
-@@ -421,2 +421,4 @@
- pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
-+ #[cfg(rust_compiler="mrustc")]
-+ { if(backend_name == "llvm") { extern "Rust" { fn __rustc_codegen_backend() -> Box<dyn CodegenBackend>; } return || unsafe { __rustc_codegen_backend() } } }
- // For now we only allow this function to be called once as it'll dlopen a
-# Disable most architecture intrinsics
---- src/stdarch/crates/std_detect/src/detect/mod.rs
-+++ src/stdarch/crates/std_detect/src/detect/mod.rs
-@@ -74,4 +74,7 @@
- // this run-time detection logic is never called.
- #[path = "os/other.rs"]
- mod os;
-+ } else if #[cfg(rust_compiler="mrustc")] {
-+ #[path = "os/other.rs"]
-+ mod os;
- } else if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
---- vendor/ppv-lite86/src/lib.rs
-+++ vendor/ppv-lite86/src/lib.rs
-@@ -12,10 +12,10 @@
--#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri)))]
-+#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri), not(rust_compiler="mrustc")))]
- pub mod x86_64;
--#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri)))]
-+#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri), not(rust_compiler="mrustc")))]
- use self::x86_64 as arch;
-
--#[cfg(any(miri, not(all(feature = "simd", any(target_arch = "x86_64")))))]
-+#[cfg(any(miri, rust_compiler="mrustc", not(all(feature = "simd", any(target_arch = "x86_64")))))]
- pub mod generic;
--#[cfg(any(miri, not(all(feature = "simd", any(target_arch = "x86_64")))))]
-+#[cfg(any(miri, rust_compiler="mrustc", not(all(feature = "simd", any(target_arch = "x86_64")))))]
- use self::generic as arch;
-
-# diff --git a/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
-# index da9d9d5bfdc0..3d47471f0ef0 100644
-# --- src/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
-# +++ src/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
-# @@ -16,6 +16,8 @@
-# #include "llvm/Demangle/DemangleConfig.h"
-# #include "llvm/Demangle/StringView.h"
-# #include <array>
-# +#include <cstdint>
-# +#include <string>
-
-# namespace llvm {
-# namespace itanium_demangle {
-##
-## gcc (used by mrustc) has 16-byte uint128_t alignment, while rustc uses 8
-##
-#--- src/libsyntax/ast.rs
-#+++ src/libsyntax/ast.rs
-#@@ -986,2 +986,2 @@
-#-#[cfg(target_arch = "x86_64")]
-#-static_assert_size!(Expr, 96);
-#+//#[cfg(target_arch = "x86_64")]
-#+//static_assert_size!(Expr, 96);
-#--- src/librustc/ty/sty.rs
-#+++ src/librustc/ty/sty.rs
-#@@ -2258,2 +2258,2 @@
-#-#[cfg(target_arch = "x86_64")]
-#-static_assert_size!(Const<'_>, 40);
-#+//#[cfg(target_arch = "x86_64")]
-#+//static_assert_size!(Const<'_>, 40);
-
diff --git a/gnu/packages/patches/rustc-1.54.0-src.patch b/gnu/packages/patches/rustc-1.54.0-src.patch
new file mode 100644
index 0000000000..d075dce39b
--- /dev/null
+++ b/gnu/packages/patches/rustc-1.54.0-src.patch
@@ -0,0 +1,117 @@
+# mrustc is much better at enum packing, so causes almost all of these to be smaller by one pointer
+--- compiler/rustc_ast/src/ast.rs
++++ compiler/rustc_ast/src/ast.rs
+@@ -1075,7 +1075,7 @@ pub struct Expr {
+ }
+
+ // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler = "mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(Expr, 104);
+
+ impl Expr {
+@@ -2779,7 +2779,7 @@ pub enum AssocItemKind {
+ MacCall(MacCall),
+ }
+
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler = "mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(AssocItemKind, 72);
+
+ impl AssocItemKind {
+@@ -2831,7 +2831,7 @@ pub enum ForeignItemKind {
+ MacCall(MacCall),
+ }
+
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler="mrustc"),target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
+
+ impl From<ForeignItemKind> for ItemKind {
+--- compiler/rustc_hir/src/hir.rs
++++ compiler/rustc_hir/src/hir.rs
+@@ -3050,3 +3050,3 @@
+ // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler="mrustc"),target_arch = "x86_64", target_pointer_width = "64"))]
+ mod size_asserts {
+--- compiler/rustc_middle/src/mir/interpret/error.rs
++++ compiler/rustc_middle/src/mir/interpret/error.rs
+@@ -452,2 +452,2 @@
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler="mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ static_assert_size!(InterpError<'_>, 64);
+--- compiler/rustc_middle/src/mir/mod.rs
++++ compiler/rustc_middle/src/mir/mod.rs
+@@ -2203,2 +2203,2 @@
+-#[cfg(target_arch = "x86_64")]
++#[cfg(all(not(rust_compiler="mrustc"), target_arch = "x86_64"))]
+ static_assert_size!(AggregateKind<'_>, 48);
+--- compiler/rustc_middle/src/thir.rs
++++ compiler/rustc_middle/src/thir.rs
+@@ -147,2 +147,2 @@
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler="mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(Expr<'_>, 144);
+--- compiler/rustc_mir/src/interpret/place.rs
++++ compiler/rustc_mir/src/interpret/place.rs
+@@ -91,2 +91,2 @@
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler = "mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(Place, 64);
+@@ -100,2 +100,2 @@
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler = "mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(PlaceTy<'_>, 80);
+--- compiler/rustc_mir/src/interpret/operand.rs
++++ compiler/rustc_mir/src/interpret/operand.rs
+@@ -35,2 +35,2 @@
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler = "mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(Immediate, 56);
+@@ -90,2 +90,2 @@
+-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
++#[cfg(all(not(rust_compiler = "mrustc"), target_arch = "x86_64", target_pointer_width = "64"))]
+ rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
+
+#
+# Disable crc32fast's use of stdarch
+#
+--- vendor/crc32fast/src/specialized/mod.rs
++++ vendor/crc32fast/src/specialized/mod.rs
+@@ -1,5 +1,6 @@
+ cfg_if! {
+ if #[cfg(all(
++ not(rust_compiler = "mrustc"),
+ crc32fast_stdarchx86,
+ any(target_arch = "x86", target_arch = "x86_64")
+ ))] {
+
+#
+# Disable std_detect's detection logic (use the same logic as miri)
+#
+--- library/stdarch/crates/std_detect/src/detect/mod.rs
++++ library/stdarch/crates/std_detect/src/detect/mod.rs
+@@ -88,2 +88,2 @@
+ cfg_if! {
+- if #[cfg(miri)] {
++ if #[cfg(any(miri, rust_compiler = "mrustc"))] {
+
+# PPV-Lite also needs to know that we're pretending to be miri
+--- vendor/ppv-lite86/src/lib.rs
++++ vendor/ppv-lite86/src/lib.rs
+@@ -12,9 +12,9 @@
+-#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri)))]
++#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri), not(rust_compiler = "mrustc")))]
+ pub mod x86_64;
+-#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri)))]
++#[cfg(all(feature = "simd", target_arch = "x86_64", not(miri), not(rust_compiler = "mrustc")))]
+ use self::x86_64 as arch;
+
+-#[cfg(any(miri, not(all(feature = "simd", any(target_arch = "x86_64")))))]
++#[cfg(any(miri, rust_compiler = "mrustc", not(all(feature = "simd", any(target_arch = "x86_64")))))]
+ pub mod generic;
+-#[cfg(any(miri, not(all(feature = "simd", any(target_arch = "x86_64")))))]
++#[cfg(any(miri, rust_compiler = "mrustc", not(all(feature = "simd", any(target_arch = "x86_64")))))]
+ use self::generic as arch;
+
diff --git a/gnu/packages/patches/texlive-hyph-utf8-no-byebug.patch b/gnu/packages/patches/texlive-hyph-utf8-no-byebug.patch
new file mode 100644
index 0000000000..fb29b76ef2
--- /dev/null
+++ b/gnu/packages/patches/texlive-hyph-utf8-no-byebug.patch
@@ -0,0 +1,13 @@
+Description: Avoid dependency on byebug to reduce package closure
+ significantly, see https://issues.guix.gnu.org/55997
+diff --git a/lib/tex/hyphen/language.rb b/lib/tex/hyphen/language.rb
+index 12831417..df6daa39 100644
+--- a/lib/tex/hyphen/language.rb
++++ b/lib/tex/hyphen/language.rb
+@@ -1,6 +1,5 @@
+ require 'yaml'
+ require 'hydra'
+-require 'byebug'
+
+ require_relative 'path'
+