31 #include <sys/types.h>
36 #include <dcopclient.h>
38 #include <tdelocale.h>
39 #include <tdeglobal.h>
40 #include <kstandarddirs.h>
41 #include <tdeapplication.h>
42 #include <tdetempfile.h>
45 #include <klibloader.h>
47 #include "tdeio/dataprotocol.h"
48 #include "tdeio/slave.h"
49 #include "tdeio/kservice.h"
50 #include <tdeio/global.h>
51 #include <tdeprotocolmanager.h>
52 #include <kprotocolinfo.h>
59 #define _PATH_TMP "/tmp"
62 using namespace TDEIO;
64 #define SLAVE_CONNECTION_TIMEOUT_MIN 2
71 #define SLAVE_CONNECTION_TIMEOUT_MAX 10
73 #define SLAVE_CONNECTION_TIMEOUT_MAX 3600
86 SlavePrivate(
bool derived) : derived(derived) {}
90 void Slave::accept(TDESocket *socket)
93 slaveconn.
init(socket);
97 slaveconn.connect(
this, TQ_SLOT(gotInput()));
101 void Slave::unlinkSocket()
103 if (m_socket.isEmpty())
return;
104 TQCString filename = TQFile::encodeName(m_socket);
105 unlink(filename.data());
106 m_socket = TQString::null;
109 void Slave::timeout()
112 kdDebug(7002) <<
"slave failed to connect to application pid=" << m_pid <<
" protocol=" << m_protocol << endl;
113 if (m_pid && (::
kill(m_pid, 0) == 0))
115 int delta_t = (int) difftime(time(0), contact_started);
116 kdDebug(7002) <<
"slave is slow... pid=" << m_pid <<
" t=" << delta_t << endl;
117 if (delta_t < SLAVE_CONNECTION_TIMEOUT_MAX)
119 TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN,
this, TQ_SLOT(timeout()));
123 kdDebug(7002) <<
"Houston, we lost our slave, pid=" << m_pid << endl;
128 TQString arg = m_protocol;
129 if (!m_host.isEmpty())
131 kdDebug(7002) <<
"slave died pid = " << m_pid << endl;
134 emit error(ERR_SLAVE_DIED, arg);
136 emit slaveDied(
this);
141 Slave::Slave(TDEServerSocket *socket,
const TQString &protocol,
const TQString &socketname)
143 d(new SlavePrivate(false))
146 m_protocol = protocol;
147 m_slaveProtocol = protocol;
148 m_socket = socketname;
150 contact_started = time(0);
151 idle_since = contact_started;
155 connect(serv, TQ_SIGNAL(accepted( TDESocket* )),
156 TQ_SLOT(accept(TDESocket*) ) );
160 Slave::Slave(
bool , TDEServerSocket *socket,
const TQString &protocol,
161 const TQString &socketname)
163 d(new SlavePrivate(true))
169 m_socket = socketname;
171 contact_started = time(0);
172 idle_since = contact_started;
177 connect(serv, TQ_SIGNAL(accepted( TDESocket* )),
178 TQ_SLOT(accept(TDESocket*) ) );
196 void Slave::setProtocol(
const TQString & protocol)
203 idle_since = time(0);
208 return (time_t) difftime(time(0), idle_since);
211 void Slave::setPID(pid_t pid)
221 virtual_hook(VIRTUAL_HOLD, ¶ms);
228 TQDataStream stream( data, IO_WriteOnly );
230 slaveconn.
send( CMD_SLAVE_HOLD, data );
233 emit slaveDied(
this);
238 DCOPClient *client = kapp->dcopClient();
239 if (!client->isAttached())
242 TQByteArray params, reply;
244 TQDataStream stream(params, IO_WriteOnly);
248 TQCString launcher = TDEApplication::launcher();
249 client->call(launcher, launcher,
"waitForSlave(pid_t)",
250 params, replyType, reply);
257 virtual_hook(VIRTUAL_SUSPEND, 0);
267 virtual_hook(VIRTUAL_RESUME, 0);
277 SuspendedParams params;
278 virtual_hook(VIRTUAL_SUSPENDED, ¶ms);
279 return params.retval;
290 virtual_hook(VIRTUAL_SEND, ¶ms);
294 slaveconn.
send(cmd, arr);
297 void Slave::gotInput()
304 TQString arg = m_protocol;
305 if (!m_host.isEmpty())
307 kdDebug(7002) <<
"slave died pid = " << m_pid << endl;
309 emit error(ERR_SLAVE_DIED, arg);
311 emit slaveDied(
this);
320 kdDebug(7002) <<
"killing slave pid=" << m_pid <<
" (" << m_protocol <<
"://"
321 << m_host <<
")" << endl;
329 const TQString &user,
const TQString &passwd)
337 TQDataStream stream( data, IO_WriteOnly );
338 stream << m_host << m_port << m_user << m_passwd;
339 slaveconn.
send( CMD_HOST, data );
350 TQDataStream stream( data, IO_WriteOnly );
352 slaveconn.
send( CMD_CONFIG, data );
362 DCOPClient *client = kapp->dcopClient();
363 if (!client->isAttached())
366 TQString prefix = locateLocal(
"socket", TDEGlobal::instance()->instanceName());
367 KTempFile socketfile(prefix, TQString::fromLatin1(
".slave-socket"));
368 if ( socketfile.status() != 0 )
370 error_text = i18n(
"Unable to create io-slave: %1").arg(strerror(errno));
371 error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS;
380 TDEServerSocket *kss =
new TDEServerSocket(TQFile::encodeName(socketfile.name()).data());
394 static bool bForkSlaves = !TQCString(getenv(
"TDE_FORK_SLAVES")).isEmpty();
396 if (bForkSlaves || !client->isAttached() || client->isAttachedToForeignServer())
401 error_text = i18n(
"Unknown protocol '%1'.").arg(
protocol);
402 error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS;
406 TQString lib_path = KLibLoader::findLibrary(_name.latin1());
407 if (lib_path.isEmpty())
409 error_text = i18n(
"Can not find io-slave for protocol '%1'.").arg(
protocol);
410 error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS;
416 proc << locate(
"exe",
"tdeioslave") << lib_path <<
protocol <<
"" << socketfile.name();
417 kdDebug(7002) <<
"tdeioslave" <<
", " << lib_path <<
", " <<
protocol <<
", " << TQString::null <<
", " << socketfile.name() << endl;
419 proc.start(TDEProcess::DontCare);
422 slave->setPID(proc.pid());
423 TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, TQ_SLOT(timeout()));
429 TQByteArray params, reply;
431 TQDataStream stream(params, IO_WriteOnly);
432 stream <<
protocol << url.host() << socketfile.name();
434 TQCString launcher = TDEApplication::launcher();
435 if (!client->call(launcher, launcher,
"requestSlave(TQString,TQString,TQString)",
436 params, replyType, reply)) {
437 error_text = i18n(
"Cannot talk to tdelauncher");
438 error = TDEIO::ERR_SLAVE_DEFINED;
442 TQDataStream stream2(reply, IO_ReadOnly);
445 stream2 >> pid >> errorStr;
448 error_text = i18n(
"Unable to create io-slave:\ntdelauncher said: %1").arg(errorStr);
449 error = TDEIO::ERR_CANNOT_LAUNCH_PROCESS;
455 TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, TQ_SLOT(timeout()));
460 Slave* Slave::holdSlave(
const TQString &protocol,
const KURL& url )
467 DCOPClient *client = kapp->dcopClient();
468 if (!client->isAttached())
471 TQString prefix = locateLocal(
"socket", TDEGlobal::instance()->instanceName());
472 KTempFile socketfile(prefix, TQString::fromLatin1(
".slave-socket"));
473 if ( socketfile.status() != 0 )
482 TDEServerSocket *kss =
new TDEServerSocket(TQFile::encodeName(socketfile.name()).data());
489 TQByteArray params, reply;
491 TQDataStream stream(params, IO_WriteOnly);
492 stream << url << socketfile.name();
494 TQCString launcher = TDEApplication::launcher();
495 if (!client->call(launcher, launcher,
"requestHoldSlave(KURL,TQString)",
496 params, replyType, reply)) {
500 TQDataStream stream2(reply, IO_ReadOnly);
510 TQTimer::singleShot(1000*SLAVE_CONNECTION_TIMEOUT_MIN, slave, TQ_SLOT(timeout()));
515 void Slave::virtual_hook(
int id,
void* data ) {
516 TDEIO::SlaveInterface::virtual_hook(
id, data );
static TQString exec(const TQString &protocol)
Returns the library / executable to open for the protocol protocol Example : "tdeio_ftp",...
void resume()
Resume handling of incoming data.
void send(int cmd, const TQByteArray &arr=TQByteArray())
Sends/queues the given command to be sent.
void init(TDESocket *sock)
Initialize this connection to use the given socket.
void suspend()
Don't handle incoming data until resumed.
void close()
Closes the connection.
This tdeioslave provides support of data urls as specified by rfc 2397.
There are two classes that specifies the protocol between application (TDEIO::Job) and tdeioslave.
Attention developers: If you change the implementation of TDEIO::Slave, do not use connection() or sl...
bool suspended()
Tells wether the tdeioslave is suspended.
Slave(bool derived, TDEServerSocket *unixdomain, const TQString &protocol, const TQString &socketname)
Use this constructor if you derive your own class from Slave derived must be true in any case.
static Slave * createSlave(const TQString &protocol, const KURL &url, int &error, TQString &error_text)
Creates a new slave.
void suspend()
Suspends the operation of the attached tdeioslave.
void kill()
Force termination.
void setIdle()
Marks this slave as idle.
TQString protocol()
The protocol this slave handles.
void setHost(const TQString &host, int port, const TQString &user, const TQString &passwd)
Set host for url.
void hold(const KURL &url)
Puts the tdeioslave associated with url at halt.
void send(int cmd, const TQByteArray &data=TQByteArray())
Sends the given command to the tdeioslave.
void resume()
Resumes the operation of the attached tdeioslave.
void resetHost()
Clear host info.
void setConfig(const MetaData &config)
Configure slave.
A namespace for TDEIO globals.