• 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
35extern "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
54extern "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
97class TDESocketPrivate
98{
99public:
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.
110TDESocket::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
124TDESocket::TDESocket( const char *_host, unsigned short int _port, int _timeout ) :
125 sock( -1 ), d(new TDESocketPrivate)
126{
127 connect( _host, _port, _timeout );
128}
129
130TDESocket::TDESocket( const char *_path ) :
131 sock( -1 ), d(new TDESocketPrivate)
132{
133 connect( _path );
134}
135
136void 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
152void 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
169void 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
180void TDESocket::slotWrite( int )
181{
182 emit writeEvent( this );
183}
184
185/*
186 * Connects the PF_UNIX domain socket to _path.
187 */
188bool 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 */
202bool 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
216unsigned 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
238bool 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
269TDESocket::~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
282class TDEServerSocketPrivate
283{
284public:
285 bool bind;
286 TQCString path;
287 unsigned short int port;
288 KExtendedSocket *ks;
289};
290
291
292TDEServerSocket::TDEServerSocket( const char *_path, bool _bind ) :
293 sock( -1 )
294{
295 d = new TDEServerSocketPrivate();
296 d->bind = _bind;
297
298 init ( _path );
299}
300
301TDEServerSocket::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
310bool 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
325bool 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
338bool 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
365unsigned 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
389unsigned 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
412void 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
431TDEServerSocket::~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
444bool 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.4
This website is maintained by Timothy Pearson.