File indexing completed on 2024-03-24 05:33:39
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 #endif 0028 0029 static inline KAboutData aboutData() 0030 { 0031 return KAboutData(QStringLiteral("kwrited"), i18n("kwrited"), QLatin1String(PROJECT_VERSION)); 0032 } 0033 0034 #if BUILD_AS_EXECUTABLE 0035 0036 static uid_t original_euid; 0037 static gid_t original_egid; 0038 0039 static void sigterm_handler(int signal) 0040 { 0041 Q_UNUSED(signal) 0042 QGuiApplication::quit(); 0043 } 0044 0045 int main(int argc, char **argv) 0046 { 0047 // drop elevated privileges temporarily 0048 original_euid = geteuid(); 0049 original_egid = getegid(); 0050 seteuid(getuid()); 0051 setegid(getgid()); 0052 0053 // install a signal handler to exit gracefully 0054 //(so that pty->logout() is called in ~KWrited()) 0055 signal(SIGTERM, sigterm_handler); 0056 signal(SIGINT, sigterm_handler); 0057 signal(SIGHUP, sigterm_handler); 0058 0059 QGuiApplication::setDesktopSettingsAware(false); 0060 QGuiApplication a(argc, argv); 0061 KAboutData::setApplicationData(aboutData()); 0062 auto disableSessionManagement = [](QSessionManager &sm) { 0063 sm.setRestartHint(QSessionManager::RestartNever); 0064 }; 0065 QObject::connect(&a, &QGuiApplication::commitDataRequest, disableSessionManagement); 0066 QObject::connect(&a, &QGuiApplication::saveStateRequest, disableSessionManagement); 0067 0068 KWrited w; 0069 return a.exec(); 0070 } 0071 0072 #else // BUILD_AS_EXECUTABLE 0073 0074 KWritedModule::KWritedModule(QObject *parent, const QList<QVariant> &) 0075 : KDEDModule(parent) 0076 { 0077 pro = new KWrited; 0078 } 0079 0080 KWritedModule::~KWritedModule() 0081 { 0082 delete pro; 0083 } 0084 0085 K_PLUGIN_FACTORY_WITH_JSON(KWritedFactory, "kwrited.json", registerPlugin<KWritedModule>();) 0086 0087 #endif // BUILD_AS_EXECUTABLE 0088 0089 KWrited::KWrited() 0090 : QObject() 0091 { 0092 pty = new KPtyDevice(); 0093 pty->open(); 0094 0095 #if BUILD_AS_EXECUTABLE 0096 dup2(pty->slaveFd(), 0); // HACK: login() from glibc requires this to login correctly 0097 // restore elevated privileges 0098 seteuid(original_euid); 0099 setegid(original_egid); 0100 #endif 0101 0102 pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY").constData()); 0103 0104 #if BUILD_AS_EXECUTABLE 0105 // drop privileges again 0106 seteuid(getuid()); 0107 setegid(getgid()); 0108 #endif 0109 0110 connect(pty, &QIODevice::readyRead, this, &KWrited::block_in); 0111 // qDebug() << "listening on device" << pty->ttyName(); 0112 } 0113 0114 KWrited::~KWrited() 0115 { 0116 #if BUILD_AS_EXECUTABLE 0117 // restore elevated privileges 0118 seteuid(original_euid); 0119 setegid(original_egid); 0120 #endif 0121 0122 pty->logout(); 0123 0124 #if BUILD_AS_EXECUTABLE 0125 // drop privileges again 0126 seteuid(getuid()); 0127 setegid(getgid()); 0128 #endif 0129 0130 delete pty; 0131 } 0132 0133 void KWrited::block_in() 0134 { 0135 QByteArray buf = pty->readAll(); 0136 QString msg = QString::fromLocal8Bit(buf.constData(), buf.size()); 0137 msg.remove(QLatin1Char('\r')); 0138 msg.remove(QLatin1Char('\a')); 0139 msg = msg.trimmed(); 0140 0141 KNotification *notification = new KNotification(QStringLiteral("NewMessage"), KNotification::Persistent); 0142 #if !BUILD_AS_EXECUTABLE 0143 notification->setComponentName(QStringLiteral("kwrited")); 0144 #endif 0145 notification->setText(msg); 0146 notification->setFlags(KNotification::SkipGrouping); 0147 connect(notification, &KNotification::closed, notification, &QObject::deleteLater); 0148 notification->sendEvent(); 0149 } 0150 0151 #if !BUILD_AS_EXECUTABLE 0152 #include "kwrited.moc" 0153 #endif 0154 0155 #include "moc_kwrited.cpp"