Akonadi

asapcat/session.cpp
1 /***************************************************************************
2  * SPDX-FileCopyrightText: 2013 Volker Krause <[email protected]> *
3  * *
4  * SPDX-License-Identifier: LGPL-2.0-or-later *
5  ***************************************************************************/
6 
7 #include "session.h"
8 
9 #include <private/standarddirs_p.h>
10 
11 #include <QCoreApplication>
12 #include <QFile>
13 #include <QSettings>
14 #include <QSocketNotifier>
15 
16 #include <fcntl.h>
17 #include <iostream>
18 #include <unistd.h>
19 
20 Session::Session(const QString &input, QObject *parent)
21  : QObject(parent)
22 {
23  auto file = new QFile(this);
24  if (input != QLatin1String("-")) {
25  file->setFileName(input);
26  if (!file->open(QFile::ReadOnly)) {
27  qFatal("Failed to open %s", qPrintable(input));
28  }
29  } else {
30  // ### does that work on Windows?
31  const int flags = fcntl(0, F_GETFL);
32  fcntl(0, F_SETFL, flags | O_NONBLOCK); // NOLINT(hicpp-signed-bitwise)
33 
34  if (!file->open(stdin, QFile::ReadOnly | QFile::Unbuffered)) {
35  qFatal("Failed to open stdin!");
36  }
37  m_notifier = new QSocketNotifier(0, QSocketNotifier::Read, this);
38  connect(m_notifier, &QSocketNotifier::activated, this, &Session::inputAvailable);
39  }
40  m_input = file;
41 }
42 
44 {
45 }
46 
47 void Session::connectToHost()
48 {
49  const QSettings connectionSettings(Akonadi::StandardDirs::connectionConfigFile(), QSettings::IniFormat);
50 
51  QString serverAddress;
52 #ifdef Q_OS_WIN
53  serverAddress = connectionSettings.value(QStringLiteral("Data/NamedPipe"), QString()).toString();
54 #else
55  serverAddress = connectionSettings.value(QStringLiteral("Data/UnixPath"), QString()).toString();
56 #endif
57  if (serverAddress.isEmpty()) {
58  qFatal("Unable to determine server address.");
59  }
60 
61  auto socket = new QLocalSocket(this);
62  connect(socket, &QLocalSocket::errorOccurred, this, &Session::serverError);
63  connect(socket, &QLocalSocket::disconnected, this, &Session::serverDisconnected);
64  connect(socket, &QIODevice::readyRead, this, &Session::serverRead);
65  connect(socket, &QLocalSocket::connected, this, &Session::inputAvailable);
66 
67  m_session = socket;
68  socket->connectToServer(serverAddress);
69 
70  m_connectionTime.start();
71 }
72 
73 void Session::inputAvailable()
74 {
75  if (!m_session->isOpen()) {
76  return;
77  }
78 
79  if (m_notifier) {
80  m_notifier->setEnabled(false);
81  }
82 
83  if (m_input->atEnd()) {
84  return;
85  }
86 
87  QByteArray buffer(1024, Qt::Uninitialized);
88  qint64 readSize = 0;
89 
90  while ((readSize = m_input->read(buffer.data(), buffer.size())) > 0) {
91  m_session->write(buffer.constData(), readSize);
92  m_sentBytes += readSize;
93  }
94 
95  if (m_notifier) {
96  m_notifier->setEnabled(true);
97  }
98 }
99 
100 void Session::serverDisconnected()
101 {
103 }
104 
105 void Session::serverError(QLocalSocket::LocalSocketError socketError)
106 {
107  if (socketError == QLocalSocket::PeerClosedError) {
109  return;
110  }
111 
112  std::cerr << qPrintable(m_session->errorString());
114 }
115 
116 void Session::serverRead()
117 {
118  QByteArray buffer(1024, Qt::Uninitialized);
119  qint64 readSize = 0;
120 
121  while ((readSize = m_session->read(buffer.data(), buffer.size())) > 0) {
122  write(1, buffer.data(), readSize);
123  m_receivedBytes += readSize;
124  }
125 }
126 
127 void Session::printStats() const
128 {
129  std::cerr << "Connection time: " << m_connectionTime.elapsed() << " ms" << std::endl;
130  std::cerr << "Sent: " << m_sentBytes << " bytes" << std::endl;
131  std::cerr << "Received: " << m_receivedBytes << " bytes" << std::endl;
132 }
void exit(int returnCode)
void connected()
void errorOccurred(QLocalSocket::LocalSocketError socketError)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool isEmpty() const const
void disconnected()
void readyRead()
~Session() override
Destroys the session.
void activated(QSocketDescriptor socket, QSocketNotifier::Type type)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Mar 22 2023 03:56:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.