File indexing completed on 2024-05-26 05:13:56
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2013 Volker Krause <vkrause@kde.org> * 0003 * * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later * 0005 ***************************************************************************/ 0006 0007 #include "session.h" 0008 0009 #include "private/standarddirs_p.h" 0010 0011 #include <QCoreApplication> 0012 #include <QFile> 0013 #include <QSettings> 0014 #include <QSocketNotifier> 0015 0016 #include <fcntl.h> 0017 #include <iostream> 0018 #include <unistd.h> 0019 0020 Session::Session(const QString &input, QObject *parent) 0021 : QObject(parent) 0022 { 0023 auto file = new QFile(this); 0024 if (input != QLatin1StringView("-")) { 0025 file->setFileName(input); 0026 if (!file->open(QFile::ReadOnly)) { 0027 qFatal("Failed to open %s", qPrintable(input)); 0028 } 0029 } else { 0030 // ### does that work on Windows? 0031 const int flags = fcntl(0, F_GETFL); 0032 fcntl(0, F_SETFL, flags | O_NONBLOCK); // NOLINT(hicpp-signed-bitwise) 0033 0034 if (!file->open(stdin, QFile::ReadOnly | QFile::Unbuffered)) { 0035 qFatal("Failed to open stdin!"); 0036 } 0037 m_notifier = new QSocketNotifier(0, QSocketNotifier::Read, this); 0038 connect(m_notifier, &QSocketNotifier::activated, this, &Session::inputAvailable); 0039 } 0040 m_input = file; 0041 } 0042 0043 Session::~Session() 0044 { 0045 } 0046 0047 void Session::connectToHost() 0048 { 0049 const QSettings connectionSettings(Akonadi::StandardDirs::connectionConfigFile(), QSettings::IniFormat); 0050 0051 QString serverAddress; 0052 #ifdef Q_OS_WIN 0053 serverAddress = connectionSettings.value(QStringLiteral("Data/NamedPipe"), QString()).toString(); 0054 #else 0055 serverAddress = connectionSettings.value(QStringLiteral("Data/UnixPath"), QString()).toString(); 0056 #endif 0057 if (serverAddress.isEmpty()) { 0058 qFatal("Unable to determine server address."); 0059 } 0060 0061 auto socket = new QLocalSocket(this); 0062 connect(socket, &QLocalSocket::errorOccurred, this, &Session::serverError); 0063 connect(socket, &QLocalSocket::disconnected, this, &Session::serverDisconnected); 0064 connect(socket, &QIODevice::readyRead, this, &Session::serverRead); 0065 connect(socket, &QLocalSocket::connected, this, &Session::inputAvailable); 0066 0067 m_session = socket; 0068 socket->connectToServer(serverAddress); 0069 0070 m_connectionTime.start(); 0071 } 0072 0073 void Session::inputAvailable() 0074 { 0075 if (!m_session->isOpen()) { 0076 return; 0077 } 0078 0079 if (m_notifier) { 0080 m_notifier->setEnabled(false); 0081 } 0082 0083 if (m_input->atEnd()) { 0084 return; 0085 } 0086 0087 QByteArray buffer(1024, Qt::Uninitialized); 0088 qint64 readSize = 0; 0089 0090 while ((readSize = m_input->read(buffer.data(), buffer.size())) > 0) { 0091 m_session->write(buffer.constData(), readSize); 0092 m_sentBytes += readSize; 0093 } 0094 0095 if (m_notifier) { 0096 m_notifier->setEnabled(true); 0097 } 0098 } 0099 0100 void Session::serverDisconnected() 0101 { 0102 QCoreApplication::exit(0); 0103 } 0104 0105 void Session::serverError(QLocalSocket::LocalSocketError socketError) 0106 { 0107 if (socketError == QLocalSocket::PeerClosedError) { 0108 QCoreApplication::exit(0); 0109 return; 0110 } 0111 0112 std::cerr << qPrintable(m_session->errorString()); 0113 QCoreApplication::exit(1); 0114 } 0115 0116 void Session::serverRead() 0117 { 0118 QByteArray buffer(1024, Qt::Uninitialized); 0119 qint64 readSize = 0; 0120 0121 while ((readSize = m_session->read(buffer.data(), buffer.size())) > 0) { 0122 write(1, buffer.data(), readSize); 0123 m_receivedBytes += readSize; 0124 } 0125 } 0126 0127 void Session::printStats() const 0128 { 0129 std::cerr << "Connection time: " << m_connectionTime.elapsed() << " ms" << std::endl; 0130 std::cerr << "Sent: " << m_sentBytes << " bytes" << std::endl; 0131 std::cerr << "Received: " << m_receivedBytes << " bytes" << std::endl; 0132 } 0133 0134 #include "moc_session.cpp"