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 <sys/types.h>
00026
#include <sys/stat.h>
00027
00028
#include <sys/socket.h>
00029
#include <sys/resource.h>
00030
#include <sys/time.h>
00031
#include <sys/un.h>
00032
#ifdef HAVE_SYS_SELECT_H
00033
#include <sys/select.h>
00034
#endif
00035
extern "C" {
00036
#include <netinet/in.h>
00037
00038
#include <arpa/inet.h>
00039 }
00040
00041
#define KSOCK_NO_BROKEN
00042
#include "kdebug.h"
00043
#include "ksock.h"
00044
#include "kextsock.h"
00045
#include "ksockaddr.h"
00046
00047
#include "ksocks.h"
00048
00049
extern "C" {
00050
#include <errno.h>
00051
#include <fcntl.h>
00052
00053
#ifdef HAVE_GETADDRINFO
00054
#include <netdb.h>
00055
#endif
00056
00057
00058
#include <arpa/nameser.h>
00059
#include <resolv.h>
00060 }
00061
#include <stdio.h>
00062
#include <stdlib.h>
00063
#include <string.h>
00064
#include <signal.h>
00065
#include <unistd.h>
00066
#include <assert.h>
00067
00068
#ifdef HAVE_SYSENT_H
00069
#include <sysent.h>
00070
#endif
00071
00072
#if TIME_WITH_SYS_TIME
00073
#include <time.h>
00074
#endif
00075
00076
00077
00078
#ifndef SOMAXCONN
00079
#warning Your header files do not seem to support SOMAXCONN
00080
#define SOMAXCONN 5
00081
#endif
00082
00083
#include <qapplication.h>
00084
#include <qsocketnotifier.h>
00085
00086
#include "netsupp.h"
00087
00088
class KSocketPrivate
00089 {
00090
public:
00091
QSocketNotifier *readNotifier;
00092
QSocketNotifier *writeNotifier;
00093
00094 KSocketPrivate() :
00095 readNotifier(0), writeNotifier(0)
00096 { }
00097 };
00098
00099
00100
00101 KSocket::KSocket(
int _sock)
00102 : sock(_sock), d(new KSocketPrivate)
00103 {
00104
struct sockaddr_in sin;
00105 ksocklen_t len =
sizeof(sin);
00106
00107 memset(&sin, 0, len);
00108
00109
00110
00111
00112 KSocks::self()->getsockname(_sock, (
struct sockaddr *)&sin, &len);
00113 }
00114
00115 KSocket::KSocket(
const char *_host,
unsigned short int _port,
int _timeout ) :
00116 sock( -1 ), d(new KSocketPrivate)
00117 {
00118 connect( _host, _port, _timeout );
00119 }
00120
00121 KSocket::KSocket(
const char *_path ) :
00122 sock( -1 ), d(new KSocketPrivate)
00123 {
00124 connect( _path );
00125 }
00126
00127
void KSocket::enableRead(
bool _state )
00128 {
00129
if ( _state )
00130 {
00131
if ( !d->readNotifier )
00132 {
00133 d->readNotifier =
new QSocketNotifier( sock, QSocketNotifier::Read );
00134 QObject::connect( d->readNotifier, SIGNAL( activated(
int) ),
this, SLOT( slotRead(
int) ) );
00135 }
00136
else
00137 d->readNotifier->setEnabled(
true );
00138 }
00139
else if ( d->readNotifier )
00140 d->readNotifier->setEnabled(
false );
00141 }
00142
00143
void KSocket::enableWrite(
bool _state )
00144 {
00145
if ( _state )
00146 {
00147
if ( !d->writeNotifier )
00148 {
00149 d->writeNotifier =
new QSocketNotifier( sock, QSocketNotifier::Write );
00150 QObject::connect( d->writeNotifier, SIGNAL( activated(
int) ),
this,
00151 SLOT( slotWrite(
int) ) );
00152 }
00153
else
00154 d->writeNotifier->setEnabled(
true );
00155 }
00156
else if ( d->writeNotifier )
00157 d->writeNotifier->setEnabled(
false );
00158 }
00159
00160
void KSocket::slotRead(
int )
00161 {
00162
char buffer[2];
00163
00164
int n = recv( sock, buffer, 1, MSG_PEEK );
00165
if ( n <= 0 )
00166 emit closeEvent(
this );
00167
else
00168 emit readEvent(
this );
00169 }
00170
00171
void KSocket::slotWrite(
int )
00172 {
00173 emit writeEvent(
this );
00174 }
00175
00176
00177
00178
00179
bool KSocket::connect(
const char *_path )
00180 {
00181 KExtendedSocket ks(QString::null, _path, KExtendedSocket::unixSocket);
00182
00183 ks.connect();
00184 sock = ks.fd();
00185 ks.release();
00186
00187
return sock >= 0;
00188 }
00189
00190
00191
00192
00193
bool KSocket::connect(
const QString& _host,
unsigned short int _port,
int _timeout )
00194 {
00195 KExtendedSocket ks(_host, _port, KExtendedSocket::inetSocket);
00196 ks.setTimeout(_timeout, 0);
00197
00198 ks.connect();
00199 sock = ks.fd();
00200 ks.release();
00201
00202
return sock >= 0;
00203 }
00204
00205
00206
#ifdef KSOCK_NO_BROKEN
00207
unsigned long KSocket::ipv4_addr()
00208 {
00209
unsigned long retval = 0;
00210
KSocketAddress *sa = KExtendedSocket::peerAddress(sock);
00211
if (sa == NULL)
00212
return 0;
00213
00214
if (sa->
address() != NULL && (sa->
address()->sa_family == PF_INET
00215
#ifdef PF_INET6
00216
|| sa->
address()->sa_family == PF_INET6
00217
#endif
00218
))
00219 {
00220
KInetSocketAddress *ksin = (
KInetSocketAddress*)sa;
00221
const sockaddr_in *sin = ksin->
addressV4();
00222
if (sin != NULL)
00223 retval = *(
unsigned long*)&sin->sin_addr;
00224 }
00225
delete sa;
00226
return retval;
00227 }
00228
00229
bool KSocket::initSockaddr (ksockaddr_in *server_name,
const char *hostname,
unsigned short int port,
int domain)
00230 {
00231
00232
00233
00234 kdWarning(170) <<
"deprecated KSocket::initSockaddr called" <<
endl;
00235
00236
if (domain != PF_INET)
00237
return false;
00238
00239
QPtrList<KAddressInfo> list = KExtendedSocket::lookup(hostname, QString::number(port),
00240 KExtendedSocket::ipv4Socket);
00241 list.setAutoDelete(
true);
00242
00243
if (list.isEmpty())
00244
return false;
00245
00246 memset(server_name, 0,
sizeof(*server_name));
00247
00248
00249
KInetSocketAddress *sin = (
KInetSocketAddress*)list.getFirst()->address();
00250
if (sin == NULL)
00251
return false;
00252
00253 memcpy(server_name, sin->
addressV4(),
sizeof(*server_name));
00254 kdDebug(170) <<
"KSocket::initSockaddr: returning " << sin->
pretty() <<
endl;
00255
return true;
00256 }
00257
00258
#endif
00259
00260 KSocket::~KSocket()
00261 {
00262
00263
delete d->readNotifier;
00264
delete d->writeNotifier;
00265
00266
delete d;
00267
00268
if (sock != -1) {
00269 ::close( sock );
00270 }
00271 }
00272
00273
class KServerSocketPrivate
00274 {
00275
public:
00276
bool bind;
00277
QCString path;
00278
unsigned short int port;
00279 KExtendedSocket *ks;
00280 };
00281
00282
00283 KServerSocket::KServerSocket(
const char *_path,
bool _bind ) :
00284 sock( -1 )
00285 {
00286 d =
new KServerSocketPrivate();
00287 d->bind = _bind;
00288
00289 init ( _path );
00290 }
00291
00292 KServerSocket::KServerSocket(
unsigned short int _port,
bool _bind ) :
00293 sock( -1 )
00294 {
00295 d =
new KServerSocketPrivate();
00296 d->bind = _bind;
00297
00298 init ( _port );
00299 }
00300
00301
bool KServerSocket::init(
const char *_path )
00302 {
00303 unlink(_path );
00304 d->path = _path;
00305
00306 KExtendedSocket *ks =
new KExtendedSocket(QString::null, _path, KExtendedSocket::passiveSocket |
00307 KExtendedSocket::unixSocket);
00308 d->ks = ks;
00309
00310
if (d->bind)
00311
return bindAndListen();
00312
return true;
00313 }
00314
00315
00316
bool KServerSocket::init(
unsigned short int _port )
00317 {
00318 d->port = _port;
00319 KExtendedSocket *ks;
00320 ks =
new KExtendedSocket(QString::null, _port, KExtendedSocket::passiveSocket |
00321 KExtendedSocket::inetSocket);
00322 d->ks = ks;
00323
00324
if (d->bind)
00325
return bindAndListen();
00326
return true;
00327 }
00328
00329
bool KServerSocket::bindAndListen()
00330 {
00331
if (d == NULL || d->ks == NULL)
00332
return false;
00333
00334
00335
int ret = d->ks->listen( SOMAXCONN );
00336
if (ret < 0)
00337 {
00338 kdWarning(170) <<
"Error listening on socket: " << ret <<
"\n";
00339
delete d->ks;
00340 d->ks = NULL;
00341 sock = -1;
00342
return false;
00343 }
00344
00345
00346 sock = d->ks->fd();
00347
00348 connect( d->ks->readNotifier(), SIGNAL( activated(
int) ),
this, SLOT( slotAccept(
int) ) );
00349
return true;
00350 }
00351
00352
00353
unsigned short int KServerSocket::port()
00354 {
00355
if (d == NULL || d->ks == NULL || sock == -1)
00356
return 0;
00357
const KSocketAddress *sa = d->ks->localAddress();
00358
if (sa == NULL)
00359
return 0;
00360
00361
00362 sockaddr_in *sin = (sockaddr_in*)sa->
address();
00363
00364
if (sin->sin_family == PF_INET)
00365
00366
return sin->sin_port;
00367
#ifdef PF_INET6
00368
else if (sin->sin_family == PF_INET6)
00369 {
00370 kde_sockaddr_in6 *sin6 = (kde_sockaddr_in6*)sin;
00371
return sin6->sin6_port;
00372 }
00373
#endif
00374
return 0;
00375 }
00376
00377
unsigned long KServerSocket::ipv4_addr()
00378 {
00379
if (d == NULL || d->ks == NULL || sock == -1)
00380
return 0;
00381
const KSocketAddress *sa = d->ks->localAddress();
00382
00383
const sockaddr_in *sin = (sockaddr_in*)sa->
address();
00384
00385
if (sin->sin_family == PF_INET)
00386
00387
return ntohl(*(
unsigned long*)&sin->sin_addr);
00388
#ifdef PF_INET6
00389
else if (sin->sin_family == PF_INET6)
00390 {
00391
KInetSocketAddress *ksin = (
KInetSocketAddress*)sa;
00392 sin = ksin->
addressV4();
00393
if (sin != NULL)
00394
return *(
unsigned long*)&sin->sin_addr;
00395 }
00396
#endif
00397
return 0;
00398 }
00399
00400
void KServerSocket::slotAccept(
int )
00401 {
00402
if (d == NULL || d->ks == NULL || sock == -1)
00403
return;
00404
00405 KExtendedSocket *s;
00406
if (d->ks->accept(s) < 0)
00407 {
00408 kdWarning(170) <<
"Error accepting\n";
00409
return;
00410 }
00411
00412
int new_sock = s->fd();
00413 s->release();
00414
delete s;
00415
00416 emit accepted(
new KSocket( new_sock ) );
00417 }
00418
00419 KServerSocket::~KServerSocket()
00420 {
00421
if (d != NULL)
00422 {
00423
if (d->ks != NULL)
00424
delete d->ks;
00425
delete d;
00426 }
00427
00428
00429 }
00430
00431
#include "ksock.moc"