ollie/kde/gui/ninep.h

92 lines
2.7 KiB
C++

/*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* NineP — a minimal, synchronous 9P2000 client over a Unix-domain socket.
*
* Just enough protocol to talk to a plan9port plumber: version negotiation,
* attach, walk, open, read and write. No auth (plumber accepts NOFID afid),
* no create/remove/stat. All little-endian, matching plan9port fcall.h.
*/
#ifndef OLLIE_NINEP_H
#define OLLIE_NINEP_H
#include <QByteArray>
#include <QString>
#include <cstdint>
class QLocalSocket;
/*!
* One synchronous 9P2000 session. Not thread-safe; create one per thread.
*/
class NineP
{
public:
NineP();
~NineP();
NineP(const NineP &) = delete;
NineP &operator=(const NineP &) = delete;
/*!
* Connect to \a socketPath, negotiate 9P2000, and attach as \a user.
* Returns true on success. On failure, errorString() explains why.
*/
bool connectAndAttach(const QString &socketPath, const QString &user,
const QString &aname = QString());
bool isConnected() const;
void close();
/*!
* Walk from the attached root to \a name (single path element)
* binding \a newFid to it. Returns true on success.
*/
bool walk(uint32_t newFid, const QString &name);
/*! Open \a fid with the given 9P \a mode (OREAD=0, OWRITE=1, ORDWR=2). */
bool open(uint32_t fid, uint8_t mode);
/*!
* Write \a data to \a fid at \a offset. Returns bytes accepted, or -1.
*/
int write(uint32_t fid, uint64_t offset, const QByteArray &data);
/*!
* Read up to \a count bytes from \a fid at \a offset. Returns bytes read
* (0 at EOF), or -1 on error. Blocks until server responds.
*/
int read(uint32_t fid, uint64_t offset, uint32_t count, QByteArray *out);
/*!
* Send Tread without waiting for reply. Used with recvReadReply() for
* cancellable blocking reads on edit port.
*/
bool beginRead(uint32_t fid, uint64_t offset, uint32_t count);
/*!
* Wait up to \a firstByteTimeoutMs for Rread reply. Returns byte count
* (>=0), 0 with \a timedOut set when nothing arrived, or -1 on error.
*/
int recvReadReply(QByteArray *out, int firstByteTimeoutMs, bool *timedOut);
bool clunk(uint32_t fid);
uint32_t msize() const { return m_msize; }
QString errorString() const { return m_error; }
enum OpenMode : uint8_t { OREAD = 0, OWRITE = 1, ORDWR = 2 };
static constexpr uint32_t RootFid = 0;
private:
bool sendMsg(uint8_t type, uint16_t tag, const QByteArray &body);
bool recvMsg(uint8_t *type, uint16_t *tag, QByteArray *body);
bool readExactly(char *buf, int n);
QLocalSocket *m_sock = nullptr;
uint32_t m_msize = 8192;
QString m_error;
};
#endif