1 | /* |
2 | SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com> |
3 | SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org> |
4 | SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.1-or-later |
7 | */ |
8 | |
9 | #include "helpersupport.h" |
10 | |
11 | #include <cstdlib> |
12 | |
13 | #ifndef Q_OS_WIN |
14 | #include <pwd.h> |
15 | #include <sys/types.h> |
16 | #include <syslog.h> |
17 | #include <unistd.h> |
18 | #else |
19 | // Quick hack to replace syslog (just write to stderr) |
20 | // TODO: should probably use ReportEvent |
21 | #define LOG_ERR 3 |
22 | #define LOG_WARNING 4 |
23 | #define LOG_DEBUG 7 |
24 | #define LOG_INFO 6 |
25 | #define LOG_USER (1 << 3) |
26 | static inline void openlog(const char *, int, int) |
27 | { |
28 | } |
29 | static inline void closelog() |
30 | { |
31 | } |
32 | #define syslog(level, ...) fprintf(stderr, __VA_ARGS__) |
33 | |
34 | #endif |
35 | |
36 | #include <QCoreApplication> |
37 | #include <QTimer> |
38 | |
39 | #include "BackendsManager.h" |
40 | |
41 | namespace KAuth |
42 | { |
43 | namespace HelperSupport |
44 | { |
45 | void helperDebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgStr); |
46 | } |
47 | |
48 | static bool remote_dbg = false; |
49 | |
50 | #ifdef Q_OS_UNIX |
51 | static void fixEnvironment() |
52 | { |
53 | // try correct HOME |
54 | const char *home = "HOME" ; |
55 | if (getenv(name: home) == nullptr) { |
56 | struct passwd *pw = getpwuid(uid: getuid()); |
57 | |
58 | if (pw != nullptr) { |
59 | int overwrite = 0; |
60 | setenv(name: home, value: pw->pw_dir, replace: overwrite); |
61 | } |
62 | } |
63 | } |
64 | #endif |
65 | |
66 | int HelperSupport::helperMain(int argc, char **argv, const char *id, QObject *responder) |
67 | { |
68 | #ifdef Q_OS_UNIX |
69 | fixEnvironment(); |
70 | #endif |
71 | |
72 | #ifdef Q_OS_OSX |
73 | openlog(id, LOG_CONS | LOG_PID, LOG_USER); |
74 | int logLevel = LOG_WARNING; |
75 | #else |
76 | openlog(ident: id, option: 0, LOG_USER); |
77 | int logLevel = LOG_DEBUG; |
78 | #endif |
79 | qInstallMessageHandler(&HelperSupport::helperDebugHandler); |
80 | |
81 | // NOTE: The helper proxy might use dbus, and we should have the qapp |
82 | // before using dbus. |
83 | QCoreApplication app(argc, argv); |
84 | |
85 | if (!BackendsManager::helperProxy()->initHelper(name: QString::fromLatin1(ba: id))) { |
86 | syslog(pri: logLevel, fmt: "Helper initialization failed" ); |
87 | return -1; |
88 | } |
89 | |
90 | // closelog(); |
91 | remote_dbg = true; |
92 | |
93 | BackendsManager::helperProxy()->setHelperResponder(responder); |
94 | |
95 | // Attach the timer |
96 | QTimer *timer = new QTimer(nullptr); |
97 | responder->setProperty(name: "__KAuth_Helper_Shutdown_Timer" , value: QVariant::fromValue(value: timer)); |
98 | timer->setInterval(10000); |
99 | timer->start(); |
100 | QObject::connect(sender: timer, signal: &QTimer::timeout, context: &app, slot: &QCoreApplication::quit); |
101 | app.exec(); // krazy:exclude=crashy |
102 | |
103 | return 0; |
104 | } |
105 | |
106 | void HelperSupport::helperDebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgStr) |
107 | { |
108 | Q_UNUSED(context); // can be used to find out about file, line, function name |
109 | QByteArray msg = msgStr.toLocal8Bit(); |
110 | if (!remote_dbg) { |
111 | int level = LOG_DEBUG; |
112 | switch (type) { |
113 | case QtDebugMsg: |
114 | level = LOG_DEBUG; |
115 | break; |
116 | case QtWarningMsg: |
117 | level = LOG_WARNING; |
118 | break; |
119 | case QtCriticalMsg: |
120 | case QtFatalMsg: |
121 | level = LOG_ERR; |
122 | break; |
123 | case QtInfoMsg: |
124 | level = LOG_INFO; |
125 | break; |
126 | } |
127 | syslog(pri: level, fmt: "%s" , msg.constData()); |
128 | } else { |
129 | BackendsManager::helperProxy()->sendDebugMessage(level: type, msg: msg.constData()); |
130 | } |
131 | |
132 | // Anyway I should follow the rule: |
133 | if (type == QtFatalMsg) { |
134 | exit(status: -1); |
135 | } |
136 | } |
137 | |
138 | void HelperSupport::progressStep(int step) |
139 | { |
140 | BackendsManager::helperProxy()->sendProgressStep(step); |
141 | } |
142 | |
143 | void HelperSupport::progressStep(const QVariantMap &data) |
144 | { |
145 | BackendsManager::helperProxy()->sendProgressStepData(step: data); |
146 | } |
147 | |
148 | bool HelperSupport::isStopped() |
149 | { |
150 | return BackendsManager::helperProxy()->hasToStopAction(); |
151 | } |
152 | |
153 | int HelperSupport::callerUid() |
154 | { |
155 | return BackendsManager::helperProxy()->callerUid(); |
156 | } |
157 | |
158 | } // namespace Auth |
159 | |