diff options
author | Marius Bakke <marius@gnu.org> | 2022-10-16 00:10:07 +0200 |
---|---|---|
committer | Marius Bakke <marius@gnu.org> | 2022-10-16 00:10:07 +0200 |
commit | c567a82a6975e70c8207a4aeed55a72b5121213c (patch) | |
tree | 8a6dfe8a78726933e4a1581a2c6ba4a84d59411f /gnu/packages/patches | |
parent | 3a84b4ec4cec1d122cb454da9d4f6a747a51e49a (diff) | |
parent | 322917aeb8e672c21378fd371a5cff4a9f0c2520 (diff) | |
download | guix-c567a82a6975e70c8207a4aeed55a72b5121213c.tar.gz |
Merge branch 'staging'
Diffstat (limited to 'gnu/packages/patches')
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' + |