File indexing completed on 2025-02-16 13:00:41
0001 /* 0002 SPDX-FileCopyrightText: 2008 Nicola Gigante <nicola.gigante@gmail.com> 0003 SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org> 0004 SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #include "helpersupport.h" 0010 0011 #include <cstdlib> 0012 0013 #ifndef Q_OS_WIN 0014 #include <pwd.h> 0015 #include <sys/types.h> 0016 #include <syslog.h> 0017 #include <unistd.h> 0018 #else 0019 // Quick hack to replace syslog (just write to stderr) 0020 // TODO: should probably use ReportEvent 0021 #define LOG_ERR 3 0022 #define LOG_WARNING 4 0023 #define LOG_DEBUG 7 0024 #define LOG_INFO 6 0025 #define LOG_USER (1 << 3) 0026 static inline void openlog(const char *, int, int) 0027 { 0028 } 0029 static inline void closelog() 0030 { 0031 } 0032 #define syslog(level, ...) fprintf(stderr, __VA_ARGS__) 0033 0034 #endif 0035 0036 #include <QCoreApplication> 0037 #include <QTimer> 0038 #if defined(Q_OS_UNIX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0039 #include <QTextCodec> 0040 #endif 0041 0042 #include "BackendsManager.h" 0043 0044 namespace KAuth 0045 { 0046 namespace HelperSupport 0047 { 0048 void helperDebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgStr); 0049 } 0050 0051 static bool remote_dbg = false; 0052 0053 #ifdef Q_OS_UNIX 0054 static void fixEnvironment() 0055 { 0056 // try correct HOME 0057 const char *home = "HOME"; 0058 if (getenv(home) == nullptr) { 0059 struct passwd *pw = getpwuid(getuid()); 0060 0061 if (pw != nullptr) { 0062 int overwrite = 0; 0063 setenv(home, pw->pw_dir, overwrite); 0064 } 0065 } 0066 } 0067 #endif 0068 0069 int HelperSupport::helperMain(int argc, char **argv, const char *id, QObject *responder) 0070 { 0071 #ifdef Q_OS_UNIX 0072 fixEnvironment(); 0073 0074 // With Qt6, it's UTF-8 by default 0075 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0076 // As we don't inherit lang, the locale could be something that doesn't support UTF-8. Force it 0077 auto utf8Codec = QTextCodec::codecForName("UTF-8"); 0078 if (utf8Codec) { 0079 QTextCodec::setCodecForLocale(utf8Codec); 0080 } 0081 #endif 0082 #endif 0083 0084 #ifdef Q_OS_OSX 0085 openlog(id, LOG_CONS | LOG_PID, LOG_USER); 0086 int logLevel = LOG_WARNING; 0087 #else 0088 openlog(id, 0, LOG_USER); 0089 int logLevel = LOG_DEBUG; 0090 #endif 0091 qInstallMessageHandler(&HelperSupport::helperDebugHandler); 0092 0093 // NOTE: The helper proxy might use dbus, and we should have the qapp 0094 // before using dbus. 0095 QCoreApplication app(argc, argv); 0096 0097 if (!BackendsManager::helperProxy()->initHelper(QString::fromLatin1(id))) { 0098 syslog(logLevel, "Helper initialization failed"); 0099 return -1; 0100 } 0101 0102 // closelog(); 0103 remote_dbg = true; 0104 0105 BackendsManager::helperProxy()->setHelperResponder(responder); 0106 0107 // Attach the timer 0108 QTimer *timer = new QTimer(nullptr); 0109 responder->setProperty("__KAuth_Helper_Shutdown_Timer", QVariant::fromValue(timer)); 0110 timer->setInterval(10000); 0111 timer->start(); 0112 QObject::connect(timer, &QTimer::timeout, &app, &QCoreApplication::quit); 0113 app.exec(); // krazy:exclude=crashy 0114 0115 return 0; 0116 } 0117 0118 void HelperSupport::helperDebugHandler(QtMsgType type, const QMessageLogContext &context, const QString &msgStr) 0119 { 0120 Q_UNUSED(context); // can be used to find out about file, line, function name 0121 QByteArray msg = msgStr.toLocal8Bit(); 0122 if (!remote_dbg) { 0123 int level = LOG_DEBUG; 0124 switch (type) { 0125 case QtDebugMsg: 0126 level = LOG_DEBUG; 0127 break; 0128 case QtWarningMsg: 0129 level = LOG_WARNING; 0130 break; 0131 case QtCriticalMsg: 0132 case QtFatalMsg: 0133 level = LOG_ERR; 0134 break; 0135 case QtInfoMsg: 0136 level = LOG_INFO; 0137 break; 0138 } 0139 syslog(level, "%s", msg.constData()); 0140 } else { 0141 BackendsManager::helperProxy()->sendDebugMessage(type, msg.constData()); 0142 } 0143 0144 // Anyway I should follow the rule: 0145 if (type == QtFatalMsg) { 0146 exit(-1); 0147 } 0148 } 0149 0150 void HelperSupport::progressStep(int step) 0151 { 0152 BackendsManager::helperProxy()->sendProgressStep(step); 0153 } 0154 0155 void HelperSupport::progressStep(const QVariantMap &data) 0156 { 0157 BackendsManager::helperProxy()->sendProgressStepData(data); 0158 } 0159 0160 bool HelperSupport::isStopped() 0161 { 0162 return BackendsManager::helperProxy()->hasToStopAction(); 0163 } 0164 0165 int HelperSupport::callerUid() 0166 { 0167 return BackendsManager::helperProxy()->callerUid(); 0168 } 0169 0170 } // namespace Auth