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

kdecore

  • kdecore
ksock.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 1997 Torben Weis (weis@kde.org)
4  *
5  * $Id$
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  **/
22 
23 #include <config.h>
24 
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 // on Linux/libc5, this includes linux/socket.h where SOMAXCONN is defined
28 #include <sys/socket.h>
29 #include <sys/resource.h>
30 #include <sys/time.h>
31 #include <sys/un.h>
32 #ifdef HAVE_SYS_SELECT_H
33 #include <sys/select.h>
34 #endif
35 extern "C" {
36 #include <netinet/in.h>
37 
38 #include <arpa/inet.h>
39 }
40 
41 #define KSOCK_NO_BROKEN
42 #include "kdebug.h"
43 #include "ksock.h"
44 #include "kextsock.h"
45 #include "ksockaddr.h"
46 
47 #include "ksocks.h"
48 
49 extern "C" {
50 #include <errno.h>
51 #include <fcntl.h>
52 
53 #ifdef HAVE_GETADDRINFO
54 #include <netdb.h>
55 #endif
56 
57 // defines MAXDNAME under Solaris
58 #include <arpa/nameser.h>
59 #include <resolv.h>
60 }
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <signal.h>
65 #include <unistd.h>
66 #include <assert.h>
67 
68 #ifdef HAVE_SYSENT_H
69 #include <sysent.h>
70 #endif
71 
72 #if TIME_WITH_SYS_TIME
73 #include <time.h>
74 #endif
75 
76 
77 // Play it safe, use a reasonable default, if SOMAXCONN was nowhere defined.
78 #ifndef SOMAXCONN
79 #warning Your header files do not seem to support SOMAXCONN
80 #define SOMAXCONN 5
81 #endif
82 
83 #include <tqapplication.h>
84 #include <tqsocketnotifier.h>
85 
86 #include "netsupp.h" // leave this last
87 
88 #ifdef __CYGWIN__
89 #include "tqwindowdefs.h"
90 #endif
91 
92 class KSocketPrivate
93 {
94 public:
95  TQSocketNotifier *readNotifier;
96  TQSocketNotifier *writeNotifier;
97 
98  KSocketPrivate() :
99  readNotifier(0), writeNotifier(0)
100  { }
101 };
102 
103 // I moved this into here so we could accurately detect the domain, for
104 // posterity. Really.
105 KSocket::KSocket( int _sock)
106  : sock(_sock), d(new KSocketPrivate)
107 {
108  struct sockaddr_in sin;
109  ksocklen_t len = sizeof(sin);
110 
111  memset(&sin, 0, len);
112 
113  // getsockname will fill in all the appropriate details, and
114  // since sockaddr_in will exist everywhere and is somewhat compatible
115  // with sockaddr_in6, we can use it to avoid needless ifdefs.
116  KSocks::self()->getsockname(_sock, (struct sockaddr *)&sin, &len);
117 }
118 
119 KSocket::KSocket( const char *_host, unsigned short int _port, int _timeout ) :
120  sock( -1 ), d(new KSocketPrivate)
121 {
122  connect( _host, _port, _timeout );
123 }
124 
125 KSocket::KSocket( const char *_path ) :
126  sock( -1 ), d(new KSocketPrivate)
127 {
128  connect( _path );
129 }
130 
131 void KSocket::enableRead( bool _state )
132 {
133  if ( _state )
134  {
135  if ( !d->readNotifier )
136  {
137  d->readNotifier = new TQSocketNotifier( sock, TQSocketNotifier::Read );
138  TQObject::connect( d->readNotifier, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( slotRead(int) ) );
139  }
140  else
141  d->readNotifier->setEnabled( true );
142  }
143  else if ( d->readNotifier )
144  d->readNotifier->setEnabled( false );
145 }
146 
147 void KSocket::enableWrite( bool _state )
148 {
149  if ( _state )
150  {
151  if ( !d->writeNotifier )
152  {
153  d->writeNotifier = new TQSocketNotifier( sock, TQSocketNotifier::Write );
154  TQObject::connect( d->writeNotifier, TQT_SIGNAL( activated(int) ), this,
155  TQT_SLOT( slotWrite(int) ) );
156  }
157  else
158  d->writeNotifier->setEnabled( true );
159  }
160  else if ( d->writeNotifier )
161  d->writeNotifier->setEnabled( false );
162 }
163 
164 void KSocket::slotRead( int )
165 {
166  char buffer[2];
167 
168  int n = recv( sock, buffer, 1, MSG_PEEK );
169  if ( n <= 0 )
170  emit closeEvent( this );
171  else
172  emit readEvent( this );
173 }
174 
175 void KSocket::slotWrite( int )
176 {
177  emit writeEvent( this );
178 }
179 
180 /*
181  * Connects the PF_UNIX domain socket to _path.
182  */
183 bool KSocket::connect( const char *_path )
184 {
185  KExtendedSocket ks(TQString::null, _path, KExtendedSocket::unixSocket);
186 
187  ks.connect();
188  sock = ks.fd();
189  ks.release();
190 
191  return sock >= 0;
192 }
193 
194 /*
195  * Connects the socket to _host, _port.
196  */
197 bool KSocket::connect( const TQString& _host, unsigned short int _port, int _timeout )
198 {
199  KExtendedSocket ks(_host, _port, KExtendedSocket::inetSocket);
200  ks.setTimeout(_timeout, 0);
201 
202  ks.connect();
203  sock = ks.fd();
204  ks.release();
205 
206  return sock >= 0;
207 }
208 
209 // only for doxygen - the define is always true as defined above
210 #ifdef KSOCK_NO_BROKEN
211 unsigned long KSocket::ipv4_addr()
212 {
213  unsigned long retval = 0;
214  KSocketAddress *sa = KExtendedSocket::peerAddress(sock);
215  if (sa == NULL)
216  return 0;
217 
218  if (sa->address() != NULL && (sa->address()->sa_family == PF_INET
219 #ifdef PF_INET6
220  || sa->address()->sa_family == PF_INET6
221 #endif
222  ))
223  {
224  KInetSocketAddress *ksin = (KInetSocketAddress*)sa;
225  const sockaddr_in *sin = ksin->addressV4();
226  if (sin != NULL)
227  retval = sin->sin_addr.s_addr;
228  }
229  delete sa;
230  return retval;
231 }
232 
233 bool KSocket::initSockaddr (ksockaddr_in *server_name, const char *hostname, unsigned short int port, int domain)
234 {
235  // This function is now IPv4 only
236  // if you want something better, you should use KExtendedSocket::lookup yourself
237 
238  kdWarning(170) << "deprecated KSocket::initSockaddr called" << endl;
239 
240  if (domain != PF_INET)
241  return false;
242 
243  TQPtrList<KAddressInfo> list = KExtendedSocket::lookup(hostname, TQString::number(port),
244  KExtendedSocket::ipv4Socket);
245  list.setAutoDelete(true);
246 
247  if (list.isEmpty())
248  return false;
249 
250  memset(server_name, 0, sizeof(*server_name));
251 
252  // We are sure that only KInetSocketAddress objects are in the list
253  KInetSocketAddress *sin = (KInetSocketAddress*)list.getFirst()->address();
254  if (sin == NULL)
255  return false;
256 
257  memcpy(server_name, sin->addressV4(), sizeof(*server_name));
258  kdDebug(170) << "KSocket::initSockaddr: returning " << sin->pretty() << endl;
259  return true;
260 }
261 
262 #endif
263 
264 KSocket::~KSocket()
265 {
266  // Coolo says delete 0 is ok :) -thiago
267  delete d->readNotifier;
268  delete d->writeNotifier;
269 
270  delete d;
271 
272  if (sock != -1) {
273  ::close( sock );
274  }
275 }
276 
277 class KServerSocketPrivate
278 {
279 public:
280  bool bind;
281  TQCString path;
282  unsigned short int port;
283  KExtendedSocket *ks;
284 };
285 
286 
287 KServerSocket::KServerSocket( const char *_path, bool _bind ) :
288  sock( -1 )
289 {
290  d = new KServerSocketPrivate();
291  d->bind = _bind;
292 
293  init ( _path );
294 }
295 
296 KServerSocket::KServerSocket( unsigned short int _port, bool _bind ) :
297  sock( -1 )
298 {
299  d = new KServerSocketPrivate();
300  d->bind = _bind;
301 
302  init ( _port );
303 }
304 
305 bool KServerSocket::init( const char *_path )
306 {
307  unlink(_path );
308  d->path = _path;
309 
310  KExtendedSocket *ks = new KExtendedSocket(TQString::null, _path, KExtendedSocket::passiveSocket |
311  KExtendedSocket::unixSocket);
312  d->ks = ks;
313 
314  if (d->bind)
315  return bindAndListen();
316  return true;
317 }
318 
319 
320 bool KServerSocket::init( unsigned short int _port )
321 {
322  d->port = _port;
323  KExtendedSocket *ks;
324  ks = new KExtendedSocket(TQString::null, _port, KExtendedSocket::passiveSocket |
325  KExtendedSocket::inetSocket);
326  d->ks = ks;
327 
328  if (d->bind)
329  return bindAndListen();
330  return true;
331 }
332 
333 bool KServerSocket::bindAndListen()
334 {
335  if (d == NULL || d->ks == NULL)
336  return false;
337 
338 
339  int ret = d->ks->listen( SOMAXCONN );
340  if (ret < 0)
341  {
342  kdWarning(170) << "Error listening on socket: " << ret << "\n";
343  delete d->ks;
344  d->ks = NULL;
345  sock = -1;
346  return false;
347  }
348 
349 
350  sock = d->ks->fd();
351 
352  connect( d->ks->readNotifier(), TQT_SIGNAL( activated(int) ), this, TQT_SLOT( slotAccept(int) ) );
353  return true;
354 }
355 
356 
357 unsigned short int KServerSocket::port()
358 {
359  if (d == NULL || d->ks == NULL || sock == -1)
360  return 0;
361  const KSocketAddress *sa = d->ks->localAddress();
362  if (sa == NULL)
363  return 0;
364 
365  // we can use sockaddr_in here even if it isn't IPv4
366  sockaddr_in *sin = (sockaddr_in*)sa->address();
367 
368  if (sin->sin_family == PF_INET)
369  // correct family
370  return sin->sin_port;
371 #ifdef PF_INET6
372  else if (sin->sin_family == PF_INET6)
373  {
374  kde_sockaddr_in6 *sin6 = (kde_sockaddr_in6*)sin;
375  return sin6->sin6_port;
376  }
377 #endif
378  return 0; // not a port we know
379 }
380 
381 unsigned long KServerSocket::ipv4_addr()
382 {
383  if (d == NULL || d->ks == NULL || sock == -1)
384  return 0;
385  const KSocketAddress *sa = d->ks->localAddress();
386 
387  const sockaddr_in *sin = (sockaddr_in*)sa->address();
388 
389  if (sin->sin_family == PF_INET)
390  // correct family
391  return ntohl(sin->sin_addr.s_addr);
392 #ifdef PF_INET6
393  else if (sin->sin_family == PF_INET6)
394  {
395  KInetSocketAddress *ksin = (KInetSocketAddress*)sa;
396  sin = ksin->addressV4();
397  if (sin != NULL)
398  return sin->sin_addr.s_addr;
399  }
400 #endif
401  return 0; // this is dumb, isn't it?
402 }
403 
404 void KServerSocket::slotAccept( int )
405 {
406  if (d == NULL || d->ks == NULL || sock == -1)
407  return; // nothing!
408 
409  KExtendedSocket *s;
410  if (d->ks->accept(s) < 0)
411  {
412  kdWarning(170) << "Error accepting\n";
413  return;
414  }
415 
416  int new_sock = s->fd();
417  s->release(); // we're getting rid of the KExtendedSocket
418  delete s;
419 
420  emit accepted( new KSocket( new_sock ) );
421 }
422 
423 KServerSocket::~KServerSocket()
424 {
425  if (d != NULL)
426  {
427  if (d->ks != NULL)
428  delete d->ks;
429  delete d;
430  }
431  // deleting d->ks closes the socket
432  // ::close( sock );
433 }
434 
435 #include "ksock.moc"
KSocket::~KSocket
virtual ~KSocket()
Destructor.
Definition: ksock.cpp:264
KSocket::KSocket
KSocket(int _sock) KDE_DEPRECATED
Constructs a KSocket with the provided file descriptor.
Definition: ksock.cpp:105
KServerSocket::slotAccept
virtual void slotAccept(int)
Called when someone connected to our port.
Definition: ksock.cpp:404
KSocket::enableWrite
void enableWrite(bool enable)
Enables the socket for writing.
Definition: ksock.cpp:147
KExtendedSocket::release
virtual void release()
Releases the socket and anything we have holding on it.
Definition: kextsock.cpp:1339
KInetSocketAddress::addressV4
const sockaddr_in * addressV4() const
Returns the socket address.
Definition: ksockaddr.cpp:513
KSocketAddress::address
const sockaddr * address() const
Returns a sockaddr structure, for passing down to library functions.
Definition: ksockaddr.h:78
KSocket::enableRead
void enableRead(bool enable)
Enables the socket for reading.
Definition: ksock.cpp:131
KInetSocketAddress
An Inet (IPv4 or IPv6) socket address.
Definition: ksockaddr.h:233
KServerSocket::sock
int sock
The file descriptor for this socket.
Definition: ksock.h:339
KSocket::slotWrite
void slotWrite(int x)
Connected to the writeNotifier.
Definition: ksock.cpp:175
KExtendedSocket::fd
int fd() const
Returns the file descriptor.
Definition: kextsock.h:508
KSocks::self
static KSocks * self()
Return an instance of class KSocks *.
Definition: ksocks.cpp:212
KSocket::slotRead
void slotRead(int x)
Connected to the readNotifier.
Definition: ksock.cpp:164
KSocket::readEvent
void readEvent(KSocket *s)
Data has arrived for reading.
KServerSocket::port
unsigned short int port()
Returns the port number which is being monitored.
Definition: ksock.cpp:357
KSocket::closeEvent
void closeEvent(KSocket *s)
Raised when the connection is broken.
KExtendedSocket::connect
virtual int connect()
Attempts to connect to the remote host.
Definition: kextsock.cpp:983
KSocks::getsockname
int getsockname(int s, sockaddr *name, ksocklen_t *namelen)
This is the re-implementation of libc&#39;s function of the same name.
Definition: ksocks.cpp:536
KExtendedSocket::lookup
virtual int lookup()
Performs lookup on the addresses we were given before.
Definition: kextsock.cpp:749
KExtendedSocket::peerAddress
const ::KSocketAddress * peerAddress()
Returns the peer socket address.
Definition: kextsock.cpp:736
KServerSocket::bindAndListen
bool bindAndListen()
Binds the socket and start listening.
Definition: ksock.cpp:333
KExtendedSocket::setTimeout
bool setTimeout(int secs, int usecs=0)
Sets the timeout value for the connection (if this is not passiveSocket) or acception (if it is)...
Definition: kextsock.cpp:432
KSocketAddress
A socket address.
Definition: ksockaddr.h:46
KExtendedSocket
The extended socket class.
Definition: kextsock.h:95
KServerSocket::accepted
void accepted(KSocket *s)
A connection has been accepted.
KSocket
A TCP/IP client socket.
Definition: ksock.h:91
KInetSocketAddress::pretty
virtual TQString pretty() const
Returns a pretty representation of this address.
Definition: ksockaddr.cpp:559
KSocket::writeEvent
void writeEvent(KSocket *s)
Socket is ready for writing.
endl
kndbgstream & endl(kndbgstream &s)
Does nothing.
Definition: kdebug.h:583
KServerSocket::KServerSocket
KServerSocket(unsigned short int _port, bool _bind=true)
Constructor.
Definition: ksock.cpp:296
KServerSocket::~KServerSocket
virtual ~KServerSocket()
Destructor.
Definition: ksock.cpp:423

kdecore

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

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.8.11
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |