00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <config.h>
00024
00025
#include <ksock.h>
00026
#include <qtimer.h>
00027
00028
#include <sys/types.h>
00029
#include <sys/signal.h>
00030
#include <sys/time.h>
00031
00032
#include <errno.h>
00033
#include <fcntl.h>
00034
#include <stdio.h>
00035
#include <stdlib.h>
00036
#include <signal.h>
00037
#include <string.h>
00038
#include <unistd.h>
00039
00040
#include "kio/connection.h"
00041
00042
#include <kdebug.h>
00043
#include <qsocketnotifier.h>
00044
00045
using namespace KIO;
00046
00047 Connection::Connection()
00048 {
00049 f_out = 0;
00050 fd_in = -1;
00051 socket = 0;
00052 notifier = 0;
00053 receiver = 0;
00054 member = 0;
00055 m_suspended =
false;
00056 tasks.setAutoDelete(
true);
00057 }
00058
00059 Connection::~Connection()
00060 {
00061
close();
00062 }
00063
00064 void Connection::suspend()
00065 {
00066 m_suspended =
true;
00067
if (notifier)
00068 notifier->setEnabled(
false);
00069 }
00070
00071 void Connection::resume()
00072 {
00073 m_suspended =
false;
00074
if (notifier)
00075 notifier->setEnabled(
true);
00076 }
00077
00078 void Connection::close()
00079 {
00080
delete notifier;
00081 notifier = 0;
00082
delete socket;
00083 socket = 0;
00084
00085
00086 f_out = 0;
00087 fd_in = -1;
00088 tasks.clear();
00089 }
00090
00091 void Connection::send(
int cmd,
const QByteArray& data)
00092 {
00093
if (!
inited() || tasks.count() > 0) {
00094 Task *task =
new Task();
00095 task->cmd = cmd;
00096 task->data = data;
00097 tasks.append(task);
00098 }
else {
00099
sendnow( cmd, data );
00100 }
00101 }
00102
00103
void Connection::dequeue()
00104 {
00105
if (!
inited())
00106
return;
00107
00108
while (tasks.count())
00109 {
00110 tasks.first();
00111 Task *task = tasks.take();
00112
sendnow( task->cmd, task->data );
00113
delete task;
00114 }
00115 }
00116
00117 void Connection::init(
KSocket *sock)
00118 {
00119
delete notifier;
00120 notifier = 0;
00121
delete socket;
00122 socket = sock;
00123 fd_in = socket->
socket();
00124 f_out = fdopen( socket->
socket(),
"wb" );
00125
if (receiver && ( fd_in != -1 )) {
00126 notifier =
new QSocketNotifier(fd_in, QSocketNotifier::Read);
00127
if ( m_suspended ) {
00128
suspend();
00129 }
00130 QObject::connect(notifier, SIGNAL(activated(
int)), receiver, member);
00131 }
00132 dequeue();
00133 }
00134
00135 void Connection::init(
int _fd_in,
int fd_out)
00136 {
00137
delete notifier;
00138 notifier = 0;
00139 fd_in = _fd_in;
00140 f_out = fdopen( fd_out,
"wb" );
00141
if (receiver && ( fd_in != -1 )) {
00142 notifier =
new QSocketNotifier(fd_in, QSocketNotifier::Read);
00143
if ( m_suspended ) {
00144
suspend();
00145 }
00146 QObject::connect(notifier, SIGNAL(activated(
int)), receiver, member);
00147 }
00148 dequeue();
00149 }
00150
00151
00152
void Connection::connect(
QObject *_receiver,
const char *_member)
00153 {
00154 receiver = _receiver;
00155 member = _member;
00156
delete notifier;
00157 notifier = 0;
00158
if (receiver && (fd_in != -1 )) {
00159 notifier =
new QSocketNotifier(fd_in, QSocketNotifier::Read);
00160
if ( m_suspended )
00161
suspend();
00162 QObject::connect(notifier, SIGNAL(activated(
int)), receiver, member);
00163 }
00164 }
00165
00166 bool Connection::sendnow(
int _cmd,
const QByteArray &data )
00167 {
00168
if (f_out == 0) {
00169
return false;
00170 }
00171
00172
if (data.size() > 0xffffff)
00173
return false;
00174
00175
static char buffer[ 64 ];
00176 sprintf( buffer,
"%6x_%2x_", data.size(), _cmd );
00177
00178 size_t n = fwrite( buffer, 1, 10, f_out );
00179
00180
if ( n != 10 ) {
00181
kdError(7017) <<
"Could not send header" <<
endl;
00182
return false;
00183 }
00184
00185 n = fwrite( data.data(), 1, data.size(), f_out );
00186
00187
if ( n != data.size() ) {
00188
kdError(7017) <<
"Could not write data" <<
endl;
00189
return false;
00190 }
00191
00192 fflush( f_out );
00193
00194
return true;
00195 }
00196
00197 int Connection::read(
int* _cmd,
QByteArray &data )
00198 {
00199
if (fd_in == -1 ) {
00200
kdError(7017) <<
"read: not yet inited" <<
endl;
00201
return -1;
00202 }
00203
00204
static char buffer[ 10 ];
00205
00206 again1:
00207 ssize_t n = ::read( fd_in, buffer, 10);
00208
if ( n == -1 && errno == EINTR )
00209
goto again1;
00210
00211
if ( n == -1) {
00212
kdError(7017) <<
"Header read failed, errno=" << errno <<
endl;
00213 }
00214
00215
if ( n != 10 ) {
00216
if ( n )
00217
kdError(7017) <<
"Header has invalid size (" << n <<
")" <<
endl;
00218
return -1;
00219 }
00220
00221 buffer[ 6 ] = 0;
00222 buffer[ 9 ] = 0;
00223
00224
char *p = buffer;
00225
while( *p ==
' ' ) p++;
00226
long int len = strtol( p, 0L, 16 );
00227
00228 p = buffer + 7;
00229
while( *p ==
' ' ) p++;
00230
long int cmd = strtol( p, 0L, 16 );
00231
00232 data.resize( len );
00233
00234
if ( len > 0L ) {
00235 size_t bytesToGo = len;
00236 size_t bytesRead = 0;
00237
do {
00238 n = ::read(fd_in, data.data()+bytesRead, bytesToGo);
00239
if (n == -1) {
00240
if (errno == EINTR)
00241
continue;
00242
00243
kdError(7017) <<
"Data read failed, errno=" << errno <<
endl;
00244
return -1;
00245 }
00246
00247 bytesRead += n;
00248 bytesToGo -= n;
00249 }
00250
while(bytesToGo);
00251 }
00252
00253 *_cmd = cmd;
00254
return len;
00255 }
00256
00257
#include "connection.moc"