You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
315 lines
8.4 KiB
315 lines
8.4 KiB
/*
|
|
* Copyright (C) 2005 by Linus McCabe, <Linus@McCabe.nu>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
#include "dbgpnetwork.h"
|
|
|
|
#include <kserversocket.h>
|
|
#include <kstreamsocket.h>
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
|
|
DBGpNetwork::DBGpNetwork()
|
|
: QObject()
|
|
{
|
|
m_socket = NULL;
|
|
m_server = NULL;
|
|
m_datalen = -1;
|
|
m_transaction_id = 0;
|
|
}
|
|
|
|
DBGpNetwork::~DBGpNetwork()
|
|
{
|
|
}
|
|
|
|
void DBGpNetwork::sessionStart(bool useproxy, const QString& server, const QString & service)
|
|
{
|
|
|
|
kdDebug(24002) << k_funcinfo << ", m_server: " << m_server << ", m_socket" << m_socket << endl;
|
|
m_useproxy = useproxy;
|
|
|
|
if(m_useproxy)
|
|
{
|
|
if(m_socket)
|
|
{
|
|
// m_socket->setBufferSize(-1);
|
|
connect(m_socket, SIGNAL(gotError(int)), this, SLOT(slotError(int)));
|
|
connect(m_socket, SIGNAL(connected(const KResolverEntry &)), this, SLOT(slotConnected(const KNetwork::KResolverEntry &)));
|
|
connect(m_socket, SIGNAL(closed()), this, SLOT(slotConnectionClosed()));
|
|
connect(m_socket, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
|
|
connect(m_socket, SIGNAL(destroyed()), this, SLOT(slotSocketDestroyed()));
|
|
m_socket->connect();
|
|
emit active(false);
|
|
kdDebug(24002) << k_funcinfo << ", proxy:" << server << ", " << service << endl;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(!m_server)
|
|
{
|
|
m_server = new KNetwork::KServerSocket(service);
|
|
|
|
m_server->setAddressReuseable(true);
|
|
connect(m_server, SIGNAL(readyAccept()), this, SLOT(slotReadyAccept()));
|
|
connect(m_server, SIGNAL(gotError(int)), this, SLOT(slotError(int)));
|
|
|
|
if(m_server->listen())
|
|
{
|
|
emit active(true);
|
|
emit networkError(i18n("Listening on port %1").arg(service), true);
|
|
}
|
|
else
|
|
{
|
|
delete m_server;
|
|
m_server = NULL;
|
|
emit active(false);
|
|
emit networkError(i18n("Unable to listen on port %1").arg(service), true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void DBGpNetwork::sessionEnd()
|
|
{
|
|
// Close socket
|
|
if(m_socket)
|
|
{
|
|
m_socket->flush();
|
|
disconnect(m_socket, SIGNAL(closed()), this, SLOT(slotConnectionClosed()));
|
|
if (m_socket)
|
|
m_socket->close();
|
|
delete m_socket;
|
|
m_socket = 0L;
|
|
}
|
|
|
|
// Close the server
|
|
if(m_server)
|
|
{
|
|
m_server->close();
|
|
delete m_server;
|
|
m_server = NULL;
|
|
}
|
|
|
|
// Fake a connection closed signal
|
|
slotConnectionClosed();
|
|
emit active(false);
|
|
}
|
|
|
|
|
|
// Socket errors
|
|
void DBGpNetwork::slotError(int)
|
|
{
|
|
kdDebug(24002) << k_funcinfo << ", m_server: " << m_server << ", m_socket" << m_socket << endl;
|
|
if(m_socket)
|
|
{
|
|
kdDebug(24002) << k_funcinfo << ", " << m_socket->errorString() << endl;
|
|
if(m_socket->error() == KNetwork::KSocketBase::RemotelyDisconnected)
|
|
{
|
|
slotConnectionClosed();
|
|
emit networkError(i18n("Disconnected from remote host"), true);
|
|
return;
|
|
}
|
|
|
|
if(m_socket->error())
|
|
{
|
|
emit networkError(m_socket->errorString(), true);
|
|
}
|
|
}
|
|
|
|
if(m_server && m_server->error())
|
|
{
|
|
kdDebug(24002) << k_funcinfo << ", " << m_server->errorString() << endl;
|
|
emit networkError(m_server->errorString(), true);
|
|
}
|
|
}
|
|
|
|
// slotReadyAccept
|
|
void DBGpNetwork::slotReadyAccept()
|
|
{
|
|
|
|
kdDebug(24002) << k_funcinfo << ", m_server: " << m_server << ", m_socket" << m_socket << endl;
|
|
if(!m_socket)
|
|
{
|
|
disconnect(m_server, SIGNAL(readyAccept()), this, SLOT(slotReadyAccept()));
|
|
|
|
m_socket = (KNetwork::KStreamSocket *)m_server->accept(); // KSocketServer returns a KStreamSocket (!)
|
|
if(m_socket)
|
|
{
|
|
kdDebug(24002) << k_funcinfo << ", ready" << ", m_socket" << m_socket << endl;
|
|
m_socket->enableRead(true);
|
|
m_socket->setAddressReuseable(true);
|
|
// m_socket->setSocketFlags(KExtendedSocket::inetSocket | KExtendedSocket::inputBufferedSocket);
|
|
// m_socket->setBufferSize(-1);
|
|
connect(m_socket, SIGNAL(gotError(int)), this, SLOT(slotError(int)));
|
|
connect(m_socket, SIGNAL(connected(const KResolverEntry &)), this, SLOT(slotConnected(const KResolverEntry &)));
|
|
connect(m_socket, SIGNAL(closed()), this, SLOT(slotConnectionClosed()));
|
|
connect(m_socket, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
|
|
connected();
|
|
}
|
|
else
|
|
{
|
|
kdDebug(24002) << k_funcinfo << ", " << m_server->errorString() << endl;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Connection established
|
|
void DBGpNetwork::slotConnected(const KResolverEntry &)
|
|
{
|
|
connected();
|
|
}
|
|
|
|
bool DBGpNetwork::isConnected()
|
|
{
|
|
return m_socket != NULL && m_socket->state() == KNetwork::KClientSocketBase::Connected;
|
|
}
|
|
|
|
bool DBGpNetwork::isActive()
|
|
{
|
|
return
|
|
(m_socket != NULL && m_socket->state() == KNetwork::KClientSocketBase::Connected)
|
|
|| (m_server != NULL);
|
|
}
|
|
|
|
void DBGpNetwork::connected()
|
|
{
|
|
|
|
kdDebug(24002) << k_funcinfo << endl;
|
|
emit connected(true);
|
|
// debuggerInterface()->enableAction("debug_disconnect", true);
|
|
// debuggerInterface()->enableAction("debug_request", false);
|
|
}
|
|
|
|
// Connectio closed
|
|
void DBGpNetwork::slotConnectionClosed()
|
|
{
|
|
kdDebug(24002) << k_funcinfo << ", m_server: " << m_server << ", m_socket" << m_socket << endl;
|
|
|
|
// Check if we have more data to read
|
|
slotReadyRead();
|
|
// kdDebug(24002) << k_funcinfo << "buffer: " << m_buffer << endl;
|
|
|
|
if(m_socket)
|
|
{
|
|
m_socket->flush();
|
|
m_socket->close();
|
|
delete m_socket;
|
|
m_socket = NULL;
|
|
}
|
|
|
|
if(m_server)
|
|
connect(m_server, SIGNAL(readyAccept()), this, SLOT(slotReadyAccept()));
|
|
|
|
// Disable all session related actions and enable connection action
|
|
emit connected(false);
|
|
emit active(m_server != NULL);
|
|
|
|
}
|
|
|
|
|
|
//called when m_socket is destroyed either by deleting it or if XDebug disconnects from the client
|
|
void DBGpNetwork::slotSocketDestroyed()
|
|
{
|
|
kdDebug(24002) << k_funcinfo << " , m_server: " << m_server << ", m_socket" << m_socket << endl;
|
|
|
|
m_socket = NULL; //m_socket is already wrong, without this the app would crash on the next m_socket->close() or delete m_socket call.
|
|
slotConnectionClosed();
|
|
}
|
|
|
|
|
|
// Data from socket
|
|
void DBGpNetwork::slotReadyRead()
|
|
{
|
|
|
|
// Data from dbgp
|
|
while(m_socket && (m_socket->bytesAvailable() > 0 || m_fifo.length() >= (unsigned long)m_datalen))
|
|
{
|
|
int bytes;
|
|
QString data;
|
|
|
|
if(m_socket && m_socket->bytesAvailable() > 0 )
|
|
{
|
|
// Read all available bytes from socket and append them to the buffer
|
|
bytes = m_socket->bytesAvailable();
|
|
char* buffer = new char[bytes];
|
|
m_socket->readBlock(buffer, bytes);
|
|
|
|
// Put it in the fifo buffer
|
|
m_fifo.append(buffer, bytes);
|
|
|
|
delete[] buffer;
|
|
}
|
|
|
|
while(1)
|
|
{
|
|
// If datalen == -1, we didnt read the size yet, otherwise we're reading data.
|
|
if(m_datalen == -1)
|
|
{
|
|
bytes = m_fifo.find('\0');
|
|
if(bytes < 0)
|
|
break;
|
|
|
|
data = m_fifo.retrieve();
|
|
m_datalen = data.toLong();
|
|
|
|
}
|
|
if(m_datalen != -1 && (long)m_fifo.length() >= m_datalen + 1)
|
|
{
|
|
data = m_fifo.retrieve();
|
|
m_datalen = -1;
|
|
emit command(data);
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
long DBGpNetwork::sendCommand(const QString & command)
|
|
{
|
|
return sendCommand(command, "");
|
|
}
|
|
|
|
long DBGpNetwork::sendCommand(const QString & command, const QString & arguments)
|
|
{
|
|
if(!isConnected())
|
|
return false;
|
|
|
|
m_transaction_id++;
|
|
QString commandline = command + QString(" -i %1").arg(m_transaction_id) + (!arguments.isEmpty() ? " " : "") + arguments;
|
|
|
|
kdDebug(24002) << k_funcinfo << ", sending: " << commandline << endl;
|
|
|
|
m_socket->writeBlock(commandline.latin1(), commandline.length() + 1); // Send string + NULL termination
|
|
|
|
return m_transaction_id;
|
|
}
|
|
|
|
long DBGpNetwork::sendCommand( const QString & command, const QString & arguments, const QString & data )
|
|
{
|
|
QByteArrayFifo buffer;
|
|
buffer.append(data.ascii(), data.length());
|
|
return sendCommand(command, arguments + " -- " + buffer.base64Encoded());
|
|
}
|
|
|
|
// #include "dbgpnetwork.moc"
|
|
|
|
#include "dbgpnetwork.moc"
|