• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

ksock.cpp
00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 1997 Torben Weis (weis@kde.org)
00004  *
00005  *  $Id$
00006  *
00007  *  This library is free software; you can redistribute it and/or
00008  *  modify it under the terms of the GNU Library General Public
00009  *  License as published by the Free Software Foundation; either
00010  *  version 2 of the License, or (at your option) any later version.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Library General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Library General Public License
00018  *  along with this library; see the file COPYING.LIB.  If not, write to
00019  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  *  Boston, MA 02110-1301, USA.
00021  **/
00022 
00023 #include <config.h>
00024 
00025 #include <sys/types.h>
00026 #include <sys/stat.h>
00027 // on Linux/libc5, this includes linux/socket.h where SOMAXCONN is defined
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 // FIXME
00044 // FOR BINARY COMPATIBILITY ONLY
00045 // REMOVE WHEN PRACTICAL!
00046 #define TDESOCKET_BINARY_COMPAT_HACK 1
00047 #include "ksock.h"
00048 #undef TDESOCKET_BINARY_COMPAT_HACK
00049 #include "kextsock.h"
00050 #include "ksockaddr.h"
00051 
00052 #include "ksocks.h"
00053 
00054 extern "C" {
00055 #include <errno.h>
00056 #include <fcntl.h>
00057 
00058 #ifdef HAVE_GETADDRINFO
00059 #include <netdb.h>
00060 #endif
00061 
00062 // defines MAXDNAME under Solaris
00063 #include <arpa/nameser.h>
00064 #include <resolv.h>
00065 }
00066 #include <stdio.h>
00067 #include <stdlib.h>
00068 #include <string.h>
00069 #include <signal.h>
00070 #include <unistd.h>
00071 #include <assert.h>
00072 
00073 #ifdef HAVE_SYSENT_H
00074 #include <sysent.h>
00075 #endif
00076 
00077 #if TIME_WITH_SYS_TIME
00078 #include <time.h>
00079 #endif
00080 
00081 
00082 // Play it safe, use a reasonable default, if SOMAXCONN was nowhere defined.
00083 #ifndef SOMAXCONN
00084 #warning Your header files do not seem to support SOMAXCONN
00085 #define SOMAXCONN 5
00086 #endif
00087 
00088 #include <tqapplication.h>
00089 #include <tqsocketnotifier.h>
00090 
00091 #include "netsupp.h"        // leave this last
00092 
00093 #ifdef __CYGWIN__
00094 #include "tqwindowdefs.h"
00095 #endif 
00096 
00097 class TDESocketPrivate
00098 {
00099 public:
00100   TQSocketNotifier *readNotifier;
00101   TQSocketNotifier *writeNotifier;
00102 
00103   TDESocketPrivate() :
00104     readNotifier(0), writeNotifier(0)
00105   { }
00106 };
00107 
00108 // I moved this into here so we could accurately detect the domain, for
00109 // posterity.  Really.
00110 TDESocket::TDESocket( int _sock)
00111   : sock(_sock), d(new TDESocketPrivate)
00112 {
00113   struct sockaddr_in sin;
00114   ksocklen_t len = sizeof(sin);
00115 
00116   memset(&sin, 0, len);
00117 
00118   // getsockname will fill in all the appropriate details, and
00119   // since sockaddr_in will exist everywhere and is somewhat compatible
00120   // with sockaddr_in6, we can use it to avoid needless ifdefs.
00121   KSocks::self()->getsockname(_sock, (struct sockaddr *)&sin, &len);
00122 }
00123 
00124 TDESocket::TDESocket( const char *_host, unsigned short int _port, int _timeout ) :
00125   sock( -1 ), d(new TDESocketPrivate)
00126 {
00127     connect( _host, _port, _timeout );
00128 }
00129 
00130 TDESocket::TDESocket( const char *_path ) :
00131   sock( -1 ), d(new TDESocketPrivate)
00132 {
00133   connect( _path );
00134 }
00135 
00136 void TDESocket::enableRead( bool _state )
00137 {
00138   if ( _state )
00139     {
00140       if ( !d->readNotifier  )
00141         {
00142           d->readNotifier = new TQSocketNotifier( sock, TQSocketNotifier::Read );
00143           TQObject::connect( d->readNotifier, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( slotRead(int) ) );
00144         }
00145       else
00146         d->readNotifier->setEnabled( true );
00147     }
00148   else if ( d->readNotifier )
00149     d->readNotifier->setEnabled( false );
00150 }
00151 
00152 void TDESocket::enableWrite( bool _state )
00153 {
00154   if ( _state )
00155     {
00156       if ( !d->writeNotifier )
00157         {
00158           d->writeNotifier = new TQSocketNotifier( sock, TQSocketNotifier::Write );
00159           TQObject::connect( d->writeNotifier, TQT_SIGNAL( activated(int) ), this,
00160                             TQT_SLOT( slotWrite(int) ) );
00161         }
00162       else
00163         d->writeNotifier->setEnabled( true );
00164     }
00165   else if ( d->writeNotifier )
00166     d->writeNotifier->setEnabled( false );
00167 }
00168 
00169 void TDESocket::slotRead( int )
00170 {
00171   char buffer[2];
00172 
00173   int n = recv( sock, buffer, 1, MSG_PEEK );
00174   if ( n <= 0 )
00175     emit closeEvent( this );
00176   else
00177     emit readEvent( this );
00178 }
00179 
00180 void TDESocket::slotWrite( int )
00181 {
00182   emit writeEvent( this );
00183 }
00184 
00185 /*
00186  * Connects the PF_UNIX domain socket to _path.
00187  */
00188 bool TDESocket::connect( const char *_path )
00189 {
00190   KExtendedSocket ks(TQString::null, _path, KExtendedSocket::unixSocket);
00191 
00192   ks.connect();
00193   sock = ks.fd();
00194   ks.release();
00195 
00196   return sock >= 0;
00197 }
00198 
00199 /*
00200  * Connects the socket to _host, _port.
00201  */
00202 bool TDESocket::connect( const TQString& _host, unsigned short int _port, int _timeout )
00203 {
00204   KExtendedSocket ks(_host, _port, KExtendedSocket::inetSocket);
00205   ks.setTimeout(_timeout, 0);
00206 
00207   ks.connect();
00208   sock = ks.fd();
00209   ks.release();
00210 
00211   return sock >= 0;
00212 }
00213 
00214 // only for doxygen - the define is always true as defined above
00215 #ifdef KSOCK_NO_BROKEN
00216 unsigned long TDESocket::ipv4_addr()
00217 {
00218   unsigned long retval = 0;
00219   TDESocketAddress *sa = KExtendedSocket::peerAddress(sock);
00220   if (sa == NULL)
00221     return 0;
00222 
00223   if (sa->address() != NULL && (sa->address()->sa_family == PF_INET
00224 #ifdef PF_INET6
00225                 || sa->address()->sa_family == PF_INET6
00226 #endif
00227       ))
00228     {
00229       KInetSocketAddress *ksin = (KInetSocketAddress*)sa;
00230       const sockaddr_in *sin = ksin->addressV4();
00231       if (sin != NULL)
00232     retval = sin->sin_addr.s_addr;
00233     }
00234   delete sa;
00235   return retval;
00236 }
00237 
00238 bool TDESocket::initSockaddr (ksockaddr_in *server_name, const char *hostname, unsigned short int port, int domain)
00239 {
00240   // This function is now IPv4 only
00241   // if you want something better, you should use KExtendedSocket::lookup yourself
00242 
00243   kdWarning(170) << "deprecated TDESocket::initSockaddr called" << endl;
00244 
00245   if (domain != PF_INET)
00246     return false;
00247 
00248   TQPtrList<KAddressInfo> list = KExtendedSocket::lookup(hostname, TQString::number(port),
00249                                                         KExtendedSocket::ipv4Socket);
00250   list.setAutoDelete(true);
00251 
00252   if (list.isEmpty())
00253     return false;
00254 
00255   memset(server_name, 0, sizeof(*server_name));
00256 
00257   // We are sure that only KInetSocketAddress objects are in the list
00258   KInetSocketAddress *sin = (KInetSocketAddress*)list.getFirst()->address();
00259   if (sin == NULL)
00260     return false;
00261 
00262   memcpy(server_name, sin->addressV4(), sizeof(*server_name));
00263   kdDebug(170) << "TDESocket::initSockaddr: returning " << sin->pretty() << endl;
00264   return true;
00265 }
00266 
00267 #endif
00268 
00269 TDESocket::~TDESocket()
00270 {
00271   // Coolo says delete 0 is ok :) -thiago
00272   delete d->readNotifier;
00273   delete d->writeNotifier;
00274 
00275   delete d;
00276 
00277   if (sock != -1) {
00278     ::close( sock );
00279   }
00280 }
00281 
00282 class TDEServerSocketPrivate
00283 {
00284 public:
00285    bool bind;
00286    TQCString path;
00287    unsigned short int port;
00288    KExtendedSocket *ks;
00289 };
00290 
00291 
00292 TDEServerSocket::TDEServerSocket( const char *_path, bool _bind ) :
00293   sock( -1 )
00294 {
00295   d = new TDEServerSocketPrivate();
00296   d->bind = _bind;
00297 
00298   init ( _path );
00299 }
00300 
00301 TDEServerSocket::TDEServerSocket( unsigned short int _port, bool _bind ) :
00302   sock( -1 )
00303 {
00304   d = new TDEServerSocketPrivate();
00305   d->bind = _bind;
00306 
00307   init ( _port );
00308 }
00309 
00310 bool TDEServerSocket::init( const char *_path )
00311 {
00312   unlink(_path );
00313   d->path = _path;
00314 
00315   KExtendedSocket *ks = new KExtendedSocket(TQString::null, _path, KExtendedSocket::passiveSocket |
00316                         KExtendedSocket::unixSocket);
00317   d->ks = ks;
00318 
00319   if (d->bind)
00320     return bindAndListen(false);
00321   return true;
00322 }
00323 
00324 
00325 bool TDEServerSocket::init( unsigned short int _port )
00326 {
00327   d->port = _port;
00328   KExtendedSocket *ks;
00329   ks = new KExtendedSocket(TQString::null, _port, KExtendedSocket::passiveSocket |
00330                KExtendedSocket::inetSocket);
00331   d->ks = ks;
00332 
00333   if (d->bind)
00334     return bindAndListen(false);
00335   return true;
00336 }
00337 
00338 bool TDEServerSocket::bindAndListen(bool suppressFailureMessages)
00339 {
00340   if (d == NULL || d->ks == NULL)
00341     return false;
00342 
00343 
00344   int ret = d->ks->listen( SOMAXCONN );
00345   if (ret < 0)
00346     {
00347     if (!suppressFailureMessages)
00348         {
00349         kdWarning(170) << "Error listening on socket for port " << d->ks->port() << ": " << ret << "\n";
00350         }
00351     delete d->ks;
00352     d->ks = NULL;
00353     sock = -1;
00354     return false;
00355     }
00356 
00357 
00358   sock = d->ks->fd();
00359 
00360   connect( d->ks->readNotifier(), TQT_SIGNAL( activated(int) ), this, TQT_SLOT( slotAccept(int) ) );
00361   return true;
00362 }
00363 
00364 
00365 unsigned short int TDEServerSocket::port()
00366 {
00367   if (d == NULL || d->ks == NULL || sock == -1)
00368     return 0;
00369   const TDESocketAddress *sa = d->ks->localAddress();
00370   if (sa == NULL)
00371     return 0;
00372 
00373   // we can use sockaddr_in here even if it isn't IPv4
00374   sockaddr_in *sin = (sockaddr_in*)sa->address();
00375 
00376   if (sin->sin_family == PF_INET)
00377     // correct family
00378     return sin->sin_port;
00379 #ifdef PF_INET6
00380   else if (sin->sin_family == PF_INET6)
00381     {
00382       kde_sockaddr_in6 *sin6 = (kde_sockaddr_in6*)sin;
00383       return sin6->sin6_port;
00384     }
00385 #endif
00386   return 0;         // not a port we know
00387 }
00388 
00389 unsigned long TDEServerSocket::ipv4_addr()
00390 {
00391   if (d == NULL || d->ks == NULL || sock == -1)
00392     return 0;
00393   const TDESocketAddress *sa = d->ks->localAddress();
00394 
00395   const sockaddr_in *sin = (sockaddr_in*)sa->address();
00396 
00397   if (sin->sin_family == PF_INET)
00398     // correct family
00399     return ntohl(sin->sin_addr.s_addr);
00400 #ifdef PF_INET6
00401   else if (sin->sin_family == PF_INET6)
00402     {
00403       KInetSocketAddress *ksin = (KInetSocketAddress*)sa;
00404       sin = ksin->addressV4();
00405       if (sin != NULL)
00406     return sin->sin_addr.s_addr;
00407     }
00408 #endif
00409   return 0;         // this is dumb, isn't it?
00410 }
00411 
00412 void TDEServerSocket::slotAccept( int )
00413 {
00414   if (d == NULL || d->ks == NULL || sock == -1)
00415     return;         // nothing!
00416 
00417   KExtendedSocket *s;
00418   if (d->ks->accept(s) < 0)
00419     {
00420         kdWarning(170) << "Error accepting\n";
00421         return;
00422     }
00423 
00424   int new_sock = s->fd();
00425   s->release();         // we're getting rid of the KExtendedSocket
00426   delete s;
00427 
00428   emit accepted( new TDESocket( new_sock ) );
00429 }
00430 
00431 TDEServerSocket::~TDEServerSocket()
00432 {
00433   if (d != NULL)
00434     {
00435       if (d->ks != NULL)
00436     delete d->ks;
00437       delete d;
00438     }
00439   // deleting d->ks closes the socket
00440   //  ::close( sock );
00441 }
00442 
00443 // DEPRECATED
00444 bool TDEServerSocket::bindAndListen()
00445 {
00446   return bindAndListen(false);
00447 }
00448 
00449 #include "ksock.moc"

tdecore

Skip menu "tdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.