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"