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

tdecore

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

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.9.1
This website is maintained by Timothy Pearson.