summaryrefslogtreecommitdiff
path: root/server/connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/connection.c')
-rw-r--r--server/connection.c151
1 files changed, 84 insertions, 67 deletions
diff --git a/server/connection.c b/server/connection.c
index 762d184..38ba214 100644
--- a/server/connection.c
+++ b/server/connection.c
@@ -1,5 +1,5 @@
/*
- * $Id: connection.c,v 1.3 2005/03/24 21:31:38 lordjaxom Exp $
+ * $Id: connection.c,v 1.4 2005/05/09 20:22:29 lordjaxom Exp $
*/
#include "server/connection.h"
@@ -11,96 +11,113 @@
#include <string.h>
#include <errno.h>
-cServerConnection::cServerConnection(const char *Protocol) {
- m_RdBytes = 0;
- m_WrBytes = 0;
- m_WrOffs = 0;
- m_DeferClose = false;
- m_Protocol = Protocol;
+cServerConnection::cServerConnection(const char *Protocol):
+ m_Protocol(Protocol),
+ m_DeferClose(false),
+ m_Pending(false),
+ m_ReadBytes(0),
+ m_WriteBytes(0),
+ m_WriteIndex(0)
+{
}
-cServerConnection::~cServerConnection() {
+cServerConnection::~cServerConnection()
+{
}
-bool cServerConnection::CanAct(const cTBSelect &Select) {
- if (Select.CanRead(*this)) {
- int b;
- if ((b = Read(m_RdBuf + m_RdBytes, sizeof(m_RdBuf) - m_RdBytes - 1)) < 0) {
- esyslog("Streamdev: Read from client (%s) %s:%d failed: %s", m_Protocol,
- RemoteIp().c_str(), RemotePort(), strerror(errno));
- return false;
- }
-
- if (b == 0) {
- isyslog("Streamdev: Client (%s) %s:%d closed connection", m_Protocol,
- RemoteIp().c_str(), RemotePort());
- return false;
- }
+bool cServerConnection::Read(void)
+{
+ int b;
+ if ((b = cTBSocket::Read(m_ReadBuffer + m_ReadBytes,
+ sizeof(m_ReadBuffer) - m_ReadBytes - 1)) < 0) {
+ esyslog("ERROR: read from client (%s) %s:%d failed: %m",
+ m_Protocol, RemoteIp().c_str(), RemotePort());
+ return false;
+ }
- m_RdBytes += b;
- m_RdBuf[m_RdBytes] = '\0';
- return ParseBuffer();
+ if (b == 0) {
+ isyslog("client (%s) %s:%d has closed connection",
+ m_Protocol, RemoteIp().c_str(), RemotePort());
+ return false;
}
- if (Select.CanWrite(*this)) {
- int b;
- if ((b = Write(m_WrBuf + m_WrOffs, m_WrBytes - m_WrOffs)) < 0) {
- esyslog("Streamdev: Write to client (%s) %s:%d failed: %s", m_Protocol,
- RemoteIp().c_str(), RemotePort(), strerror(errno));
+ m_ReadBytes += b;
+ m_ReadBuffer[m_ReadBytes] = '\0';
+
+ char *end;
+ bool result = true;
+ while ((end = strchr(m_ReadBuffer, '\012')) != NULL) {
+ *end = '\0';
+ if (end > m_ReadBuffer && *(end - 1) == '\015')
+ *(end - 1) = '\0';
+
+ if (!Command(m_ReadBuffer))
return false;
- }
- m_WrOffs += b;
- if (m_WrOffs == m_WrBytes) {
- m_WrBytes = 0;
- m_WrOffs = 0;
- }
+ m_ReadBytes -= ++end - m_ReadBuffer;
+ if (m_ReadBytes > 0)
+ memmove(m_ReadBuffer, end, m_ReadBytes);
}
- if (m_WrBytes == 0) {
- if (m_DeferClose)
- return false;
- Flushed();
+ if (m_ReadBytes == sizeof(m_ReadBuffer) - 1) {
+ esyslog("ERROR: streamdev: input buffer overflow (%s) for %s:%d",
+ m_Protocol, RemoteIp().c_str(), RemotePort());
+ return false;
}
- return true;
+
+ return result;
}
-bool cServerConnection::ParseBuffer(void) {
- char *ep;
- bool res;
-
- while ((ep = strchr(m_RdBuf, '\012')) != NULL) {
- *ep = '\0';
- if (ep > m_RdBuf && *(ep-1) == '\015')
- *(ep-1) = '\0';
-
- Dprintf("IN: |%s|\n", m_RdBuf);
- res = Command(m_RdBuf);
- m_RdBytes -= ++ep - m_RdBuf;
- if (m_RdBytes > 0)
- memmove(m_RdBuf, ep, m_RdBytes);
- if (res == false)
+bool cServerConnection::Write(void)
+{
+ int b;
+ if ((b = cTBSocket::Write(m_WriteBuffer + m_WriteIndex,
+ m_WriteBytes - m_WriteIndex)) < 0) {
+ esyslog("ERROR: streamdev: write to client (%s) %s:%d failed: %m",
+ m_Protocol, RemoteIp().c_str(), RemotePort());
+ return false;
+ }
+
+ m_WriteIndex += b;
+ if (m_WriteIndex == m_WriteBytes) {
+ m_WriteIndex = 0;
+ m_WriteBytes = 0;
+ if (m_Pending)
+ Command(NULL);
+ if (m_DeferClose)
return false;
+ Flushed();
}
return true;
}
-bool cServerConnection::Respond(const std::string &Message) {
- if (m_WrBytes + Message.size() + 2 > sizeof(m_WrBuf)) {
- esyslog("Streamdev: Output buffer overflow (%s) for %s:%d", m_Protocol,
- RemoteIp().c_str(), RemotePort());
+bool cServerConnection::Respond(const char *Message, bool Last, ...)
+{
+ char *buffer;
+ int length;
+ va_list ap;
+ va_start(ap, Last);
+ length = vasprintf(&buffer, Message, ap);
+ va_end(ap);
+
+ if (m_WriteBytes + length + 2 > sizeof(m_WriteBuffer)) {
+ esyslog("ERROR: streamdev: output buffer overflow (%s) for %s:%d",
+ m_Protocol, RemoteIp().c_str(), RemotePort());
return false;
}
- Dprintf("OUT: |%s|\n", Message.c_str());
- memcpy(m_WrBuf + m_WrBytes, Message.c_str(), Message.size());
-
- m_WrBytes += Message.size();
- m_WrBuf[m_WrBytes++] = '\015';
- m_WrBuf[m_WrBytes++] = '\012';
+ Dprintf("OUT: |%s|\n", buffer);
+ memcpy(m_WriteBuffer + m_WriteBytes, buffer, length);
+ free(buffer);
+
+ m_WriteBytes += length;
+ m_WriteBuffer[m_WriteBytes++] = '\015';
+ m_WriteBuffer[m_WriteBytes++] = '\012';
+ m_Pending = !Last;
return true;
}
-cDevice *cServerConnection::GetDevice(const cChannel *Channel, int Priority) {
+cDevice *cServerConnection::GetDevice(const cChannel *Channel, int Priority)
+{
cDevice *device = NULL;
/*Dprintf("+ Statistics:\n");