mirror of
https://github.com/anope/anope.git
synced 2026-06-25 10:16:39 +02:00
182 lines
3.6 KiB
C++
182 lines
3.6 KiB
C++
// Anope IRC Services <https://www.anope.org/>
|
|
//
|
|
// Copyright (C) 2003-2026 Anope Contributors
|
|
//
|
|
// Anope is free software. You can use, modify, and/or distribute it under the
|
|
// terms of version 2 of the GNU General Public License. See docs/LICENSE.txt
|
|
// for the complete terms of this license and docs/AUTHORS.txt for a list of
|
|
// contributors.
|
|
//
|
|
// Based on the original code of Epona by Lara
|
|
// Based on the original code of Services by Andy Church
|
|
//
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
#include "services.h"
|
|
#include "sockets.h"
|
|
#include "socketengine.h"
|
|
#include "textproc.h"
|
|
|
|
#define NET_BUFSIZE 65535
|
|
|
|
bool BufferedSocket::ProcessRead()
|
|
{
|
|
char tbuffer[NET_BUFSIZE];
|
|
|
|
this->recv_len = 0;
|
|
|
|
int len = this->io->Recv(this, tbuffer, sizeof(tbuffer) - 1);
|
|
if (len == 0)
|
|
return false;
|
|
if (len < 0)
|
|
return SocketEngine::IgnoreErrno();
|
|
|
|
tbuffer[len] = 0;
|
|
this->read_buffer.append(tbuffer);
|
|
this->recv_len = len;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool BufferedSocket::ProcessWrite()
|
|
{
|
|
if (this->write_buffer.empty())
|
|
return true;
|
|
|
|
int count = this->io->Send(this, this->write_buffer);
|
|
if (count == 0)
|
|
return false;
|
|
if (count < 0)
|
|
return SocketEngine::IgnoreErrno();
|
|
|
|
this->write_buffer = this->write_buffer.substr(count);
|
|
if (this->write_buffer.empty())
|
|
SocketEngine::Change(this, false, SF_WRITABLE);
|
|
|
|
return true;
|
|
}
|
|
|
|
Anope::string BufferedSocket::GetLine()
|
|
{
|
|
size_t s = this->read_buffer.find('\n');
|
|
if (s == Anope::string::npos)
|
|
return "";
|
|
Anope::string str = this->read_buffer.substr(0, s + 1);
|
|
this->read_buffer.erase(0, s + 1);
|
|
this->read_buffer.ltrim("\r\n");
|
|
return str.trim("\r\n");
|
|
}
|
|
|
|
void BufferedSocket::Write(const char *buffer, size_t l)
|
|
{
|
|
this->write_buffer += buffer + Anope::string("\r\n");
|
|
SocketEngine::Change(this, true, SF_WRITABLE);
|
|
}
|
|
|
|
void BufferedSocket::Write(const char *message, ...)
|
|
{
|
|
if (!message)
|
|
return;
|
|
|
|
Anope::string tbuffer;
|
|
ANOPE_FORMAT(message, message, tbuffer);
|
|
this->Write(tbuffer.c_str(), tbuffer.length());
|
|
}
|
|
|
|
void BufferedSocket::Write(const Anope::string &message)
|
|
{
|
|
this->Write(message.c_str(), message.length());
|
|
}
|
|
|
|
int BufferedSocket::ReadBufferLen() const
|
|
{
|
|
return recv_len;
|
|
}
|
|
|
|
int BufferedSocket::WriteBufferLen() const
|
|
{
|
|
return this->write_buffer.length();
|
|
}
|
|
|
|
|
|
BinarySocket::DataBlock::DataBlock(const char *b, size_t l)
|
|
{
|
|
this->orig = this->buf = new char[l];
|
|
memcpy(this->buf, b, l);
|
|
this->len = l;
|
|
}
|
|
|
|
BinarySocket::DataBlock::~DataBlock()
|
|
{
|
|
delete [] this->orig;
|
|
}
|
|
|
|
bool BinarySocket::ProcessRead()
|
|
{
|
|
char tbuffer[NET_BUFSIZE];
|
|
|
|
int len = this->io->Recv(this, tbuffer, sizeof(tbuffer));
|
|
if (len <= 0)
|
|
return false;
|
|
|
|
return this->Read(tbuffer, len);
|
|
}
|
|
|
|
bool BinarySocket::ProcessWrite()
|
|
{
|
|
if (this->write_buffer.empty())
|
|
{
|
|
SocketEngine::Change(this, false, SF_WRITABLE);
|
|
return true;
|
|
}
|
|
|
|
DataBlock *d = this->write_buffer.front();
|
|
|
|
int len = this->io->Send(this, d->buf, d->len);
|
|
if (len <= -1)
|
|
return false;
|
|
else if (static_cast<size_t>(len) == d->len)
|
|
{
|
|
delete d;
|
|
this->write_buffer.pop_front();
|
|
}
|
|
else
|
|
{
|
|
d->buf += len;
|
|
d->len -= len;
|
|
}
|
|
|
|
if (this->write_buffer.empty())
|
|
SocketEngine::Change(this, false, SF_WRITABLE);
|
|
|
|
return true;
|
|
}
|
|
|
|
void BinarySocket::Write(const char *buffer, size_t l)
|
|
{
|
|
if (l == 0)
|
|
return;
|
|
this->write_buffer.push_back(new DataBlock(buffer, l));
|
|
SocketEngine::Change(this, true, SF_WRITABLE);
|
|
}
|
|
|
|
void BinarySocket::Write(const char *message, ...)
|
|
{
|
|
if (!message)
|
|
return;
|
|
|
|
Anope::string tbuffer;
|
|
ANOPE_FORMAT(message, message, tbuffer);
|
|
this->Write(tbuffer.c_str(), tbuffer.length());
|
|
}
|
|
|
|
void BinarySocket::Write(const Anope::string &message)
|
|
{
|
|
this->Write(message.c_str(), message.length());
|
|
}
|
|
|
|
bool BinarySocket::Read(const char *buffer, size_t l)
|
|
{
|
|
return true;
|
|
}
|