File indexing completed on 2024-04-21 16:17:05
0001 /* 0002 kwrited is a write(1) receiver for KDE. 0003 SPDX-FileCopyrightText: 1997, 1998 Lars Doelle <lars.doelle@on-line.de> 0004 SPDX-FileCopyrightText: 2008 George Kiagiadakis <gkiagia@users.sourceforge.net> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 // Own 0010 #include "kwrited.h" 0011 0012 #include <QDebug> 0013 #include <kaboutdata.h> 0014 #include <klocalizedstring.h> 0015 #include <knotification.h> 0016 #include <kptydevice.h> 0017 #include <kuser.h> 0018 0019 #if BUILD_AS_EXECUTABLE 0020 #include <QGuiApplication> 0021 #include <QSessionManager> 0022 #include <signal.h> 0023 #include <sys/types.h> 0024 #include <unistd.h> 0025 #else 0026 #include <kpluginfactory.h> 0027 #include <kpluginloader.h> 0028 #endif 0029 0030 static inline KAboutData aboutData() 0031 { 0032 return KAboutData(QStringLiteral("kwrited"), i18n("kwrited"), QLatin1String(PROJECT_VERSION)); 0033 } 0034 0035 #if BUILD_AS_EXECUTABLE 0036 0037 static uid_t original_euid; 0038 static gid_t original_egid; 0039 0040 static void sigterm_handler(int signal) 0041 { 0042 Q_UNUSED(signal) 0043 QGuiApplication::quit(); 0044 } 0045 0046 int main(int argc, char **argv) 0047 { 0048 // drop elevated privileges temporarily 0049 original_euid = geteuid(); 0050 original_egid = getegid(); 0051 seteuid(getuid()); 0052 setegid(getgid()); 0053 0054 // install a signal handler to exit gracefully 0055 //(so that pty->logout() is called in ~KWrited()) 0056 signal(SIGTERM, sigterm_handler); 0057 signal(SIGINT, sigterm_handler); 0058 signal(SIGHUP, sigterm_handler); 0059 0060 QGuiApplication::setDesktopSettingsAware(false); 0061 QGuiApplication a(argc, argv); 0062 KAboutData::setApplicationData(aboutData()); 0063 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0064 QGuiApplication::setFallbackSessionManagementEnabled(false); 0065 #endif 0066 auto disableSessionManagement = [](QSessionManager &sm) { 0067 sm.setRestartHint(QSessionManager::RestartNever); 0068 }; 0069 QObject::connect(&a, &QGuiApplication::commitDataRequest, disableSessionManagement); 0070 QObject::connect(&a, &QGuiApplication::saveStateRequest, disableSessionManagement); 0071 0072 KWrited w; 0073 return a.exec(); 0074 } 0075 0076 #else // BUILD_AS_EXECUTABLE 0077 0078 KWritedModule::KWritedModule(QObject *parent, const QList<QVariant> &) 0079 : KDEDModule(parent) 0080 { 0081 pro = new KWrited; 0082 } 0083 0084 KWritedModule::~KWritedModule() 0085 { 0086 delete pro; 0087 } 0088 0089 K_PLUGIN_FACTORY_WITH_JSON(KWritedFactory, "kwrited.json", registerPlugin<KWritedModule>();) 0090 0091 #endif // BUILD_AS_EXECUTABLE 0092 0093 KWrited::KWrited() 0094 : QObject() 0095 { 0096 pty = new KPtyDevice(); 0097 pty->open(); 0098 0099 #if BUILD_AS_EXECUTABLE 0100 dup2(pty->slaveFd(), 0); // HACK: login() from glibc requires this to login correctly 0101 // restore elevated privileges 0102 seteuid(original_euid); 0103 setegid(original_egid); 0104 #endif 0105 0106 pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY").constData()); 0107 0108 #if BUILD_AS_EXECUTABLE 0109 // drop privileges again 0110 seteuid(getuid()); 0111 setegid(getgid()); 0112 #endif 0113 0114 connect(pty, &QIODevice::readyRead, this, &KWrited::block_in); 0115 // qDebug() << "listening on device" << pty->ttyName(); 0116 } 0117 0118 KWrited::~KWrited() 0119 { 0120 #if BUILD_AS_EXECUTABLE 0121 // restore elevated privileges 0122 seteuid(original_euid); 0123 setegid(original_egid); 0124 #endif 0125 0126 pty->logout(); 0127 0128 #if BUILD_AS_EXECUTABLE 0129 // drop privileges again 0130 seteuid(getuid()); 0131 setegid(getgid()); 0132 #endif 0133 0134 delete pty; 0135 } 0136 0137 void KWrited::block_in() 0138 { 0139 QByteArray buf = pty->readAll(); 0140 QString msg = QString::fromLocal8Bit(buf.constData(), buf.size()); 0141 msg.remove(QLatin1Char('\r')); 0142 msg.remove(QLatin1Char('\a')); 0143 msg = msg.trimmed(); 0144 0145 KNotification *notification = new KNotification(QStringLiteral("NewMessage"), KNotification::Persistent); 0146 #if !BUILD_AS_EXECUTABLE 0147 notification->setComponentName(QStringLiteral("kwrited")); 0148 #endif 0149 notification->setText(msg); 0150 notification->setFlags(KNotification::SkipGrouping); 0151 connect(notification, &KNotification::closed, notification, &QObject::deleteLater); 0152 notification->sendEvent(); 0153 } 0154 0155 #if !BUILD_AS_EXECUTABLE 0156 #include "kwrited.moc" 0157 #endif