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)
26static inline void openlog(const char *, int, int)
27{
28}
29static 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
41namespace KAuth
42{
43namespace HelperSupport
44{
45void helperDebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgStr);
46}
47
48static bool remote_dbg = false;
49
50#ifdef Q_OS_UNIX
51static 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
66int 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
106void 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
138void HelperSupport::progressStep(int step)
139{
140 BackendsManager::helperProxy()->sendProgressStep(step);
141}
142
143void HelperSupport::progressStep(const QVariantMap &data)
144{
145 BackendsManager::helperProxy()->sendProgressStepData(step: data);
146}
147
148bool HelperSupport::isStopped()
149{
150 return BackendsManager::helperProxy()->hasToStopAction();
151}
152
153int HelperSupport::callerUid()
154{
155 return BackendsManager::helperProxy()->callerUid();
156}
157
158} // namespace Auth
159

source code of kauth/src/helpersupport.cpp