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