Advance Wayland and KDE package bring-up

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-14 10:51:06 +01:00
parent 51f3c21121
commit cf12defd28
15214 changed files with 20594243 additions and 269 deletions
@@ -0,0 +1,163 @@
/*
SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com>
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "policy-gen.h"
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QRegularExpression>
#include <QSettings>
#include <QStringList>
#include <cerrno>
#include <cstdio>
using namespace std;
QList<Action> parse(QSettings &ini);
QMap<QString, QString> parseDomain(const QSettings &ini);
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
if (argc < 2) {
qCritical("Too few arguments");
return 1;
}
QSettings ini(QFile::decodeName(argv[1]), QSettings::IniFormat);
if (ini.status()) {
qCritical("Error loading file: %s", argv[1]);
return 1;
}
if (argc == 3) {
// Support an optional 2nd argument pointing to the output file
//
// This is safer to use in build systems than
// "kauth-policy-gen foo.actions > foo.policy" because when using a
// redirection "foo.policy" is created even if kauth-policy-gen fails.
// This means the first call to make fails, but a second call succeeds
// because an empty "foo.policy" exists.
if (!freopen(argv[2], "w", stdout)) {
qCritical("Failed to open %s for writing: %s", argv[2], strerror(errno));
return 1;
}
}
output(parse(ini), parseDomain(ini));
}
QList<Action> parse(QSettings &ini)
{
// clazy:excludeall=use-static-qregularexpression
// example: [org.kde.kcontrol.kcmfoo.save]
const QRegularExpression actionExp(QRegularExpression::anchoredPattern(QStringLiteral("[0-9a-z]+(\\.[0-9a-z]+)*")));
// example: Description[ca]=Mòdul de control del Foo.
const QRegularExpression descriptionExp(QRegularExpression::anchoredPattern(QStringLiteral("description(?:\\[(\\w+)\\])?")),
QRegularExpression::CaseInsensitiveOption);
// example: Name[ca]=Mòdul de control del Foo
const QRegularExpression nameExp(QRegularExpression::anchoredPattern(QStringLiteral("name(?:\\[(\\w+)\\])?")), QRegularExpression::CaseInsensitiveOption);
// example: Policy=auth_admin
const QRegularExpression policyExp(QRegularExpression::anchoredPattern(QStringLiteral("(?:yes|no|auth_self|auth_admin)")));
QList<Action> actions;
const auto listChilds = ini.childGroups();
for (const QString &name : listChilds) {
Action action;
if (name == QLatin1String("Domain")) {
continue;
}
if (!actionExp.match(name).hasMatch()) {
qCritical("Wrong action syntax: %s\n", name.toLatin1().data());
exit(1);
}
action.name = name;
ini.beginGroup(name);
const QStringList listChildKeys = ini.childKeys();
for (const QString &key : listChildKeys) {
QRegularExpressionMatch match;
if ((match = descriptionExp.match(key)).hasMatch()) {
QString lang = match.captured(1);
if (lang.isEmpty()) {
lang = QString::fromLatin1("en");
}
action.descriptions.insert(lang, ini.value(key).toString());
} else if ((match = nameExp.match(key)).hasMatch()) {
QString lang = match.captured(1);
if (lang.isEmpty()) {
lang = QString::fromLatin1("en");
}
action.messages.insert(lang, ini.value(key).toString());
} else if (key.toLower() == QLatin1String("policy")) {
QString policy = ini.value(key).toString();
if (!policyExp.match(policy).hasMatch()) {
qCritical("Wrong policy: %s", policy.toLatin1().data());
exit(1);
}
action.policy = policy;
} else if (key.toLower() == QLatin1String("policyinactive")) {
QString policyInactive = ini.value(key).toString();
if (!policyExp.match(policyInactive).hasMatch()) {
qCritical("Wrong policy: %s", policyInactive.toLatin1().data());
exit(1);
}
action.policyInactive = policyInactive;
} else if (key.toLower() == QLatin1String("persistence")) {
QString persistence = ini.value(key).toString();
if (persistence != QLatin1String("session") && persistence != QLatin1String("always")) {
qCritical("Wrong persistence: %s", persistence.toLatin1().data());
exit(1);
}
action.persistence = persistence;
}
}
if (action.policy.isEmpty() || action.messages.isEmpty() || action.descriptions.isEmpty()) {
qCritical("Missing option in action: %s", name.toLatin1().data());
exit(1);
}
ini.endGroup();
actions.append(action);
}
return actions;
}
QMap<QString, QString> parseDomain(const QSettings &ini)
{
QMap<QString, QString> rethash;
if (ini.childGroups().contains(QString::fromLatin1("Domain"))) {
if (ini.contains(QString::fromLatin1("Domain/Name"))) {
rethash[QString::fromLatin1("vendor")] = ini.value(QString::fromLatin1("Domain/Name")).toString();
}
if (ini.contains(QString::fromLatin1("Domain/URL"))) {
rethash[QString::fromLatin1("vendorurl")] = ini.value(QString::fromLatin1("Domain/URL")).toString();
}
if (ini.contains(QString::fromLatin1("Domain/Icon"))) {
rethash[QString::fromLatin1("icon")] = ini.value(QString::fromLatin1("Domain/Icon")).toString();
}
}
return rethash;
}
@@ -0,0 +1,28 @@
/*
SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com>
SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org>
SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef _POLICY_GEN_H_
#define _POLICY_GEN_H_
#include <QHash>
#include <QMap>
#include <QString>
struct Action {
QString name;
QMap<QString, QString> descriptions;
QMap<QString, QString> messages;
QString policy;
QString policyInactive;
QString persistence;
};
extern void output(const QList<Action> &actions, const QMap<QString, QString> &domain);
#endif