-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinputaccess.cpp
More file actions
60 lines (52 loc) · 1.92 KB
/
Copy pathinputaccess.cpp
File metadata and controls
60 lines (52 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "inputaccess.h"
#include <QDir>
#include <QFile>
#include <QProcess>
#include <QTemporaryFile>
QString InputAccess::ruleDestinationPath()
{
return QStringLiteral("/etc/udev/rules.d/71-trackclick-input.rules");
}
QString InputAccess::bundledRuleText()
{
QFile res(QStringLiteral(":/linux/71-trackclick-input.rules"));
if (!res.open(QIODevice::ReadOnly | QIODevice::Text))
return {};
return QString::fromUtf8(res.readAll());
}
InputAccess::InstallResult InputAccess::installUdevRule()
{
const QString ruleText = bundledRuleText();
if (ruleText.isEmpty())
return InstallResult::RuleUnavailable;
QString tmpPath;
{
QTemporaryFile tmp(QDir::tempPath() + QStringLiteral("/trackclick-XXXXXX.rules"));
tmp.setAutoRemove(false);
if (!tmp.open())
return InstallResult::TempFileFailed;
tmp.write(ruleText.toUtf8());
tmp.flush();
tmpPath = tmp.fileName();
}
// Both paths are app-controlled: dest is a constant, tmpPath comes from our
// own QTemporaryFile. Keep it that way — see the header.
const QString script = QStringLiteral(
"cp '%1' '%2' && chmod 0644 '%2' && "
"udevadm control --reload-rules && "
"udevadm trigger --subsystem-match=input --action=change")
.arg(tmpPath, ruleDestinationPath());
QProcess proc;
proc.start(QStringLiteral("pkexec"), {QStringLiteral("/bin/sh"),
QStringLiteral("-c"), script});
const bool started = proc.waitForStarted(5000);
bool finished = false;
if (started)
finished = proc.waitForFinished(120000); // allow time at the password prompt
QFile::remove(tmpPath);
if (!started)
return InstallResult::HelperMissing;
if (finished && proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0)
return InstallResult::Installed;
return InstallResult::Refused;
}