diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-06 15:56:40 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-06 15:56:40 -0600 |
commit | e16866e072f94410321d70daedbcb855ea878cac (patch) | |
tree | ee3f52eabde7da1a0e6ca845fb9c2813cf1558cf /kdecore/network | |
parent | a58c20c1a7593631a1b50213c805507ebc16adaf (diff) | |
download | tdelibs-e16866e072f94410321d70daedbcb855ea878cac.tar.gz tdelibs-e16866e072f94410321d70daedbcb855ea878cac.zip |
Actually move the kde files that were renamed in the last commit
Diffstat (limited to 'kdecore/network')
42 files changed, 0 insertions, 15900 deletions
diff --git a/kdecore/network/CMakeLists.txt b/kdecore/network/CMakeLists.txt deleted file mode 100644 index 101da4843..000000000 --- a/kdecore/network/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/tdecore - ${CMAKE_BINARY_DIR}/tdecore -) - - -##### headers ################################### - -install( FILES - kresolver.h kreverseresolver.h ksocketaddress.h - ksocketbase.h ksocketdevice.h kclientsocketbase.h - kstreamsocket.h kserversocket.h kdatagramsocket.h - kmulticastsocketdevice.h kmulticastsocket.h - knetworkinterface.h khttpproxysocketdevice.h - ksockssocketdevice.h kbufferedsocket.h kiobuffer.h - DESTINATION ${INCLUDE_INSTALL_DIR} ) - - -##### other files ############################### - -install( FILES ipv6blacklist DESTINATION ${CONFIG_INSTALL_DIR} ) - - -##### tdecorenetwork ############################ - -set( target tdecorenetwork ) - -set( ${target}_SRCS - kresolver.cpp kresolvermanager.cpp kresolverworkerbase.cpp - ksocketaddress.cpp kresolverstandardworkers.cpp - kreverseresolver.cpp ksocketdevice.cpp ksocketbase.cpp - kclientsocketbase.cpp kstreamsocket.cpp kserversocket.cpp - kdatagramsocket.cpp khttpproxysocketdevice.cpp - ksockssocketdevice.cpp kbufferedsocket.cpp ksocketbuffer.cpp - ksrvresolverworker.cpp -) - -tde_add_library( ${target} STATIC_PIC AUTOMOC - SOURCES ${${target}_SRCS} -) diff --git a/kdecore/network/Makefile.am b/kdecore/network/Makefile.am deleted file mode 100644 index f686a50ca..000000000 --- a/kdecore/network/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -## Makefile.am for libqt-addon - -# this is the program that gets installed. it's name is used for all -# of the other Makefile.am variables -noinst_LTLIBRARIES = libtdecorenetwork.la - -# set the include path for X, qt and KDE -INCLUDES = $(all_includes) - -# the library search path. -# convenience lib - no LDFLAGS or LIBADD ! -# Note: -# ksocketdevice.cpp must appear before any inclusion of ksocketdevice.h -libtdecorenetwork_la_SOURCES = kresolver.cpp \ - kresolvermanager.cpp \ - kresolverworkerbase.cpp \ - ksocketaddress.cpp \ - kresolverstandardworkers.cpp \ - kreverseresolver.cpp \ - ksocketdevice.cpp \ - ksocketbase.cpp \ - kclientsocketbase.cpp \ - kstreamsocket.cpp \ - kserversocket.cpp \ - kdatagramsocket.cpp \ - khttpproxysocketdevice.cpp \ - ksockssocketdevice.cpp \ - kbufferedsocket.cpp \ - ksocketbuffer.cpp \ - ksrvresolverworker.cpp - -include_HEADERS = kresolver.h \ - kreverseresolver.h \ - ksocketaddress.h \ - ksocketbase.h \ - ksocketdevice.h \ - kclientsocketbase.h \ - kstreamsocket.h \ - kserversocket.h \ - kdatagramsocket.h \ - kmulticastsocketdevice.h \ - kmulticastsocket.h \ - knetworkinterface.h \ - khttpproxysocketdevice.h \ - ksockssocketdevice.h \ - kbufferedsocket.h \ - kiobuffer.h -noinst_HEADERS = kresolver_p.h \ - kresolverworkerbase.h \ - kresolverstandardworkers_p.h \ - ksocketbuffer_p.h \ - ksrvresolverworker_p.h \ - syssocket.h - -configdir = $(kde_confdir) -config_DATA = ipv6blacklist - -# let automoc handle all of the meta source files (moc) -METASOURCES = AUTO diff --git a/kdecore/network/ipv6blacklist b/kdecore/network/ipv6blacklist deleted file mode 100644 index f4d4d1252..000000000 --- a/kdecore/network/ipv6blacklist +++ /dev/null @@ -1,3 +0,0 @@ -.doubleclick.net -.linebourse.fr -.banquepopulaire.fr diff --git a/kdecore/network/kbufferedsocket.cpp b/kdecore/network/kbufferedsocket.cpp deleted file mode 100644 index ffac2e98b..000000000 --- a/kdecore/network/kbufferedsocket.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <tqmutex.h> -#include <tqtimer.h> - -#include "ksocketdevice.h" -#include "ksocketaddress.h" -#include "ksocketbuffer_p.h" -#include "kbufferedsocket.h" - -using namespace KNetwork; -using namespace KNetwork::Internal; - -class KNetwork::KBufferedSocketPrivate -{ -public: - mutable KSocketBuffer *input, *output; - - KBufferedSocketPrivate() - { - input = 0L; - output = 0L; - } -}; - -KBufferedSocket::KBufferedSocket(const TQString& host, const TQString& service, - TQObject *parent, const char *name) - : KStreamSocket(host, service, parent, name), - d(new KBufferedSocketPrivate) -{ - setInputBuffering(true); - setOutputBuffering(true); -} - -KBufferedSocket::~KBufferedSocket() -{ - closeNow(); - delete d->input; - delete d->output; - delete d; -} - -void KBufferedSocket::setSocketDevice(KSocketDevice* device) -{ - KStreamSocket::setSocketDevice(device); - device->setBlocking(false); -} - -bool KBufferedSocket::setSocketOptions(int opts) -{ - if (opts == Blocking) - return false; - - opts &= ~Blocking; - return KStreamSocket::setSocketOptions(opts); -} - -void KBufferedSocket::close() -{ - if (!d->output || d->output->isEmpty()) - closeNow(); - else - { - setState(Closing); - TQSocketNotifier *n = socketDevice()->readNotifier(); - if (n) - n->setEnabled(false); - emit stateChanged(Closing); - } -} - -#ifdef USE_QT3 -TQ_LONG KBufferedSocket::bytesAvailable() const -#endif -#ifdef USE_QT4 -qint64 KBufferedSocket::bytesAvailable() const -#endif -{ - if (!d->input) - return KStreamSocket::bytesAvailable(); - - return d->input->length(); -} - -TQ_LONG KBufferedSocket::waitForMore(int msecs, bool *timeout) -{ - TQ_LONG retval = KStreamSocket::waitForMore(msecs, timeout); - if (d->input) - { - resetError(); - slotReadActivity(); - return bytesAvailable(); - } - return retval; -} - -TQT_TQIO_LONG KBufferedSocket::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen) -{ - if (d->input) - { - if (d->input->isEmpty()) - { - setError(IO_ReadError, WouldBlock); - emit gotError(WouldBlock); - return -1; - } - resetError(); - return d->input->consumeBuffer(data, maxlen); - } - return KStreamSocket::tqreadBlock(data, maxlen); -} - -TQT_TQIO_LONG KBufferedSocket::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress& from) -{ - from = peerAddress(); - return tqreadBlock(data, maxlen); -} - -TQ_LONG KBufferedSocket::peekBlock(char *data, TQ_ULONG maxlen) -{ - if (d->input) - { - if (d->input->isEmpty()) - { - setError(IO_ReadError, WouldBlock); - emit gotError(WouldBlock); - return -1; - } - resetError(); - return d->input->consumeBuffer(data, maxlen, false); - } - return KStreamSocket::peekBlock(data, maxlen); -} - -TQ_LONG KBufferedSocket::peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from) -{ - from = peerAddress(); - return peekBlock(data, maxlen); -} - -TQT_TQIO_LONG KBufferedSocket::tqwriteBlock(const char *data, TQT_TQIO_ULONG len) -{ - if (state() != Connected) - { - // cannot write now! - setError(IO_WriteError, NotConnected); - return -1; - } - - if (d->output) - { - if (d->output->isFull()) - { - setError(IO_WriteError, WouldBlock); - emit gotError(WouldBlock); - return -1; - } - resetError(); - - // enable notifier to send data - TQSocketNotifier *n = socketDevice()->writeNotifier(); - if (n) - n->setEnabled(true); - - return d->output->feedBuffer(data, len); - } - - return KStreamSocket::tqwriteBlock(data, len); -} - -TQT_TQIO_LONG KBufferedSocket::tqwriteBlock(const char *data, TQT_TQIO_ULONG maxlen, - const KSocketAddress&) -{ - // ignore the third parameter - return tqwriteBlock(data, maxlen); -} - -void KBufferedSocket::enableRead(bool enable) -{ - KStreamSocket::enableRead(enable); - if (!enable && d->input) - { - // reenable it - TQSocketNotifier *n = socketDevice()->readNotifier(); - if (n) - n->setEnabled(true); - } - - if (enable && state() != Connected && d->input && !d->input->isEmpty()) - // this means the buffer is still dirty - // allow the signal to be emitted - TQTimer::singleShot(0, this, TQT_SLOT(slotReadActivity())); -} - -void KBufferedSocket::enableWrite(bool enable) -{ - KStreamSocket::enableWrite(enable); - if (!enable && d->output && !d->output->isEmpty()) - { - // reenable it - TQSocketNotifier *n = socketDevice()->writeNotifier(); - if (n) - n->setEnabled(true); - } -} - -void KBufferedSocket::stateChanging(SocketState newState) -{ - if (newState == Connecting || newState == Connected) - { - // we're going to connect - // make sure the buffers are clean - if (d->input) - d->input->clear(); - if (d->output) - d->output->clear(); - - // also, turn on notifiers - enableRead(emitsReadyRead()); - enableWrite(emitsReadyWrite()); - } - KStreamSocket::stateChanging(newState); -} - -void KBufferedSocket::setInputBuffering(bool enable) -{ - TQMutexLocker locker(mutex()); - if (!enable) - { - delete d->input; - d->input = 0L; - } - else if (d->input == 0L) - { - d->input = new KSocketBuffer; - } -} - -KIOBufferBase* KBufferedSocket::inputBuffer() -{ - return d->input; -} - -void KBufferedSocket::setOutputBuffering(bool enable) -{ - TQMutexLocker locker(mutex()); - if (!enable) - { - delete d->output; - d->output = 0L; - } - else if (d->output == 0L) - { - d->output = new KSocketBuffer; - } -} - -KIOBufferBase* KBufferedSocket::outputBuffer() -{ - return d->output; -} - -#ifdef USE_QT3 -TQ_ULONG KBufferedSocket::bytesToWrite() const -#endif -#ifdef USE_QT4 -qint64 KBufferedSocket::bytesToWrite() const -#endif -{ - if (!d->output) - return 0; - - return d->output->length(); -} - -void KBufferedSocket::closeNow() -{ - KStreamSocket::close(); - if (d->output) - d->output->clear(); -} - -bool KBufferedSocket::canReadLine() const -{ - if (!d->input) - return false; - - return d->input->canReadLine(); -} - -TQCString KBufferedSocket::readLine() -{ - return d->input->readLine(); -} - -void KBufferedSocket::waitForConnect() -{ - if (state() != Connecting) - return; // nothing to be waited on - - KStreamSocket::setSocketOptions(socketOptions() | Blocking); - connectionEvent(); - KStreamSocket::setSocketOptions(socketOptions() & ~Blocking); -} - -void KBufferedSocket::slotReadActivity() -{ - if (d->input && state() == Connected) - { - mutex()->lock(); - TQ_LONG len = d->input->receiveFrom(socketDevice()); - - if (len == -1) - { - if (socketDevice()->error() != WouldBlock) - { - // nope, another error! - copyError(); - mutex()->unlock(); - emit gotError(error()); - closeNow(); // emits closed - return; - } - } - else if (len == 0) - { - // remotely closed - setError(IO_ReadError, RemotelyDisconnected); - mutex()->unlock(); - emit gotError(error()); - closeNow(); // emits closed - return; - } - - // no error - mutex()->unlock(); - } - - if (state() == Connected) - KStreamSocket::slotReadActivity(); // this emits readyRead - else if (emitsReadyRead()) // state() != Connected - { - if (d->input && !d->input->isEmpty()) - { - // buffer isn't empty - // keep emitting signals till it is - TQTimer::singleShot(0, this, TQT_SLOT(slotReadActivity())); - emit readyRead(); - } - } -} - -void KBufferedSocket::slotWriteActivity() -{ - if (d->output && !d->output->isEmpty() && - (state() == Connected || state() == Closing)) - { - mutex()->lock(); - TQ_LONG len = d->output->sendTo(socketDevice()); - - if (len == -1) - { - if (socketDevice()->error() != WouldBlock) - { - // nope, another error! - copyError(); - mutex()->unlock(); - emit gotError(error()); - closeNow(); - return; - } - } - else if (len == 0) - { - // remotely closed - setError(IO_ReadError, RemotelyDisconnected); - mutex()->unlock(); - emit gotError(error()); - closeNow(); - return; - } - - if (d->output->isEmpty()) - // deactivate the notifier until we have something to send - // writeNotifier can't return NULL here - socketDevice()->writeNotifier()->setEnabled(false); - - mutex()->unlock(); - emit bytesWritten(len); - } - - if (state() != Closing) - KStreamSocket::slotWriteActivity(); - else if (d->output && d->output->isEmpty() && state() == Closing) - { - KStreamSocket::close(); // finished sending data - } -} - -#include "kbufferedsocket.moc" diff --git a/kdecore/network/kbufferedsocket.h b/kdecore/network/kbufferedsocket.h deleted file mode 100644 index 8f9dde92c..000000000 --- a/kdecore/network/kbufferedsocket.h +++ /dev/null @@ -1,269 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago@kde.org> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KBUFFEREDSOCKET_H -#define KBUFFEREDSOCKET_H - -#include <tqobject.h> -#include <tqcstring.h> -#include <tqvaluelist.h> -#include "kstreamsocket.h" -#include <kdelibs_export.h> - -class KIOBufferBase; - -namespace KNetwork { - -class KBufferedSocketPrivate; -/** @class KBufferedSocket kbufferedsocket.h kbufferedsocket.h - * @brief Buffered stream sockets. - * - * This class allows the user to create and operate buffered stream sockets - * such as those used in most Internet connections. This class is - * also the one that resembles the most to the old @ref QSocket - * implementation. - * - * Objects of this type operate only in non-blocking mode. A call to - * setBlocking(true) will result in an error. - * - * @note Buffered sockets only make sense if you're using them from - * the main (event-loop) thread. This is actually a restriction - * imposed by Qt's TQSocketNotifier. If you want to use a socket - * in an auxiliary thread, please use KStreamSocket. - * - * @see KNetwork::KStreamSocket, KNetwork::KServerSocket - * @author Thiago Macieira <thiago@kde.org> - */ -class KDECORE_EXPORT KBufferedSocket: public KStreamSocket -{ - Q_OBJECT - TQ_OBJECT -public: - /** - * Default constructor. - * - * @param node destination host - * @param service destination service to connect to - * @param parent the parent object for this object - * @param name the internal name for this object - */ - KBufferedSocket(const TQString& node = TQString::null, const TQString& service = TQString::null, - TQObject* parent = 0L, const char *name = 0L); - - /** - * Destructor. - */ - virtual ~KBufferedSocket(); - - /** - * Be sure to catch new devices. - */ - virtual void setSocketDevice(KSocketDevice* device); - -protected: - /** - * Buffered sockets can only operate in non-blocking mode. - */ - virtual bool setSocketOptions(int opts); - -public: - /** - * Closes the socket for new data, but allow data that had been buffered - * for output with @ref writeBlock to be still be written. - * - * @sa closeNow - */ - virtual void close(); - - /** - * Make use of the buffers. - */ -#ifdef USE_QT3 - virtual TQ_LONG bytesAvailable() const; -#endif -#ifdef USE_QT4 - virtual qint64 bytesAvailable() const; -#endif - - /** - * Make use of buffers. - */ - virtual TQ_LONG waitForMore(int msecs, bool *timeout = 0L); - - /** - * Reads data from the socket. Make use of buffers. - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen); - - /** - * @overload - * Reads data from a socket. - * - * The @p from parameter is always set to @ref peerAddress() - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress& from); - - /** - * Peeks data from the socket. - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen); - - /** - * @overload - * Peeks data from the socket. - * - * The @p from parameter is always set to @ref peerAddress() - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress &from); - - /** - * Writes data to the socket. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len); - - /** - * @overload - * Writes data to the socket. - * - * The @p to parameter is discarded. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to); - - /** - * Catch changes. - */ - virtual void enableRead(bool enable); - - /** - * Catch changes. - */ - virtual void enableWrite(bool enable); - - /** - * Sets the use of input buffering. - */ - void setInputBuffering(bool enable); - - /** - * Retrieves the input buffer object. - */ - KIOBufferBase* inputBuffer(); - - /** - * Sets the use of output buffering. - */ - void setOutputBuffering(bool enable); - - /** - * Retrieves the output buffer object. - */ - KIOBufferBase* outputBuffer(); - - /** - * Returns the length of the output buffer. - */ -#ifdef USE_QT3 - virtual TQ_ULONG bytesToWrite() const; -#endif -#ifdef USE_QT4 - virtual qint64 bytesToWrite() const; -#endif - - /** - * Closes the socket and discards any output data that had been buffered - * with @ref writeBlock but that had not yet been written. - * - * @sa close - */ - virtual void closeNow(); - - /** - * Returns true if a line can be read with @ref readLine - */ - bool canReadLine() const; - - /** - * Reads a line of data from the socket buffers. - */ - TQCString readLine(); - - // KDE4: make virtual, add timeout to match the Qt4 signature - // and move to another class up the hierarchy - /** - * Blocks until the connection is either established, or completely - * failed. - */ - void waitForConnect(); - -protected: - /** - * Catch connection to clear the buffers - */ - virtual void stateChanging(SocketState newState); - -protected slots: - /** - * Slot called when there's read activity. - */ - virtual void slotReadActivity(); - - /** - * Slot called when there's write activity. - */ - virtual void slotWriteActivity(); - -signals: - /** - * This signal is emitted whenever data is written. - */ - void bytesWritten(int bytes); - -private: - KBufferedSocket(const KBufferedSocket&); - KBufferedSocket& operator=(const KBufferedSocket&); - - KBufferedSocketPrivate *d; - -public: - // KDE4: remove this function - /** - * @deprecated - * Closes the socket. - * - * This function is provided to ease porting from KExtendedSocket, - * which required a call to reset() in order to be able to connect again - * using the same device. This is not necessary in KBufferedSocket any more. - */ -#ifdef USE_QT3 - inline void reset() -#endif -#ifdef USE_QT4 - inline bool reset() -#endif - { closeNow(); } -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kclientsocketbase.cpp b/kdecore/network/kclientsocketbase.cpp deleted file mode 100644 index 9785ce36c..000000000 --- a/kdecore/network/kclientsocketbase.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <tqsocketnotifier.h> -#include <tqtimer.h> -#include <tqmutex.h> - -#include "ksocketaddress.h" -#include "kresolver.h" -#include "ksocketbase.h" -#include "ksocketdevice.h" -#include "kclientsocketbase.h" - -using namespace KNetwork; - -class KNetwork::KClientSocketBasePrivate -{ -public: - int state; - - KResolver localResolver, peerResolver; - KResolverResults localResults, peerResults; - - bool enableRead : 1, enableWrite : 1; -}; - -KClientSocketBase::KClientSocketBase(TQObject *parent, const char *name) : -#ifdef USE_QT4 -#else // USE_QT4 - TQObject(parent, name), -#endif // USE_QT4 - d(new KClientSocketBasePrivate) -{ -#ifdef USE_QT4 - setParent(parent); - setObjectName(name); -#endif // USE_QT4 - d->state = Idle; - d->enableRead = true; - d->enableWrite = false; -} - -KClientSocketBase::~KClientSocketBase() -{ - close(); - delete d; -} - -KClientSocketBase::SocketState KClientSocketBase::state() const -{ - return static_cast<SocketState>(d->state); -} - -void KClientSocketBase::setState(SocketState state) -{ - d->state = state; - stateChanging(state); -} - -bool KClientSocketBase::setSocketOptions(int opts) -{ - TQMutexLocker locker(mutex()); - KSocketBase::setSocketOptions(opts); // call parent - - // don't create the device unnecessarily - if (hasDevice()) - { - bool result = socketDevice()->setSocketOptions(opts); // and set the implementation - copyError(); - return result; - } - - return true; -} - -KResolver& KClientSocketBase::peerResolver() const -{ - return d->peerResolver; -} - -const KResolverResults& KClientSocketBase::peerResults() const -{ - return d->peerResults; -} - -KResolver& KClientSocketBase::localResolver() const -{ - return d->localResolver; -} - -const KResolverResults& KClientSocketBase::localResults() const -{ - return d->localResults; -} - -void KClientSocketBase::setResolutionEnabled(bool enable) -{ - if (enable) - { - d->localResolver.setFlags(d->localResolver.flags() & ~KResolver::NoResolve); - d->peerResolver.setFlags(d->peerResolver.flags() & ~KResolver::NoResolve); - } - else - { - d->localResolver.setFlags(d->localResolver.flags() | KResolver::NoResolve); - d->peerResolver.setFlags(d->peerResolver.flags() | KResolver::NoResolve); - } -} - -void KClientSocketBase::setFamily(int families) -{ - d->localResolver.setFamily(families); - d->peerResolver.setFamily(families); -} - -bool KClientSocketBase::lookup() -{ - if (state() == HostLookup && !blocking()) - return true; // already doing lookup - - if (state() > HostLookup) - return true; // results are already available - - if (state() < HostLookup) - { - if (d->localResolver.serviceName().isNull() && - !d->localResolver.nodeName().isNull()) - d->localResolver.setServiceName(TQString::tqfromLatin1("")); - - // don't restart the lookups if they had succeeded and - // the input values weren't changed - TQObject::connect(&d->peerResolver, TQT_SIGNAL(finished(KResolverResults)), - this, TQT_SLOT(lookupFinishedSlot())); - TQObject::connect(&d->localResolver, TQT_SIGNAL(finished(KResolverResults)), - this, TQT_SLOT(lookupFinishedSlot())); - - if (d->localResolver.status() <= 0) - d->localResolver.start(); - if (d->peerResolver.status() <= 0) - d->peerResolver.start(); - - setState(HostLookup); - emit stateChanged(HostLookup); - - if (!d->localResolver.isRunning() && !d->peerResolver.isRunning()) - { - // if nothing is running, then the lookup results are still valid - // pretend we had done lookup - if (blocking()) - lookupFinishedSlot(); - else - TQTimer::singleShot(0, this, TQT_SLOT(lookupFinishedSlot())); - } - else - { - d->localResults = d->peerResults = KResolverResults(); - } - } - - if (blocking()) - { - // we're in blocking mode operation - // wait for the results - - localResolver().wait(); - peerResolver().wait(); - - // lookupFinishedSlot has been called - } - - return true; -} - -bool KClientSocketBase::bind(const KResolverEntry& address) -{ - if (state() == HostLookup || state() > Connecting) - return false; - - if (socketDevice()->bind(address)) - { - resetError(); - - // don't set the state or emit signals if we are in a higher state - if (state() < Bound) - { - setState(Bound); - emit stateChanged(Bound); - emit bound(address); - } - return true; - } - return false; -} - -bool KClientSocketBase::connect(const KResolverEntry& address) -{ - if (state() == Connected) - return true; // to be compliant with the other classes - if (state() == HostLookup || state() > Connecting) - return false; - - bool ok = socketDevice()->connect(address); - copyError(); - - if (ok) - { - SocketState newstate; - if (error() == InProgress) - newstate = Connecting; - else - newstate = Connected; - - if (state() < newstate) - { - setState(newstate); - emit stateChanged(newstate); - if (error() == NoError) - { - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); - emit connected(address); - } - } - - return true; - } - return false; -} - -bool KClientSocketBase::disconnect() -{ - if (state() != Connected) - return false; - - bool ok = socketDevice()->disconnect(); - copyError(); - - if (ok) - { - setState(Unconnected); - emit stateChanged(Unconnected); - return true; - } - return false; -} - -void KClientSocketBase::close() -{ - if (state() == Idle) - return; // nothing to do - - if (state() == HostLookup) - { - d->peerResolver.cancel(false); - d->localResolver.cancel(false); - } - - d->localResults = d->peerResults = KResolverResults(); - - socketDevice()->close(); - setState(Idle); - emit stateChanged(Idle); - emit closed(); -} - -// This function is unlike all the others because it is const -#ifdef USE_QT3 -TQ_LONG KClientSocketBase::bytesAvailable() const -#endif -#ifdef USE_QT4 -qint64 KClientSocketBase::bytesAvailable() const -#endif -{ - return socketDevice()->bytesAvailable(); -} - -// All the functions below look really alike -// Should I use a macro to define them? - -TQ_LONG KClientSocketBase::waitForMore(int msecs, bool *timeout) -{ - resetError(); - TQ_LONG retval = socketDevice()->waitForMore(msecs, timeout); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -TQT_TQIO_LONG KClientSocketBase::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen) -{ - resetError(); - TQ_LONG retval = socketDevice()->tqreadBlock(data, maxlen); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -TQT_TQIO_LONG KClientSocketBase::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress& from) -{ - resetError(); - TQ_LONG retval = socketDevice()->tqreadBlock(data, maxlen, from); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -TQ_LONG KClientSocketBase::peekBlock(char *data, TQ_ULONG maxlen) -{ - resetError(); - TQ_LONG retval = socketDevice()->peekBlock(data, maxlen); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -TQ_LONG KClientSocketBase::peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from) -{ - resetError(); - TQ_LONG retval = socketDevice()->peekBlock(data, maxlen, from); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -TQT_TQIO_LONG KClientSocketBase::tqwriteBlock(const char *data, TQT_TQIO_ULONG len) -{ - resetError(); - TQ_LONG retval = socketDevice()->tqwriteBlock(data, len); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -TQT_TQIO_LONG KClientSocketBase::tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to) -{ - resetError(); - TQ_LONG retval = socketDevice()->tqwriteBlock(data, len, to); - if (retval == -1) - { - copyError(); - emit gotError(error()); - } - return retval; -} - -KSocketAddress KClientSocketBase::localAddress() const -{ - return socketDevice()->localAddress(); -} - -KSocketAddress KClientSocketBase::peerAddress() const -{ - return socketDevice()->peerAddress(); -} - -bool KClientSocketBase::emitsReadyRead() const -{ - return d->enableRead; -} - -void KClientSocketBase::enableRead(bool enable) -{ - TQMutexLocker locker(mutex()); - - d->enableRead = enable; - TQSocketNotifier *n = socketDevice()->readNotifier(); - if (n) - n->setEnabled(enable); -} - -bool KClientSocketBase::emitsReadyWrite() const -{ - return d->enableWrite; -} - -void KClientSocketBase::enableWrite(bool enable) -{ - TQMutexLocker locker(mutex()); - - d->enableWrite = enable; - TQSocketNotifier *n = socketDevice()->writeNotifier(); - if (n) - n->setEnabled(enable); -} - -void KClientSocketBase::slotReadActivity() -{ - if (d->enableRead) - emit readyRead(); -} - -void KClientSocketBase::slotWriteActivity() -{ - if (d->enableWrite) - emit readyWrite(); -} - -void KClientSocketBase::lookupFinishedSlot() -{ - if (d->peerResolver.isRunning() || d->localResolver.isRunning() || state() != HostLookup) - return; - - TQObject::disconnect(&d->peerResolver, 0L, this, TQT_SLOT(lookupFinishedSlot())); - TQObject::disconnect(&d->localResolver, 0L, this, TQT_SLOT(lookupFinishedSlot())); - if (d->peerResolver.status() < 0 || d->localResolver.status() < 0) - { - setState(Idle); // backtrack - setError(IO_LookupError, LookupFailure); - emit stateChanged(Idle); - emit gotError(LookupFailure); - return; - } - - d->localResults = d->localResolver.results(); - d->peerResults = d->peerResolver.results(); - setState(HostFound); - emit stateChanged(HostFound); - emit hostFound(); -} - -void KClientSocketBase::stateChanging(SocketState newState) -{ - if (newState == Connected && socketDevice()) - { - TQSocketNotifier *n = socketDevice()->readNotifier(); - if (n) - { - n->setEnabled(d->enableRead); - TQObject::connect(n, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotReadActivity())); - } - else - return; - - n = socketDevice()->writeNotifier(); - if (n) - { - n->setEnabled(d->enableWrite); - TQObject::connect(n, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotWriteActivity())); - } - else - return; - } -} - -void KClientSocketBase::copyError() -{ - setError(socketDevice()->status(), socketDevice()->error()); -} - -#include "kclientsocketbase.moc" diff --git a/kdecore/network/kclientsocketbase.h b/kdecore/network/kclientsocketbase.h deleted file mode 100644 index 75e796ffc..000000000 --- a/kdecore/network/kclientsocketbase.h +++ /dev/null @@ -1,532 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KCLIENTSOCKETBASE_H -#define KCLIENTSOCKETBASE_H - -#include <tqobject.h> -#include <tqstring.h> - -#include "ksocketbase.h" -#include "kresolver.h" -#include <kdelibs_export.h> - -#ifdef Q_MOC_RUN -#define USE_QT4 -#endif // Q_MOC_RUN - -namespace KNetwork { - -class KClientSocketBasePrivate; -/** @class KClientSocketBase kclientsocketbase.h kclientsocketbase.h - * @brief Abstract client socket class. - * - * This class provides the base functionality for client sockets, - * such as, and especially, name resolution and signals. - * - * @note This class is abstract. If you're looking for a normal, - * client socket class, see @ref KStreamSocket and KBufferedSocket - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KClientSocketBase : -#ifdef USE_QT4 -#else // USE_QT4 -public TQObject, -#endif // USE_QT4 -public KActiveSocketBase -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Socket states. - * - * These are the possible states for a KClientSocketBase: - * - Idle: socket is not connected - * - HostLookup: socket is doing host lookup prior to connecting - * - HostFound: name lookup is complete - * - Bound: the socket is locally bound - * - Connecting: socket is attempting connection - * - Open: socket is open - * - Connected (=Open): socket is connected - * - Connection (=Open): yet another name for a connected socket - * - Closing: socket is shutting down - * - * Whenever the socket state changes, the @ref stateChanged(int) signal - * will be emitted. - */ - enum SocketState - { - Idle, - HostLookup, - HostFound, - Bound, - Connecting, - Open, - Closing, - - Unconnected = Bound, - Connected = Open, - Connection = Open - }; - -public: - /** - * Default constructor. - * - * @param parent the parent TQObject object - * @param name the name of this object - */ - KClientSocketBase(TQObject* parent, const char *name); - - /** - * Destructor. - */ - virtual ~KClientSocketBase(); - - /** - * Returns the current state for this socket. - * @see SocketState - */ - SocketState state() const; - -protected: - /** - * Sets the socket options. Reimplemented from KSocketBase. - */ - virtual bool setSocketOptions(int opts); - -public: - /** - * Returns the internal KResolver object used for - * looking up the peer host name and service. - * - * This can be used to set extra options to the - * lookup process other than the default values, as well - * as obtaining the error codes in case of lookup failure. - */ - KResolver& peerResolver() const; - - /** - * Returns the internal list of resolved results for the peer address. - */ - const KResolverResults& peerResults() const; - - /** - * Returns the internal KResolver object used for - * looking up the local host name and service. - * - * This can be used to set extra options to the - * lookup process other than the default values, as well - * as obtaining the error codes in case of lookup failure. - */ - KResolver& localResolver() const; - - /** - * Returns the internal list of resolved results for the local address. - */ - const KResolverResults& localResults() const; - - /** - * Enables or disables name resolution. If this flag is set to true, - * @ref bind and @ref connect operations will trigger name lookup - * operations (i.e., converting a hostname into its binary form). - * If the flag is set to false, those operations will instead - * try to convert a string representation of an address without - * attempting name resolution. - * - * This is useful, for instance, when IP addresses are in - * their string representation (such as "1.2.3.4") or come - * from other sources like @ref KSocketAddress. - * - * @param enable whether to enable - */ - void setResolutionEnabled(bool enable); - - /** - * Sets the allowed families for the resolutions. - * - * @param families the families that we want/accept - * @see KResolver::SocketFamilies for possible values - */ - void setFamily(int families); - - /** - * Starts the lookup for peer and local hostnames as - * well as their services. - * - * If the blocking mode for this object is on, this function will - * wait for the lookup results to be available (by calling the - * @ref KResolver::wait method on the resolver objects). - * - * When the lookup is done, the signal @ref hostFound will be - * emitted (only once, even if we're doing a double lookup). - * If the lookup failed (for any of the two lookups) the - * @ref gotError signal will be emitted with the appropriate - * error condition (see @ref KSocketBase::SocketError). - * - * This function returns true on success and false on error. Note that - * this is not the lookup result! - */ - virtual bool lookup(); - - /** - * Binds this socket to the given nodename and service, - * or use the default ones if none are given. - * - * Upon successful binding, the @ref bound signal will be - * emitted. If an error is found, the @ref gotError - * signal will be emitted. - * - * @note Due to the internals of the name lookup and binding - * mechanism, some (if not most) implementations of this function - * do not actually bind the socket until the connection - * is requested (see @ref connect). They only set the values - * for future reference. - * - * This function returns true on success. - * - * @param node the nodename - * @param service the service - */ - virtual bool bind(const TQString& node = TQString::null, - const TQString& service = TQString::null) = 0; - - /** - * Reimplemented from KSocketBase. Connect this socket to this - * specific address. - * - * Unlike @ref bind(const TQString&, const TQString&) above, this function - * really does bind the socket. No lookup is performed. The @ref bound - * signal will be emitted. - */ - virtual bool bind(const KResolverEntry& address); - - /** - * Attempts to connect to the these hostname and service, - * or use the default ones if none are given. If a connection attempt - * is already in progress, check on its state and set the error status - * (NoError or InProgress). - * - * If the blocking mode for this object is on, this function will only - * return when all the resolved peer addresses have been tried or when - * a connection is established. - * - * Upon successfully connecting, the @ref connected signal - * will be emitted. If an error is found, the @ref gotError - * signal will be emitted. - * - * @par Note for derived classes: - * Derived classes must implement this function. The implementation - * will set the parameters for the lookup (using the peer KResolver - * object) and call @ref lookup to start it. - * - * @par - * The implementation should use the @ref hostFound - * signal to be notified of the completion of the lookup process and - * then proceed to start the connection itself. Care should be taken - * regarding the value of @ref blocking flag. - * - * @param node the nodename - * @param service the service - */ - virtual bool connect(const TQString& node = TQString::null, - const TQString& service = TQString::null) = 0; - - /** - * @overload - * Reimplemented from KSocketBase. - */ - virtual bool connect(const KResolverEntry& address); - - /** - * @deprecated - * This is a convenience function provided to ease migrating from - * Qt 3.x's TQSocket class. - */ - inline void connectToHost(const TQString& host, TQ_UINT16 port) - { connect(host, TQString::number(port)); } - - /** - * Disconnects the socket. - * Note that not all socket types can disconnect. - */ - virtual bool disconnect(); - - /** - * Opens the socket. Reimplemented from TQIODevice. - * - * You should not call this function; instead, use @ref connect - */ - virtual inline bool open(TQ_OpenMode) - { return connect(); } - - /** - * Closes the socket. Reimplemented from TQIODevice. - * - * The closing of the socket causes the emission of the - * signal @ref closed. - */ - virtual void close(); - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - */ - virtual void flush() - { } - - /** - * Returns the number of bytes available on this socket. - * Reimplemented from KSocketBase. - */ -#ifdef USE_QT3 - virtual TQ_LONG bytesAvailable() const; -#endif -#ifdef USE_QT4 - virtual qint64 bytesAvailable() const; -#endif - - /** - * Waits for more data. Reimplemented from KSocketBase. - */ - virtual TQ_LONG waitForMore(int msecs, bool *timeout = 0L); - - /** - * Reads data from a socket. Reimplemented from KSocketBase. - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen); - - /** - * @overload - * Reads data from a socket. Reimplemented from KSocketBase. - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress& from); - - /** - * Peeks data from the socket. Reimplemented from KSocketBase. - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen); - - /** - * @overload - * Peeks data from the socket. Reimplemented from KSocketBase. - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress &from); - - /** - * Writes data to the socket. Reimplemented from KSocketBase. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len); - - /** - * @overload - * Writes data to the socket. Reimplemented from KSocketBase. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to); - - /** - * Returns the local socket address. Reimplemented from KSocketBase. - */ - virtual KSocketAddress localAddress() const; - - /** - * Returns the peer socket address. Reimplemented from KSocketBase. - */ - virtual KSocketAddress peerAddress() const; - - /** - * Returns true if the readyRead signal is set to be emitted. - */ - bool emitsReadyRead() const; - - /** - * Enables the emission of the readyRead signal. - * By default, this signal is enabled. - * - * @param enable whether to enable the signal - */ - virtual void enableRead(bool enable); - - /** - * Returns true if the readyWrite signal is set to be emitted. - */ - bool emitsReadyWrite() const; - - /** - * Enables the emission of the readyWrite signal. - * By default, this signal is disabled. - * - * @param enable whether to enable the signal - */ - virtual void enableWrite(bool enable); - -protected slots: - // protected slots - - /** - * This slot is connected to the read notifier's signal meaning - * the socket can read more data. - * - * The default implementation only emits the readyRead signal. - * - * Override if your class requires processing of incoming - * data. - */ - virtual void slotReadActivity(); - - /** - * This slot is connected to the write notifier's signal - * meaning the socket can write more data. - * - * The default implementation only emits the readyWrite signal. - * - * Override if your class writes data from another source - * (like a buffer). - */ - virtual void slotWriteActivity(); - -private slots: - void lookupFinishedSlot(); - -signals: - /** - * This signal is emitted whenever the socket state changes. - * - * Note: do not delete this object inside the slot called by this - * signal. - * - * @param newstate the new state of the socket object - */ - void stateChanged(int newstate); - - /** - * This signal is emitted when this object finds an error. - * The @p code parameter contains the error code that can - * also be found by calling @ref error. - */ - void gotError(int code); - - /** - * This signal is emitted when the lookup is successfully completed. - */ - void hostFound(); - - /** - * This signal is emitted when the socket successfully binds - * to an address. - * - * @param local the local address we bound to - */ - void bound(const KResolverEntry& local); - - /** - * This signal is emitted when the socket is about to connect - * to an address (but before doing so). - * - * The @p skip parameter can be used to make the loop skip this address. - * Its value is initially false: change it to true if you want to - * skip the current address (as given by @p remote). - * - * This function is also useful if one wants to reset the timeout. - * - * @param remote the address we're about to connect to - * @param skip set to true if you want to skip this address - * @note if the connection is successful, the @ref connected signal will be - * emitted. - */ - void aboutToConnect(const KResolverEntry& remote, bool& skip); - - /** - * This socket is emitted when the socket successfully connects - * to a remote address. - * - * @param remote the remote address we did connect to - */ - void connected(const KResolverEntry& remote); - - /** - * This signal is emitted when the socket completes the - * closing/shut down process. - */ - void closed(); - - /** - * This signal is emitted whenever the socket is ready for - * reading -- i.e., there is data to be read in the buffers. - * The subsequent read operation is guaranteed to be non-blocking. - * - * You can toggle the emission of this signal with the @ref enableRead - * function. This signal is by default enabled. - */ - void readyRead(); - - /** - * This signal is emitted whenever the socket is ready for - * writing -- i.e., whenever there's space available in the buffers - * to receive more data. The subsequent write operation is - * guaranteed to be non-blocking. - * - * You can toggle the emission of this signal with the @ref enableWrite - * function. This signal is by default disabled. You will - * want to disable this signal after the first reception, since - * it'll probably fire at every event loop. - */ - void readyWrite(); - -protected: - /** - * Sets the socket state to @p state. This function does not - * emit the @ref stateChanged signal. - */ - void setState(SocketState state); - - /** - * This function is called by @ref setState whenever the state - * changes. You should override it if you need to specify any - * actions to be done when the state changes. - * - * The default implementation acts for these states only: - * - Connected: it sets up the socket notifiers to fire readyRead and - * readyWrite signals. - */ - virtual void stateChanging(SocketState newState); - - /** - * Convenience function to set this object's error code to match - * that of the socket device. - */ - void copyError(); - -private: - KClientSocketBase(const KClientSocketBase&); - KClientSocketBase& operator=(const KClientSocketBase&); - - KClientSocketBasePrivate *d; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kdatagramsocket.cpp b/kdecore/network/kdatagramsocket.cpp deleted file mode 100644 index d4bddc543..000000000 --- a/kdecore/network/kdatagramsocket.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2004 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/socket.h> - -#include "ksocketaddress.h" -#include "kresolver.h" -#include "ksocketdevice.h" -#include "kdatagramsocket.h" - -using namespace KNetwork; - -/* - * TODO: - * - * don't use signals and slots to track state changes: use stateChanging - * - */ - -KDatagramSocket::KDatagramSocket(TQObject* parent, const char *name) - : KClientSocketBase(parent, name), d(0L) -{ - peerResolver().setFamily(KResolver::KnownFamily); - localResolver().setFamily(KResolver::KnownFamily); - - peerResolver().setSocketType(SOCK_DGRAM); - localResolver().setSocketType(SOCK_DGRAM); - - localResolver().setFlags(KResolver::Passive); - - // TQObject::connect(localResolver(), TQT_SIGNAL(finished(KResolverResults)), - // this, TQT_SLOT(lookupFinishedLocal())); - TQObject::connect(&peerResolver(), TQT_SIGNAL(finished(KResolverResults)), - this, TQT_SLOT(lookupFinishedPeer())); - TQObject::connect(this, TQT_SIGNAL(hostFound()), this, TQT_SLOT(lookupFinishedLocal())); -} - -KDatagramSocket::~KDatagramSocket() -{ - // KClientSocketBase's destructor closes the socket - - //delete d; -} - -bool KDatagramSocket::bind(const TQString& node, const TQString& service) -{ - if (state() >= Bound) - return false; - - if (localResolver().isRunning()) - localResolver().cancel(false); - - // no, we must do a host lookup - localResolver().setAddress(node, service); - - if (!lookup()) - return false; - - // see if lookup has finished already - // this also catches blocking mode, since lookup has to finish - // its processing if we're in blocking mode - if (state() > HostLookup) - return doBind(); - - return true; -} - -bool KDatagramSocket::connect(const TQString& node, const TQString& service) -{ - if (state() >= Connected) - return true; // already connected - - if (peerResolver().nodeName() != node || - peerResolver().serviceName() != service) - peerResolver().setAddress(node, service); // this resets the resolver's state - - // KClientSocketBase::lookup only works if the state is Idle or HostLookup - // therefore, we store the old state, call the lookup routine and then set - // it back. - SocketState s = state(); - setState(s == Connecting ? HostLookup : Idle); - bool ok = lookup(); - if (!ok) - { - setState(s); // go back - return false; - } - - // check if lookup is finished - // if we're in blocking mode, then the lookup has to be finished - if (state() == HostLookup) - { - // it hasn't finished - setState(Connecting); - emit stateChanged(Connecting); - return true; - } - - // it has to be finished here - if (state() != Connected) - { - setState(Connecting); - emit stateChanged(Connecting); - lookupFinishedPeer(); - } - - return state() == Connected; -} - -KDatagramPacket KDatagramSocket::receive() -{ - TQ_LONG size = bytesAvailable(); - if (size == 0) - { - // nothing available yet to read - // wait for data if we're not blocking - if (blocking()) - socketDevice()->waitForMore(-1); // wait forever - else - { - // mimic error - setError(IO_ReadError, WouldBlock); - emit gotError(WouldBlock); - return KDatagramPacket(); - } - - // try again - size = bytesAvailable(); - } - - TQByteArray data(size); - KSocketAddress address; - - // now do the reading - size = tqreadBlock(data.data(), size, address); - if (size < 0) - // error has been set - return KDatagramPacket(); - - data.resize(size); // just to be sure - return KDatagramPacket(data, address); -} - -TQ_LONG KDatagramSocket::send(const KDatagramPacket& packet) -{ - return tqwriteBlock(packet.data(), packet.size(), packet.address()); -} - -TQ_LONG KDatagramSocket::tqwriteBlock(const char *data, TQ_ULONG len, const KSocketAddress& to) -{ - if (to.family() != AF_UNSPEC) - { - // make sure the socket is open at this point - if (!socketDevice()->isOpen()) - // error handling will happen below - socketDevice()->create(to.family(), SOCK_DGRAM, 0); - } - return KClientSocketBase::tqwriteBlock(data, len, to); -} - -void KDatagramSocket::lookupFinishedLocal() -{ - // bind lookup has finished and succeeded - // state() == HostFound - - if (!doBind()) - return; // failed binding - - if (peerResults().count() > 0) - { - setState(Connecting); - emit stateChanged(Connecting); - - lookupFinishedPeer(); - } -} - -void KDatagramSocket::lookupFinishedPeer() -{ - // this function is called by lookupFinishedLocal above - // and is also connected to a signal - // so it might be called twice. - - if (state() != Connecting) - return; - - if (peerResults().count() == 0) - { - setState(Unconnected); - emit stateChanged(Unconnected); - return; - } - - KResolverResults::ConstIterator it = peerResults().begin(); - for ( ; it != peerResults().end(); ++it) - if (connect(*it)) - { - // weee, we connected - - setState(Connected); // this sets up signals - //setupSignals(); // setState sets up the signals - - emit stateChanged(Connected); - emit connected(*it); - return; - } - - // no connection - copyError(); - setState(Unconnected); - emit stateChanged(Unconnected); - emit gotError(error()); -} - -bool KDatagramSocket::doBind() -{ - if (localResults().count() == 0) - return true; - if (state() >= Bound) - return true; // already bound - - KResolverResults::ConstIterator it = localResults().begin(); - for ( ; it != localResults().end(); ++it) - if (bind(*it)) - { - // bound - setupSignals(); - return true; - } - - // not bound - // no need to set state since it can only be HostFound already - copyError(); - emit gotError(error()); - return false; -} - -void KDatagramSocket::setupSignals() -{ - TQSocketNotifier *n = socketDevice()->readNotifier(); - if (n) - { - n->setEnabled(emitsReadyRead()); - TQObject::connect(n, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotReadActivity())); - } - else - return; - - n = socketDevice()->writeNotifier(); - if (n) - { - n->setEnabled(emitsReadyWrite()); - TQObject::connect(n, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotWriteActivity())); - } - else - return; -} - -#include "kdatagramsocket.moc" diff --git a/kdecore/network/kdatagramsocket.h b/kdecore/network/kdatagramsocket.h deleted file mode 100644 index becbe404a..000000000 --- a/kdecore/network/kdatagramsocket.h +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KDATAGRAMSOCKET_H -#define KDATAGRAMSOCKET_H - -#include <tqcstring.h> - -#include "ksocketaddress.h" -#include "kclientsocketbase.h" - -namespace KNetwork { - -class KResolverEntry; - -/** - * @class KDatagramPacket kdatagramsocket.h kdatagramsocket.h - * @brief one datagram - * - * This object represents one datagram of data sent or received through - * a datagram socket (as @ref KDatagramSocket or derived classes). A datagram - * consists of data as well as a network address associated (whither to send - * the data or whence it came). - * - * This is a lightweight class. Data is stored in a @ref TQByteArray, which means - * that it is explicitly shared. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KDatagramPacket -{ - TQByteArray m_data; - KSocketAddress m_address; - -public: - /** - * Default constructor. - */ - KDatagramPacket() - { } - - /** - * Constructs the datagram with the specified content. - */ - KDatagramPacket(const TQByteArray& content) - : m_data(content) - { } - - /** - * Constructs the datagram with the specified content. - * - * @see setData for information on data sharing. - */ - KDatagramPacket(const char* content, uint length) - { setData(content, length); } - - /** - * Constructs the datagram with the specified content and address. - */ - KDatagramPacket(const TQByteArray& content, const KSocketAddress& addr) - : m_data(content), m_address(addr) - { } - - /** - * Constructs the datagram with the specified content and address. - */ - KDatagramPacket(const char *content, uint length, const KSocketAddress& addr) - : m_address(addr) - { setData(content, length); } - - /** - * Copy constructor. Note that data is explicitly shared. - */ - KDatagramPacket(const KDatagramPacket& other) - { *this = other; } - - /** - * Destructor. Non-virtual. - */ - ~KDatagramPacket() - { } - - /** - * Returns the data. - */ - const TQByteArray& data() const - { return m_data; } - - /** - * Returns the data length. - */ - uint length() const - { return m_data.size(); } - - /** - * Returns the data length. - */ - uint size() const - { return m_data.size(); } - - /** - * Returns true if this object is empty. - */ - bool isEmpty() const - { return m_data.isEmpty(); } - - /** - * Returns true if this object is null. - */ - bool isNull() const - { return m_data.isNull(); } - - /** - * Returns the socket address - */ - const KSocketAddress& address() const - { return m_address; } - - /** - * Sets the address stored to the given value. - */ - void setAddress(const KSocketAddress& addr) - { m_address = addr; } - - /** - * Detaches our data from a shared pool. - * @see TQByteArray::detach - */ - void detach() - { m_data.detach(); } - - /** - * Sets the data to the given value. Data is explicitly shared. - */ - void setData(const TQByteArray& data) - { m_data = data; } - - /** - * Sets the data to the given buffer and size. - */ - void setData(const char* data, uint length) - { m_data.duplicate(data, length); } -}; - -class KDatagramSocketPrivate; -/** - * @class KDatagramSocket kdatagramsocket.h kdatagramsocket.h - * @brief A socket that operates on datagrams. - * - * Unlike @ref KStreamSocket, which operates on a connection-based stream - * socket (generally TCP), this class and its descendants operates on datagrams, - * which are normally connectionless. - * - * This class in specific provides easy access to the system's connectionless - * SOCK_DGRAM sockets. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KDatagramSocket: public KClientSocketBase -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Default constructor. - */ - KDatagramSocket(TQObject* parent = 0L, const char *name = 0L); - - /** - * Destructor. This closes the socket. - */ - virtual ~KDatagramSocket(); - - /** - * Performs host lookups. - */ - // virtual bool lookup(); - - /** - * Binds this socket to the given address. If the socket is blocking, - * the socket will be bound when this function returns. - * - * Note that binding a socket is not necessary to be able to send datagrams. - * Some protocol families will use anonymous source addresses, while others - * will allocate an address automatically. - */ - virtual bool bind(const TQString& node = TQString::null, - const TQString& service = TQString::null); - - /** - * @overload - * Binds this socket to the given address. - */ - virtual bool bind(const KResolverEntry& entry) - { return KClientSocketBase::bind(entry); } - - /** - * "Connects" this socket to the given address. Note that connecting - * a datagram socket normally does not establish a permanent connection - * with the peer nor normally returns an error in case of failure. - * - * Connecting means only to designate the given address as the default - * destination address for datagrams sent without destination addresses - * ( tqwriteBlock(const char *, TQ_ULONG) ). - * - * @note Calling connect will not cause the socket to be bound. You have - * to call @ref bind explicitly. - */ - virtual bool connect(const TQString& node = TQString::null, - const TQString& service = TQString::null); - - /** - * @overload - * "Connects" this socket to the given address. - */ - virtual bool connect(const KResolverEntry& entry) - { return KClientSocketBase::connect(entry); } - - /** - * Writes data to the socket. Reimplemented from KClientSocketBase. - */ - virtual TQ_LONG tqwriteBlock(const char *data, TQ_ULONG len, const KSocketAddress& to); - - /** - * Receives one datagram from the stream. The reading process is guaranteed - * to be atomical and not lose data from the packet. - * - * If nothing could be read, a null object will be returned. - */ - virtual KDatagramPacket receive(); - - /** - * Sends one datagram into the stream. The destination address must be - * set if this socket has not been connected (see @ref connect). - * - * The data in this packet will be sent only in one single datagram. If the - * system cannot send it like that, this function will fail. So, please take - * into consideration the datagram size limits. - * - * @returns the number of bytes written or -1 in case of error. - */ - virtual TQ_LONG send(const KDatagramPacket& packet); - -private slots: - void lookupFinishedLocal(); - void lookupFinishedPeer(); - -private: - bool doBind(); - void setupSignals(); - - KDatagramSocketPrivate *d; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/khttpproxysocketdevice.cpp b/kdecore/network/khttpproxysocketdevice.cpp deleted file mode 100644 index 648f4e571..000000000 --- a/kdecore/network/khttpproxysocketdevice.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/socket.h> - -#include <tqsocketnotifier.h> -#include <tqcstring.h> - -#include "kresolver.h" -#include "ksocketaddress.h" -#include "ksocketdevice.h" -#include "khttpproxysocketdevice.h" - -using namespace KNetwork; - -KResolverEntry KHttpProxySocketDevice::defaultProxy; - -class KNetwork::KHttpProxySocketDevicePrivate -{ -public: - KResolverEntry proxy; - TQCString request; - TQCString reply; - KSocketAddress peer; - - KHttpProxySocketDevicePrivate() - : proxy(KHttpProxySocketDevice::defaultProxy) - { } -}; - -KHttpProxySocketDevice::KHttpProxySocketDevice(const KSocketBase* parent) - : KSocketDevice(parent), d(new KHttpProxySocketDevicePrivate) -{ -} - -KHttpProxySocketDevice::KHttpProxySocketDevice(const KResolverEntry& proxy) - : d(new KHttpProxySocketDevicePrivate) -{ - d->proxy = proxy; -} - -KHttpProxySocketDevice::~KHttpProxySocketDevice() -{ - // nothing special to be done during closing - // KSocketDevice::~KSocketDevice closes the socket - - delete d; -} - -int KHttpProxySocketDevice::capabilities() const -{ - return CanConnectString | CanNotBind | CanNotListen | CanNotUseDatagrams; -} - -const KResolverEntry& -KHttpProxySocketDevice::proxyServer() const -{ - return d->proxy; -} - -void KHttpProxySocketDevice::setProxyServer(const KResolverEntry& proxy) -{ - d->proxy = proxy; -} - -void KHttpProxySocketDevice::close() -{ - d->reply = d->request = TQCString(); - d->peer = KSocketAddress(); - KSocketDevice::close(); -} - -KSocketAddress KHttpProxySocketDevice::peerAddress() const -{ - if (isOpen()) - return d->peer; - return KSocketAddress(); -} - -KSocketAddress KHttpProxySocketDevice::externalAddress() const -{ - return KSocketAddress(); -} - -bool KHttpProxySocketDevice::connect(const KResolverEntry& address) -{ - if (d->proxy.family() == AF_UNSPEC) - // no proxy server set ! - return KSocketDevice::connect(address); - - if (isOpen()) - { - // socket is already open - resetError(); - return true; - } - - if (m_sockfd == -1) - // socket isn't created yet - return connect(address.address().nodeName(), - address.address().serviceName()); - - d->peer = address.address(); - return parseServerReply(); -} - -bool KHttpProxySocketDevice::connect(const TQString& node, const TQString& service) -{ - // same safety checks as above - if (m_sockfd == -1 && (d->proxy.family() == AF_UNSPEC || - node.isEmpty() || service.isEmpty())) - { - // no proxy server set ! - setError(IO_ConnectError, NotSupported); - return false; - } - - if (isOpen()) - { - // socket is already open - return true; - } - - if (m_sockfd == -1) - { - // must create the socket - if (!KSocketDevice::connect(d->proxy)) - return false; // also unable to contact proxy server - setState(0); // unset open flag - - // prepare the request - TQString request = TQString::tqfromLatin1("CONNECT %1:%2 HTTP/1.1\r\n" - "Cache-Control: no-cache\r\n" - "Host: \r\n" - "\r\n"); - TQString node2 = node; - if (node.contains(':')) - node2 = '[' + node + ']'; - - d->request = TQString(request.arg(node2).arg(service)).latin1(); - } - - return parseServerReply(); -} - -bool KHttpProxySocketDevice::parseServerReply() -{ - // make sure we're connected - if (!KSocketDevice::connect(d->proxy)) - if (error() == InProgress) - return true; - else if (error() != NoError) - return false; - - if (!d->request.isEmpty()) - { - // send request - TQ_LONG written = tqwriteBlock(d->request, d->request.length()); - if (written < 0) - { - qDebug("KHttpProxySocketDevice: would block writing request!"); - if (error() == WouldBlock) - setError(IO_ConnectError, InProgress); - return error() == WouldBlock; // error - } - qDebug("KHttpProxySocketDevice: request written"); - - d->request.remove(0, written); - - if (!d->request.isEmpty()) - { - setError(IO_ConnectError, InProgress); - return true; // still in progress - } - } - - // request header is sent - // must parse reply, but must also be careful not to read too much - // from the buffer - - int index; - if (!blocking()) - { - TQ_LONG avail = bytesAvailable(); - qDebug("KHttpProxySocketDevice: %ld bytes available", avail); - setState(0); - if (avail == 0) - { - setError(IO_ConnectError, InProgress); - return true; - } - else if (avail < 0) - return false; // error! - - TQByteArray buf(avail); - if (peekBlock(buf.data(), avail) < 0) - return false; // error! - - TQCString fullHeaders = d->reply + buf.data(); - // search for the end of the headers - index = fullHeaders.find("\r\n\r\n"); - if (index == -1) - { - // no, headers not yet finished... - // consume data from socket - tqreadBlock(buf.data(), avail); - d->reply += buf.data(); - setError(IO_ConnectError, InProgress); - return true; - } - - // headers are finished - index -= d->reply.length(); - d->reply += fullHeaders.mid(d->reply.length(), index + 4); - - // consume from socket - tqreadBlock(buf.data(), index + 4); - } - else - { - int state = 0; - if (d->reply.right(3) == "\r\n\r") - state = 3; - else if (d->reply.right(2) == "\r\n") - state = 2; - else if (d->reply.right(1) == "\r") - state = 1; - while (state != 4) - { - char c = getch(); - d->reply += c; - - if ((state == 3 && c == '\n') || - (state == 1 && c == '\n') || - c == '\r') - ++state; - else - state = 0; - } - } - - // now really parse the reply - qDebug("KHttpProxySocketDevice: get reply: %s\n", - d->reply.left(d->reply.find('\r')).data()); - if (d->reply.left(7) != "HTTP/1." || - (index = d->reply.find(' ')) == -1 || - d->reply[index + 1] != '2') - { - setError(IO_ConnectError, NetFailure); - return false; - } - - // we've got it - resetError(); - setState(IO_Open); - return true; -} diff --git a/kdecore/network/khttpproxysocketdevice.h b/kdecore/network/khttpproxysocketdevice.h deleted file mode 100644 index 7c9908ad5..000000000 --- a/kdecore/network/khttpproxysocketdevice.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KHTTPPROXYSOCKETDEVICE_H -#define KHTTPPROXYSOCKETDEVICE_H - -#include "ksocketdevice.h" - -namespace KNetwork { - -class KHttpProxySocketDevicePrivate; - -/** - * @class KHttpProxySocketDevice khttpproxysocketdevice.h khttproxysocketdevice.h - * @brief The low-level backend for HTTP proxying. - * - * This class derives from @ref KSocketDevice and implements the necessary - * calls to make a connection through an HTTP proxy. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KHttpProxySocketDevice: public KSocketDevice -{ -public: - /** - * Constructor. - */ - KHttpProxySocketDevice(const KSocketBase* = 0L); - - /** - * Constructor with proxy server's address. - */ - KHttpProxySocketDevice(const KResolverEntry& proxy); - - /** - * Destructor - */ - virtual ~KHttpProxySocketDevice(); - - /** - * Sets our capabilities. - */ - virtual int capabilities() const; - - /** - * Retrieves the proxy server address. - */ - const KResolverEntry& proxyServer() const; - - /** - * Sets the proxy server address. - */ - void setProxyServer(const KResolverEntry& proxy); - - /** - * Closes the socket. - */ - virtual void close(); - - /** - * Overrides connection. - */ - virtual bool connect(const KResolverEntry& address); - - /** - * Name-based connection. - * We can tell the HTTP proxy server the full name. - */ - virtual bool connect(const TQString& name, const TQString& service); - - /** - * Return the peer address. - */ - virtual KSocketAddress peerAddress() const; - - /** - * Return the externally visible address. We can't tell what that address is, - * so this function always returns an empty object. - */ - virtual KSocketAddress externalAddress() const; - -private: - /** - * Parses the server reply after sending the connect command. - * Returns true on success and false on failure. - */ - bool parseServerReply(); - KHttpProxySocketDevicePrivate *d; - -public: - /** - * This is the default proxy server to be used. - * Applications may want to set this value so that calling @ref setProxyServer - * is unnecessary. - */ - static KResolverEntry defaultProxy; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kiobuffer.h b/kdecore/network/kiobuffer.h deleted file mode 100644 index 02f75a420..000000000 --- a/kdecore/network/kiobuffer.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KIOBUFFER_H -#define KIOBUFFER_H - -#include <tqcstring.h> - -#include <kdelibs_export.h> - -class TQIODevice; - -/** - * @class KIOBufferBase kiobuffer.h kiobuffer.h - * @brief base for I/O buffer implementation - * - * This class declares the base methods to interface with an I/O buffer. - * Most applications will not need to access this class directly, since - * it is all handled by @ref KNetwork::KBufferedSocket and other buffering - * classes. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KIOBufferBase -{ -public: - /** - * Default constructor. Does nothing. - */ - KIOBufferBase() - { } - - /** - * Copy constructor. Does nothing here. - */ - KIOBufferBase(const KIOBufferBase& ) - { } - - /** - * Virtual destructor. Does nothing. - */ - virtual ~KIOBufferBase() - { } - - /** - * Assignment operator. Does nothing. - */ - KIOBufferBase& operator=(const KIOBufferBase& ) - { return *this; } - - /** - * Returns true if a line can be read from the buffer. - */ - virtual bool canReadLine() const = 0; - - /** - * Reads a line from the buffer and discards it. - */ - virtual TQCString readLine() = 0; - - /** - * Returns the number of bytes in the buffer. Note that this is not - * the size of the buffer. - * - * @sa size - */ - virtual TQ_LONG length() const = 0; - - /** - * Returns true if the buffer is empty of data. - */ - inline bool isEmpty() const - { return length() == 0; } - - /** - * Retrieves the buffer size. The value of -1 indicates that - * the buffer has no defined upper limit. - * - * @sa length for the length of the data stored - */ - virtual TQ_LONG size() const = 0; - - /** - * Returns true if the buffer is full (i.e., cannot receive more data) - */ - inline bool isFull() const - { return size() != -1 && size() == length(); } - - /** - * Sets the size of the buffer, if allowed. - * - * @param size the maximum size, use -1 for unlimited. - * @returns true on success, false if an error occurred. - * @note if the new size is less than length(), the buffer will be truncated - */ - virtual bool setSize(TQ_LONG size) = 0; - - /** - * Adds data to the end of the buffer. - * - * @param data the data to be added - * @param len the data length, in bytes - * @returns the number of bytes added to the end of the buffer. - */ - virtual TQ_LONG feedBuffer(const char *data, TQ_LONG len) = 0; - - /** - * Consumes data from the beginning of the buffer. - * - * @param data where to copy the data to - * @param maxlen the maximum length to copy, in bytes - * @param discard if true, the bytes copied will be discarded - * @returns the number of bytes copied from the buffer - */ - virtual TQ_LONG consumeBuffer(char *data, TQ_LONG maxlen, bool discard = true) = 0; - - /** - * Clears the buffer. - */ - virtual void clear() = 0; -}; - -#endif diff --git a/kdecore/network/kmulticastsocket.h b/kdecore/network/kmulticastsocket.h deleted file mode 100644 index 7fbd6e0f2..000000000 --- a/kdecore/network/kmulticastsocket.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KMULTICASTSOCKET_H -#define KMULTICASTSOCKET_H - -#include "kdatagramsocket.h" -#include "kmulticastsocketdevice.h" - -namespace KNetwork { - -class KMulticastSocketPrivate; -/** - * @class KMulticastSocket kmulticastsocket.h kmulticastsocket.h - * @brief A multicast-capable datagram socket class - * - * This class derives from @ref KDatagramSocket adding methods to it to - * allow better control over the multicast functionality. In special, - * the join and leave group functions are added. - * - * Other more low-level options on multicast sockets can be accessed - * directly with the @ref KMulticastSocketImpl class returned by - * @ref multicastSocketDevice. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KMulticastSocket: public KDatagramSocket -{ - // Q_add-it-here_OBJECT -public: - /** - * Constructor. - */ - KMulticastSocket(TQObject* parent = 0L, const char *name = 0L); - - /** - * Destructor. - */ - ~KMulticastSocket(); - - /** - * Returns the multicast socket device in use by this object. - * - * @note The returned object can be null. - */ - KMulticastSocketImpl* multicastSocketDevice(); - - /** - * @overload - */ - const KMulticastSocketImpl* multicastSocketDevice() const; - - /** - * Joins a multicast group. The group to be joined is identified by the - * @p group parameter. - * - * @param group the multicast group to join - * @returns true on success - */ - virtual bool joinGroup(const KSocketAddress& group); - - /** - * @overload - * Joins a multicast group. This function also specifies the network interface - * to be used. - */ - virtual bool joinGroup(const KSocketAddress& group, - const KNetworkInterface& iface); - - /** - * Leaves a multicast group. The group being left is given by its address in the - * @p group parameter. - * - * @param group the group to leave - * @returns true on successful leaving the group - */ - virtual bool leaveGroup(const KSocketAddress& group); - - /** - * @overload - * Leaves a multicast group. - */ - virtual bool leaveGroup(const KSocketAddress& group, - const KNetworkInterface& iface); - -private: - KMulticastSocketPrivate *d; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kmulticastsocketdevice.h b/kdecore/network/kmulticastsocketdevice.h deleted file mode 100644 index 7710fe5c1..000000000 --- a/kdecore/network/kmulticastsocketdevice.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KMULTICASTSOCKETDEVICE_H -#define KMULTICASTSOCKETDEVICE_H - -#include "ksocketdevice.h" -#include "knetworkinterface.h" -#include "ksocketaddress.h" - -namespace KNetwork { - -class KMulticastSocketImplPrivate; - -/** - * @class KMulticastSocketImpl kmulticastsocketdevice.h kmulticastsocketdevice.h - * @brief The low-level backend for multicasting sockets. - * - * This class is an interface providing methods for handling multicast - * operations. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KMulticastSocketImpl: public KSocketDevice -{ -public: - /** - * Constructor. - */ - KMulticastSocketImpl(const KSocketBase* = 0L); - - /** - * Destructor - */ - virtual ~KMulticastSocketImpl(); - - /** - * Sets our capabilities. - */ - virtual int capabilities() const; - - /** - * Overrides the socket creation. - */ - virtual bool create(int family, int type, int protocol); - - /** - * Overrides connection. Multicast sockets may not connect. - */ - virtual bool connect(const KResolverEntry& address); - - /** - * Retrieves the time-to-live/hop count value on multicast packets being sent. - */ - virtual int timeToLive() const; - - /** - * Sets the time-to-live/hop count for outgoing multicast packets. - * - * @param ttl the hop count, from 0 to 255 - * @returns true if setting the value was successful. - */ - virtual bool setTimeToLive(int ttl); - - /** - * Retrieves the flag indicating if sent packets will be echoed back - * to sender. - */ - virtual bool multicastLoop() const; - - /** - * Sets the flag indicating the loopback of packets to the sender. - * - * @param enable if true, will echo back - * @returns true if setting the value was successful. - */ - virtual bool setMulticastLoop(bool enable); - - /** - * Retrieves the network interface this socket is associated to. - */ - virtual KNetworkInterface networkInterface(); - - /** - * Sets the network interface on which this socket should work. - * - * @param iface the interface to associate with - * @return true if setting the value was successful. - */ - virtual bool setNetworkInterface(const KNetworkInterface& iface); - - /** - * Joins a multicast group. The group to be joined is identified by the - * @p group parameter. - * - * @param group the multicast group to join - * @returns true on success - */ - virtual bool joinGroup(const KSocketAddress& group); - - /** - * @overload - * Joins a multicast group. This function also specifies the network interface - * to be used. - */ - virtual bool joinGroup(const KSocketAddress& group, - const KNetworkInterface& iface); - - /** - * Leaves a multicast group. The group being left is given by its address in the - * @p group parameter. - * - * @param group the group to leave - * @returns true on successful leaving the group - */ - virtual bool leaveGroup(const KSocketAddress& group); - - /** - * @overload - * Leaves a multicast group. - */ - virtual bool leaveGroup(const KSocketAddress& group, - const KNetworkInterface& iface); -private: - KMulticastSocketImplPrivate *d; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/knetworkinterface.h b/kdecore/network/knetworkinterface.h deleted file mode 100644 index 74fd52d55..000000000 --- a/kdecore/network/knetworkinterface.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef KNETWORKINTERFACE_H -#define KNETWORKINTERFACE_H - -#include <kdelibs_export.h> - -namespace KNetwork { - -/** - * A place-holder class for a future network interface class. - * This class is to be replaced with a more powerful version, inspired - * by: - * - KInetInterface (kdenetwork/krfb/srvloc) - * - NWInterface (kdenonbeta/knot/lib) - * - java.net.NetworkInterface - */ -class KNetworkInterface -{ -}; - -} // namespace KNetwork - -#endif - diff --git a/kdecore/network/kresolver.cpp b/kdecore/network/kresolver.cpp deleted file mode 100644 index 93c029b8e..000000000 --- a/kdecore/network/kresolver.cpp +++ /dev/null @@ -1,1164 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -// System includes -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/param.h> -#include <errno.h> -#include <netdb.h> -#include <time.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <stdlib.h> -#include <unistd.h> - -// Qt includes -#include <tqapplication.h> -#include <tqstring.h> -#include <tqcstring.h> -#include <tqstrlist.h> -#include <tqstringlist.h> -#include <tqshared.h> -#include <tqdatetime.h> -#include <tqtimer.h> -#include <tqmutex.h> -#include <tqguardedptr.h> - -// IDN -#ifdef HAVE_IDNA_H -# include <idna.h> -#endif - -// KDE -#include <klocale.h> - -// Us -#include "kresolver.h" -#include "kresolver_p.h" -#include "ksocketaddress.h" - -#ifdef NEED_MUTEX -#warning "mutex" -TQMutex getXXbyYYmutex; -#endif - -using namespace KNetwork; -using namespace KNetwork::Internal; - -///////////////////////////////////////////// -// class KResolverEntry - -class KNetwork::KResolverEntryPrivate: public TQShared -{ -public: - KSocketAddress addr; - int socktype; - int protocol; - TQString canonName; - TQCString encodedName; - - inline KResolverEntryPrivate() : - socktype(0), protocol(0) - { } -}; - -// default constructor -KResolverEntry::KResolverEntry() : - d(0L) -{ -} - -// constructor with stuff -KResolverEntry::KResolverEntry(const KSocketAddress& addr, int socktype, int protocol, - const TQString& canonName, const TQCString& encodedName) : - d(new KResolverEntryPrivate) -{ - d->addr = addr; - d->socktype = socktype; - d->protocol = protocol; - d->canonName = canonName; - d->encodedName = encodedName; -} - -// constructor with even more stuff -KResolverEntry::KResolverEntry(const struct sockaddr* sa, TQ_UINT16 salen, int socktype, - int protocol, const TQString& canonName, - const TQCString& encodedName) : - d(new KResolverEntryPrivate) -{ - d->addr = KSocketAddress(sa, salen); - d->socktype = socktype; - d->protocol = protocol; - d->canonName = canonName; - d->encodedName = encodedName; -} - -// copy constructor -KResolverEntry::KResolverEntry(const KResolverEntry& that) : - d(0L) -{ - *this = that; -} - -// destructor -KResolverEntry::~KResolverEntry() -{ - if (d == 0L) - return; - - if (d->deref()) - delete d; -} - -// returns the socket address -KSocketAddress KResolverEntry::address() const -{ - return d ? d->addr : KSocketAddress(); -} - -// returns the length -TQ_UINT16 KResolverEntry::length() const -{ - return d ? d->addr.length() : 0; -} - -// returns the family -int KResolverEntry::family() const -{ - return d ? d->addr.family() : AF_UNSPEC; -} - -// returns the canonical name -TQString KResolverEntry::canonicalName() const -{ - return d ? d->canonName : TQString::null; -} - -// returns the encoded name -TQCString KResolverEntry::encodedName() const -{ - return d ? d->encodedName : TQCString(); -} - -// returns the socket type -int KResolverEntry::socketType() const -{ - return d ? d->socktype : 0; -} - -// returns the protocol -int KResolverEntry::protocol() const -{ - return d ? d->protocol : 0; -} - -// assignment operator -KResolverEntry& KResolverEntry::operator= (const KResolverEntry& that) -{ - // copy the data - if (that.d) - that.d->ref(); - - if (d && d->deref()) - delete d; - - d = that.d; - return *this; -} - -///////////////////////////////////////////// -// class KResolverResults - -class KNetwork::KResolverResultsPrivate -{ -public: - TQString node, service; - int errorcode, syserror; - - KResolverResultsPrivate() : - errorcode(0), syserror(0) - { } -}; - -// default constructor -KResolverResults::KResolverResults() - : d(new KResolverResultsPrivate) -{ -} - -// copy constructor -KResolverResults::KResolverResults(const KResolverResults& other) - : TQValueList<KResolverEntry>(other), d(new KResolverResultsPrivate) -{ - *d = *other.d; -} - -// destructor -KResolverResults::~KResolverResults() -{ - delete d; -} - -// assignment operator -KResolverResults& -KResolverResults::operator= (const KResolverResults& other) -{ - if (this == &other) - return *this; - - // copy over the other data - *d = *other.d; - - // now let TQValueList do the rest of the work - TQValueList<KResolverEntry>::operator =(other); - - return *this; -} - -// gets the error code -int KResolverResults::error() const -{ - return d->errorcode; -} - -// gets the system errno -int KResolverResults::systemError() const -{ - return d->syserror; -} - -// sets the error codes -void KResolverResults::setError(int errorcode, int systemerror) -{ - d->errorcode = errorcode; - d->syserror = systemerror; -} - -// gets the hostname -TQString KResolverResults::nodeName() const -{ - return d->node; -} - -// gets the service name -TQString KResolverResults::serviceName() const -{ - return d->service; -} - -// sets the address -void KResolverResults::setAddress(const TQString& node, - const TQString& service) -{ - d->node = node; - d->service = service; -} - -void KResolverResults::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - - -/////////////////////// -// class KResolver - -TQStringList *KResolver::idnDomains = 0; - - -// default constructor -KResolver::KResolver(TQObject *parent, const char *name) - : TQObject(parent, name), d(new KResolverPrivate(this)) -{ -} - -// constructor with host and service -KResolver::KResolver(const TQString& nodename, const TQString& servicename, - TQObject *parent, const char *name) - : TQObject(parent, name), d(new KResolverPrivate(this, nodename, servicename)) -{ -} - -// destructor -KResolver::~KResolver() -{ - cancel(false); - delete d; -} - -// get the status -int KResolver::status() const -{ - return d->status; -} - -// get the error code -int KResolver::error() const -{ - return d->errorcode; -} - -// get the errno -int KResolver::systemError() const -{ - return d->syserror; -} - -// are we running? -bool KResolver::isRunning() const -{ - return d->status > 0 && d->status < Success; -} - -// get the hostname -TQString KResolver::nodeName() const -{ - return d->input.node; -} - -// get the service -TQString KResolver::serviceName() const -{ - return d->input.service; -} - -// sets the hostname -void KResolver::setNodeName(const TQString& nodename) -{ - // don't touch those values if we're working! - if (!isRunning()) - { - d->input.node = nodename; - d->status = Idle; - d->results.setAddress(nodename, d->input.service); - } -} - -// sets the service -void KResolver::setServiceName(const TQString& service) -{ - // don't change if running - if (!isRunning()) - { - d->input.service = service; - d->status = Idle; - d->results.setAddress(d->input.node, service); - } -} - -// sets the address -void KResolver::setAddress(const TQString& nodename, const TQString& service) -{ - setNodeName(nodename); - setServiceName(service); -} - -// get the flags -int KResolver::flags() const -{ - return d->input.flags; -} - -// sets the flags -int KResolver::setFlags(int flags) -{ - int oldflags = d->input.flags; - if (!isRunning()) - { - d->input.flags = flags; - d->status = Idle; - } - return oldflags; -} - -// sets the family mask -void KResolver::setFamily(int families) -{ - if (!isRunning()) - { - d->input.familyMask = families; - d->status = Idle; - } -} - -// sets the socket type -void KResolver::setSocketType(int type) -{ - if (!isRunning()) - { - d->input.socktype = type; - d->status = Idle; - } -} - -// sets the protocol -void KResolver::setProtocol(int protonum, const char *name) -{ - if (isRunning()) - return; // can't change now - - // we copy the given protocol name. If it isn't an empty string - // and the protocol number was 0, we will look it up in /etc/protocols - // we also leave the error reporting to the actual lookup routines, in - // case the given protocol name doesn't exist - - d->input.protocolName = name; - if (protonum == 0 && name != 0L && *name != '\0') - { - // must look up the protocol number - d->input.protocol = KResolver::protocolNumber(name); - } - else - d->input.protocol = protonum; - d->status = Idle; -} - -bool KResolver::start() -{ - if (!isRunning()) - { - d->results.empty(); - - // is there anything to be queued? - if (d->input.node.isEmpty() && d->input.service.isEmpty()) - { - d->status = KResolver::Success; - emitFinished(); - } - else - KResolverManager::manager()->enqueue(this, 0L); - } - - return true; -} - -bool KResolver::wait(int msec) -{ - if (!isRunning()) - { - emitFinished(); - return true; - } - - TQMutexLocker locker(&d->mutex); - - if (!isRunning()) - { - // it was running and no longer is? - // That means the manager has finished its processing and has posted - // an event for the signal to be emitted already. This means the signal - // will be emitted twice! - - emitFinished(); - return true; - } - else - { - TQTime t; - t.start(); - - while (!msec || t.elapsed() < msec) - { - // wait on the manager to broadcast completion - d->waiting = true; - if (msec) - KResolverManager::manager()->notifyWaiters.wait(&d->mutex, msec - t.elapsed()); - else - KResolverManager::manager()->notifyWaiters.wait(&d->mutex); - - // the manager has processed - // see if this object is done - if (!isRunning()) - { - // it's done - d->waiting = false; - emitFinished(); - return true; - } - } - - // if we've got here, we've timed out - d->waiting = false; - return false; - } -} - -void KResolver::cancel(bool emitSignal) -{ - KResolverManager::manager()->dequeue(this); - if (emitSignal) - emitFinished(); -} - -KResolverResults -KResolver::results() const -{ - if (!isRunning()) - return d->results; - - // return a dummy, empty result - KResolverResults r; - r.setAddress(d->input.node, d->input.service); - r.setError(d->errorcode, d->syserror); - return r; -} - -bool KResolver::event(TQEvent* e) -{ - if (static_cast<int>(e->type()) == KResolverManager::ResolutionCompleted) - { - emitFinished(); - return true; - } - - return false; -} - -void KResolver::emitFinished() -{ - if (isRunning()) - d->status = KResolver::Success; - - TQGuardedPtr<TQObject> p = this; // guard against deletion - - emit finished(d->results); - - if (p && d->deleteWhenDone) - deleteLater(); // in QObject -} - -TQString KResolver::errorString(int errorcode, int syserror) -{ - // no i18n now... - static const char * const messages[] = - { - I18N_NOOP("no error"), // NoError - I18N_NOOP("requested family not supported for this host name"), // AddrFamily - I18N_NOOP("temporary failure in name resolution"), // TryAgain - I18N_NOOP("non-recoverable failure in name resolution"), // NonRecoverable - I18N_NOOP("invalid flags"), // BadFlags - I18N_NOOP("memory allocation failure"), // Memory - I18N_NOOP("name or service not known"), // NoName - I18N_NOOP("requested family not supported"), // UnsupportedFamily - I18N_NOOP("requested service not supported for this socket type"), // UnsupportedService - I18N_NOOP("requested socket type not supported"), // UnsupportedSocketType - I18N_NOOP("unknown error"), // UnknownError - I18N_NOOP2("1: the i18n'ed system error code, from errno", - "system error: %1") // SystemError - }; - - // handle the special value - if (errorcode == Canceled) - return i18n("request was canceled"); - - if (errorcode > 0 || errorcode < SystemError) - return TQString::null; - - TQString msg = i18n(messages[-errorcode]); - if (errorcode == SystemError) - msg.arg(TQString::fromLocal8Bit(strerror(syserror))); - - return msg; -} - -KResolverResults -KResolver::resolve(const TQString& host, const TQString& service, int flags, - int families) -{ - KResolver qres(host, service, TQT_TQOBJECT(tqApp), "synchronous KResolver"); - qres.setFlags(flags); - qres.setFamily(families); - qres.start(); - qres.wait(); - return qres.results(); -} - -bool KResolver::resolveAsync(TQObject* userObj, const char *userSlot, - const TQString& host, const TQString& service, - int flags, int families) -{ - KResolver* qres = new KResolver(host, service, TQT_TQOBJECT(tqApp), "asynchronous KResolver"); - TQObject::connect(qres, TQT_SIGNAL(finished(KResolverResults)), userObj, userSlot); - qres->setFlags(flags); - qres->setFamily(families); - qres->d->deleteWhenDone = true; // this is the only difference from the example code - return qres->start(); -} - -TQStrList KResolver::protocolName(int protonum) -{ - struct protoent *pe = 0L; -#ifndef HAVE_GETPROTOBYNAME_R - TQMutexLocker locker(&getXXbyYYmutex); - - pe = getprotobynumber(protonum); - -#else - size_t buflen = 1024; - struct protoent protobuf; - char *buf; - do - { - buf = new char[buflen]; -# ifdef USE_SOLARIS // Solaris uses a 4 argument getprotobynumber_r which returns struct *protoent or NULL - if ((pe = getprotobynumber_r(protonum, &protobuf, buf, buflen)) && (errno == ERANGE)) -# else - if (getprotobynumber_r(protonum, &protobuf, buf, buflen, &pe) == ERANGE) -# endif - { - pe = 0L; - buflen += 1024; - delete [] buf; - } - else - break; - } - while (pe == 0L); -#endif - - // Do common processing - TQStrList lst(true); // use deep copies - if (pe != NULL) - { - lst.append(pe->p_name); - for (char **p = pe->p_aliases; *p; p++) - lst.append(*p); - } - -#ifdef HAVE_GETPROTOBYNAME_R - delete [] buf; -#endif - - return lst; -} - -TQStrList KResolver::protocolName(const char *protoname) -{ - struct protoent *pe = 0L; -#ifndef HAVE_GETPROTOBYNAME_R - TQMutexLocker locker(&getXXbyYYmutex); - - pe = getprotobyname(protoname); - -#else - size_t buflen = 1024; - struct protoent protobuf; - char *buf; - do - { - buf = new char[buflen]; -# ifdef USE_SOLARIS // Solaris uses a 4 argument getprotobyname_r which returns struct *protoent or NULL - if ((pe = getprotobyname_r(protoname, &protobuf, buf, buflen)) && (errno == ERANGE)) -# else - if (getprotobyname_r(protoname, &protobuf, buf, buflen, &pe) == ERANGE) -# endif - { - pe = 0L; - buflen += 1024; - delete [] buf; - } - else - break; - } - while (pe == 0L); -#endif - - // Do common processing - TQStrList lst(true); // use deep copies - if (pe != NULL) - { - lst.append(pe->p_name); - for (char **p = pe->p_aliases; *p; p++) - lst.append(*p); - } - -#ifdef HAVE_GETPROTOBYNAME_R - delete [] buf; -#endif - - return lst; -} - -int KResolver::protocolNumber(const char *protoname) -{ - struct protoent *pe = 0L; -#ifndef HAVE_GETPROTOBYNAME_R - TQMutexLocker locker(&getXXbyYYmutex); - - pe = getprotobyname(protoname); - -#else - size_t buflen = 1024; - struct protoent protobuf; - char *buf; - do - { - buf = new char[buflen]; -# ifdef USE_SOLARIS // Solaris uses a 4 argument getprotobyname_r which returns struct *protoent or NULL - if ((pe = getprotobyname_r(protoname, &protobuf, buf, buflen)) && (errno == ERANGE)) -# else - if (getprotobyname_r(protoname, &protobuf, buf, buflen, &pe) == ERANGE) -# endif - { - pe = 0L; - buflen += 1024; - delete [] buf; - } - else - break; - } - while (pe == 0L); -#endif - - // Do common processing - int protonum = -1; - if (pe != NULL) - protonum = pe->p_proto; - -#ifdef HAVE_GETPROTOBYNAME_R - delete [] buf; -#endif - - return protonum; -} - -int KResolver::servicePort(const char *servname, const char *protoname) -{ - struct servent *se = 0L; -#ifndef HAVE_GETSERVBYNAME_R - TQMutexLocker locker(&getXXbyYYmutex); - - se = getservbyname(servname, protoname); - -#else - size_t buflen = 1024; - struct servent servbuf; - char *buf; - do - { - buf = new char[buflen]; -# ifdef USE_SOLARIS // Solaris uses a 5 argument getservbyname_r which returns struct *servent or NULL - if ((se = getservbyname_r(servname, protoname, &servbuf, buf, buflen)) && (errno == ERANGE)) -# else - if (getservbyname_r(servname, protoname, &servbuf, buf, buflen, &se) == ERANGE) -# endif - { - se = 0L; - buflen += 1024; - delete [] buf; - } - else - break; - } - while (se == 0L); -#endif - - // Do common processing - int servport = -1; - if (se != NULL) - servport = ntohs(se->s_port); - -#ifdef HAVE_GETSERVBYNAME_R - delete [] buf; -#endif - - return servport; -} - -TQStrList KResolver::serviceName(const char* servname, const char *protoname) -{ - struct servent *se = 0L; -#ifndef HAVE_GETSERVBYNAME_R - TQMutexLocker locker(&getXXbyYYmutex); - - se = getservbyname(servname, protoname); - -#else - size_t buflen = 1024; - struct servent servbuf; - char *buf; - do - { - buf = new char[buflen]; -# ifdef USE_SOLARIS // Solaris uses a 5 argument getservbyname_r which returns struct *servent or NULL - if ((se = getservbyname_r(servname, protoname, &servbuf, buf, buflen)) && (errno == ERANGE)) -# else - if (getservbyname_r(servname, protoname, &servbuf, buf, buflen, &se) == ERANGE) -# endif - { - se = 0L; - buflen += 1024; - delete [] buf; - } - else - break; - } - while (se == 0L); -#endif - - // Do common processing - TQStrList lst(true); // use deep copies - if (se != NULL) - { - lst.append(se->s_name); - for (char **p = se->s_aliases; *p; p++) - lst.append(*p); - } - -#ifdef HAVE_GETSERVBYNAME_R - delete [] buf; -#endif - - return lst; -} - -TQStrList KResolver::serviceName(int port, const char *protoname) -{ - struct servent *se = 0L; -#ifndef HAVE_GETSERVBYPORT_R - TQMutexLocker locker(&getXXbyYYmutex); - - se = getservbyport(port, protoname); - -#else - size_t buflen = 1024; - struct servent servbuf; - char *buf; - do - { - buf = new char[buflen]; -# ifdef USE_SOLARIS // Solaris uses a 5 argument getservbyport_r which returns struct *servent or NULL - if ((se = getservbyport_r(port, protoname, &servbuf, buf, buflen)) && (errno == ERANGE)) -# else - if (getservbyport_r(port, protoname, &servbuf, buf, buflen, &se) == ERANGE) -# endif - { - se = 0L; - buflen += 1024; - delete [] buf; - } - else - break; - } - while (se == 0L); -#endif - - // Do common processing - TQStrList lst(true); // use deep copies - if (se != NULL) - { - lst.append(se->s_name); - for (char **p = se->s_aliases; *p; p++) - lst.append(*p); - } - -#ifdef HAVE_GETSERVBYPORT_R - delete [] buf; -#endif - - return lst; -} - -TQString KResolver::localHostName() -{ - TQCString name; - int len; - -#ifdef MAXHOSTNAMELEN - len = MAXHOSTNAMELEN; -#else - len = 256; -#endif - - while (true) - { - name.resize(len); - - if (gethostname(name.data(), len - 1) == 0) - { - // Call succeeded, but it's not guaranteed to be NUL-terminated - // Note that some systems return success even if they did truncation - name[len - 1] = '\0'; - break; - } - - // Call failed - if (errno == ENAMETOOLONG || errno == EINVAL) - len += 256; - else - { - // Oops! Unknown error! - name = TQCString(); - } - } - - if (name.isEmpty()) - return TQString::tqfromLatin1("localhost"); - - if (name.find('.') == -1) - { - // not fully qualified - // must resolve - KResolverResults results = resolve(name, "0", CanonName); - if (results.isEmpty()) - // cannot find a valid hostname! - return TQString::tqfromLatin1("localhost"); - else - return results.first().canonicalName(); - } - - return domainToUnicode(name); -} - - -// forward declaration -static TQStringList splitLabels(const TQString& tqunicodeDomain); -static TQCString ToASCII(const TQString& label); -static TQString ToUnicode(const TQString& label); - -static TQStringList *KResolver_initIdnDomains() -{ - const char *kde_use_idn = getenv("KDE_USE_IDN"); - if (!kde_use_idn) - kde_use_idn = "ac:at:br:cat:ch:cl:cn:de:dk:fi:gr:hu:info:io:is:jp:kr:li:lt:museum:org:no:se:sh:th:tm:tw:vn"; - return new TQStringList(TQStringList::split(':', TQString::tqfromLatin1(kde_use_idn).lower())); -} - -// implement the ToAscii function, as described by IDN documents -TQCString KResolver::domainToAscii(const TQString& tqunicodeDomain) -{ - if (!idnDomains) - idnDomains = KResolver_initIdnDomains(); - - TQCString retval; - // RFC 3490, section 4 describes the operation: - // 1) this is a query, so don't allow unassigned - - // 2) split the domain into individual labels, without - // separators. - TQStringList input = splitLabels(tqunicodeDomain); - - // Do we allow IDN names for this TLD? - if (input.count() && !idnDomains->contains(input[input.count()-1].lower())) - return input.join(".").lower().latin1(); // No IDN allowed for this TLD - - // 3) decide whether to enforce the STD3 rules for chars < 0x7F - // we don't enforce - - // 4) for each label, apply ToASCII - TQStringList::Iterator it = input.begin(); - const TQStringList::Iterator end = input.end(); - for ( ; it != end; ++it) - { - TQCString cs = ToASCII(*it); - if (cs.isNull()) - return TQCString(); // error! - - // no, all is Ok. - if (!retval.isEmpty()) - retval += '.'; - retval += cs; - } - - return retval; -} - -TQString KResolver::domainToUnicode(const TQCString& asciiDomain) -{ - return domainToUnicode(TQString::tqfromLatin1(asciiDomain)); -} - -// implement the ToUnicode function, as described by IDN documents -TQString KResolver::domainToUnicode(const TQString& asciiDomain) -{ - if (asciiDomain.isEmpty()) - return asciiDomain; - if (!idnDomains) - idnDomains = KResolver_initIdnDomains(); - - TQString retval; - - // draft-idn-idna-14.txt, section 4 describes the operation: - // 1) this is a query, so don't allow unassigned - // besides, input is ASCII - - // 2) split the domain into individual labels, without - // separators. - TQStringList input = splitLabels(asciiDomain); - - // Do we allow IDN names for this TLD? - if (input.count() && !idnDomains->contains(input[input.count()-1].lower())) - return asciiDomain.lower(); // No TLDs allowed - - // 3) decide whether to enforce the STD3 rules for chars < 0x7F - // we don't enforce - - // 4) for each label, apply ToUnicode - TQStringList::Iterator it; - const TQStringList::Iterator end = input.end(); - for (it = input.begin(); it != end; ++it) - { - TQString label = ToUnicode(*it).lower(); - - // ToUnicode can't fail - if (!retval.isEmpty()) - retval += '.'; - retval += label; - } - - return retval; -} - -TQString KResolver::normalizeDomain(const TQString& domain) -{ - return domainToUnicode(domainToAscii(domain)); -} - -void KResolver::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -// here follows IDN functions -// all IDN functions conform to the following documents: -// RFC 3454 - Preparation of Internationalized Strings -// RFC 3490 - Internationalizing Domain Names in Applications (IDNA) -// RFC 3491 - Nameprep: A Stringprep Profile for -// Internationalized Domain Names (IDN -// RFC 3492 - Punycode: A Bootstring encoding of Unicode -// for Internationalized Domain Names in Applications (IDNA) - -static TQStringList splitLabels(const TQString& tqunicodeDomain) -{ - // From RFC 3490 section 3.1: - // "Whenever dots are used as label separators, the following characters - // MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full - // stop), U+FF0E (fullwidth full stop), U+FF61 (halfwidth ideographic full - // stop)." - static const unsigned int separators[] = { 0x002E, 0x3002, 0xFF0E, 0xFF61 }; - - TQStringList lst; - int start = 0; - uint i; - for (i = 0; i < tqunicodeDomain.length(); i++) - { - unsigned int c = tqunicodeDomain[i].tqunicode(); - - if (c == separators[0] || - c == separators[1] || - c == separators[2] || - c == separators[3]) - { - // found a separator! - lst << tqunicodeDomain.mid(start, i - start); - start = i + 1; - } - } - if ((long)i >= start) - // there is still one left - lst << tqunicodeDomain.mid(start, i - start); - - return lst; -} - -static TQCString ToASCII(const TQString& label) -{ -#ifdef HAVE_IDNA_H - // We have idna.h, so we can use the idna_to_ascii - // function :) - - if (label.length() > 64) - return (char*)0L; // invalid label - - if (label.length() == 0) - // this is allowed - return TQCString(""); // empty, not null - - TQCString retval; - char buf[65]; - - TQ_UINT32* ucs4 = new TQ_UINT32[label.length() + 1]; - - uint i; - for (i = 0; i < label.length(); i++) - ucs4[i] = (unsigned long)label[i].tqunicode(); - ucs4[i] = 0; // terminate with NUL, just to be on the safe side - - if (idna_to_ascii_4i(ucs4, label.length(), buf, 0) == IDNA_SUCCESS) - // success! - retval = buf; - - delete [] ucs4; - return retval; -#else - return label.latin1(); -#endif -} - -static TQString ToUnicode(const TQString& label) -{ -#ifdef HAVE_IDNA_H - // We have idna.h, so we can use the idna_to_tqunicode - // function :) - - TQ_UINT32 *ucs4_input, *ucs4_output; - size_t outlen; - - ucs4_input = new TQ_UINT32[label.length() + 1]; - for (uint i = 0; i < label.length(); i++) - ucs4_input[i] = (unsigned long)label[i].tqunicode(); - - // try the same length for output - ucs4_output = new TQ_UINT32[outlen = label.length()]; - - idna_to_unicode_44i(ucs4_input, label.length(), - ucs4_output, &outlen, - 0); - - if (outlen > label.length()) - { - // it must have failed - delete [] ucs4_output; - ucs4_output = new TQ_UINT32[outlen]; - - idna_to_unicode_44i(ucs4_input, label.length(), - ucs4_output, &outlen, - 0); - } - - // now set the answer - TQString result; - result.setLength(outlen); - for (uint i = 0; i < outlen; i++) - result[i] = (unsigned int)ucs4_output[i]; - - delete [] ucs4_input; - delete [] ucs4_output; - - return result; -#else - return label; -#endif -} - -#include "kresolver.moc" diff --git a/kdecore/network/kresolver.h b/kdecore/network/kresolver.h deleted file mode 100644 index 069428904..000000000 --- a/kdecore/network/kresolver.h +++ /dev/null @@ -1,946 +0,0 @@ -/* -*- mode: C++; coding: utf-8; -*- - * Copyright (C) 2003,2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KRESOLVER_H -#define KRESOLVER_H - -////////////////// -// Needed includes -#include <tqvaluelist.h> -#include <tqobject.h> -#include "ksocketaddress.h" - - -//////////////////////// -// Forward declarations -struct sockaddr; -class TQString; -class TQCString; -class TQStrList; - -////////////////// -// Our definitions - -namespace KNetwork { - - namespace Internal { class KResolverManager; } - -class KResolverEntryPrivate; -/** @class KResolverEntry kresolver.h kresolver.h - * @brief One resolution entry. - * - * This class is one element in the resolution results list. - * It contains the socket address for connecting, as well as - * a bit more of information: the socket type, address family - * and protocol numbers. - * - * This class contains all the information required for creating, - * binding and connecting a socket. - * - * KResolverEntry objects implicitly share data, so copying them - * is quite efficient. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KResolverEntry -{ -public: - /** - * Default constructor - * - */ - KResolverEntry(); - - /** - * Constructs a new KResolverEntry from a KSocketAddress - * and other data. - * - * The KSocketAddress @p addr parameter will be deep-copied. - * - * @param addr the address that was resolved - * @param socktype the socket type of the resolved address - * @param protocol the protocol of the resolved address - * @param canonName the canonical name of the resolved hostname - * @param encodedName the ASCII-compatible encoding of the hostname - */ - KResolverEntry(const KSocketAddress& addr, int socktype, int protocol, - const TQString& canonName = TQString::null, - const TQCString& encodedName = TQCString()); - - /** - * Constructs a new KResolverEntry from raw forms of - * socket addresses and other data. - * - * This constructor instead creates an internal KSocketAddress object. - * - * @param sa the sockaddr structure containing the raw address - * @param salen the length of the sockaddr structure - * @param socktype the socket type of the resolved address - * @param protocol the protocol of the resolved address - * @param canonName the canonical name of the resolved hostname - * @param encodedName the ASCII-compatible encoding of the hostname - */ - KResolverEntry(const struct sockaddr *sa, TQ_UINT16 salen, int socktype, - int protocol, const TQString& canonName = TQString::null, - const TQCString& encodedName = TQCString()); - - /** - * Copy constructor. - * - * This constructor performs a shallow-copy of the other object. - */ - KResolverEntry(const KResolverEntry &other); - - /** - * Destructor. - * - * The destructor frees associated resources with this object. It does - * not destroy shared data. - */ - ~KResolverEntry(); - - /** - * Retrieves the socket address associated with this entry. - */ - KSocketAddress address() const; - - /** - * Retrieves the length of the socket address structure. - */ - TQ_UINT16 length() const; - - /** - * Retrieves the family associated with this socket address. - */ - int family() const; - - /** - * Retrieves the canonical name associated with this entry, if there is any. - * If the canonical name was not found, this function returns TQString::null. - */ - TQString canonicalName() const; - - /** - * Retrieves the encoded domain name associated with this entry, if there is - * any. If this domain has been resolved through DNS, this will be the - * the ACE-encoded hostname. - * - * Returns a null TQCString if such information is not available. - * - * Please note that this information is NOT to be presented to the user, - * unless requested. - */ - TQCString encodedName() const; - - /** - * Retrieves the socket type associated with this entry. - */ - int socketType() const; - - /** - * Retrieves the protocol associated with this entry. - */ - int protocol() const; - - /** - * Assignment operator - * - * This function copies the contents of the other object into this one. - * Data will be shared between the two of them. - */ - KResolverEntry& operator=(const KResolverEntry& other); - -private: - KResolverEntryPrivate* d; -}; - -class KResolverResultsPrivate; -/** - * @class KResolverResults kresolver.h kresolver.h - * @brief Name and service resolution results. - * - * This object contains the results of a name and service resolution, as - * those performed by @ref KResolver. It is also a descendant of TQValueList, so - * you may use all its member functions here to access the elements. - * - * A KResolverResults object is associated with a resolution, so, in addition - * to the resolved elements, you can also retrieve information about the - * resolution process itself, like the nodename that was resolved or an error - * code. - * - * Note Resolver also uses KResolverResults objects to indicate failure, so - * you should test for failure. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KResolverResults: public TQValueList<KResolverEntry> -{ -public: - /** - * Default constructor. - * - * Constructs an empty list. - */ - KResolverResults(); - - /** - * Copy constructor - * - * Creates a new object with the contents of the other one. Data will be - * shared by the two objects, like QValueList - */ - KResolverResults(const KResolverResults& other); - - /** - * Destructor - * - * Destroys the object and frees associated resources. - */ - virtual ~KResolverResults(); - - /** - * Assignment operator - * - * Copies the contents of the other container into this one, discarding - * our current values. - */ - KResolverResults& operator=(const KResolverResults& other); - - /** - * Retrieves the error code associated with this resolution. The values - * here are the same as in @ref KResolver::ErrorCodes. - */ - int error() const; - - /** - * Retrieves the system error code, if any. - * @see KResolver::systemError for more information - */ - int systemError() const; - - /** - * Sets the error codes - * - * @param errorcode the error code in @ref KResolver::ErrorCodes - * @param systemerror the system error code associated, if any - */ - void setError(int errorcode, int systemerror = 0); - - /** - * The nodename to which the resolution was performed. - */ - TQString nodeName() const; - - /** - * The service name to which the resolution was performed. - */ - TQString serviceName() const; - - /** - * Sets the new nodename and service name - */ - void setAddress(const TQString& host, const TQString& service); - -protected: - virtual void virtual_hook( int id, void* data ); -private: - KResolverResultsPrivate* d; -}; - -class KResolverPrivate; -/** - * @class KResolver kresolver.h kresolver.h - * @brief Name and service resolution class. - * - * This class provides support for doing name-to-binary resolution - * for nodenames and service ports. You should use this class if you - * need specific resolution techniques when creating a socket or if you - * want to inspect the results before calling the socket functions. - * - * You can either create an object and set the options you want in it - * or you can simply call the static member functions, which will create - * standard Resolver objects and dispatch the resolution for you. Normally, - * the static functions will be used, except in cases where specific options - * must be set. - * - * A Resolver object defaults to the following: - * @li address family: any address family - * @li socket type: streaming socket - * @li protocol: implementation-defined. Generally, TCP - * @li host and service: unset - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KResolver: public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - - /** - * Address family selection types - * - * These values can be OR-ed together to form a composite family selection. - * - * @li UnknownFamily: a family that is unknown to the current implementation - * @li KnownFamily: a family that is known to the implementation (the exact - * opposite of UnknownFamily) - * @li AnyFamilies: any address family is acceptable - * @li InternetFamily: an address for connecting to the Internet - * @li InetFamily: alias for InternetFamily - * @li IPv6Family: an IPv6 address only - * @li IPv4Family: an IPv4 address only - * @li UnixFamily: an address for the local Unix namespace (i.e., Unix sockets) - * @li LocalFamily: alias for UnixFamily - */ - enum SocketFamilies - { - UnknownFamily = 0x0001, - - UnixFamily = 0x0002, - LocalFamily = UnixFamily, - - IPv4Family = 0x0004, - IPv6Family = 0x0008, - InternetFamily = IPv4Family | IPv6Family, - InetFamily = InternetFamily, - - KnownFamily = ~UnknownFamily, - AnyFamily = KnownFamily | UnknownFamily - }; - - /** - * Flags for the resolution. - * - * These flags are used for setting the resolution behaviour for this - * object: - * @li Passive: resolve to a passive socket (i.e., one that can be used for - * binding to a local interface) - * @li CanonName: request that the canonical name for the given nodename - * be found and recorded - * @li NoResolve: request that no external resolution be performed. The given - * nodename and servicename will be resolved locally only. - * @li NoSrv: don't try to use SRV-based name-resolution. (deprecated) - * @li UseSrv: use SRV-based name resolution. - * @li Multiport: the port/service argument is a list of port numbers and - * ranges. (future extension) - * - * @note SRV-based lookup and Multiport are not implemented yet. - */ - enum Flags - { - Passive = 0x01, - CanonName = 0x02, - NoResolve = 0x04, - NoSrv = 0x08, - Multiport = 0x10, - UseSrv = 0x20 - }; - - /** - * Error codes - * - * These are the possible error values that objects of this class - * may return. See \ref errorString() for getting a string representation - * for these errors. - * - * @li AddrFamily: Address family for the given nodename is not supported. - * @li TryAgain: Temporary failure in name resolution. You should try again. - * @li NonRecoverable: Non-recoverable failure in name resolution. - * @li BadFlags: Invalid flags were given. - * @li Memory: Memory allocation failure. - * @li NoName: The specified name or service doesn't exist. - * @li UnsupportedFamily: The requested socket family is not supported. - * @li UnsupportedService: The requested service is not supported for this - * socket type (i.e., a datagram service in a streaming socket). - * @li UnsupportedSocketType: The requested socket type is not supported. - * @li UnknownError: An unknown, unexpected error occurred. - * @li SystemError: A system error occurred. See @ref systemError. - * @li Canceled: This request was cancelled by the user. - */ - enum ErrorCodes - { - // note: if you change this enum, take a look at KResolver::errorString - NoError = 0, - AddrFamily = -1, - TryAgain = -2, - NonRecoverable = -3, - BadFlags = -4, - Memory = -5, - NoName = -6, - UnsupportedFamily = -7, - UnsupportedService = -8, - UnsupportedSocketType = -9, - UnknownError = -10, - SystemError = -11, - Canceled = -100 - }; - - /** - * Status codes. - * - * These are the possible status for a Resolver object. A value - * greater than zero indicates normal behaviour, while negative - * values either indicate failure or error. - * - * @li Idle: resolution has not yet been started. - * @li Queued: resolution is queued but not yet in progress. - * @li InProgress: resolution is in progress. - * @li PostProcessing: resolution is in progress. - * @li Success: resolution is done; you can retrieve the results. - * @li Canceled: request cancelled by the user. - * @li Failed: resolution is done, but failed. - * - * Note: the status Canceled and the error code Canceled are the same. - * - * Note 2: the status Queued and InProgress might not be distinguishable. - * Some implementations might not differentiate one from the other. - */ - enum StatusCodes - { - Idle = 0, - Queued = 1, - InProgress = 5, - PostProcessing = 6, - Success = 10, - //Canceled = -100, // already defined above - Failed = -101 - }; - - /** - * Default constructor. - * - * Creates an empty Resolver object. You should set the wanted - * names and flags using the member functions before starting - * the name resolution. - */ - KResolver(TQObject * = 0L, const char * = 0L); - - /** - * Constructor with host and service names. - * - * Creates a Resolver object with the given host and - * service names. Flags are initialised to 0 and any address family - * will be accepted. - * - * @param nodename The host name we want resolved. - * @param servicename The service name associated, like "http". - */ - KResolver(const TQString& nodename, const TQString& servicename = TQString::null, - TQObject * = 0L, const char * = 0L); - - /** - * Destructor. - * - * When this object is deleted, it'll destroy all associated - * resources. If the resolution is still in progress, it will be - * cancelled and the signal will \b not be emitted. - */ - virtual ~KResolver(); - - /** - * Retrieve the current status of this object. - * - * @see StatusCodes for the possible status codes. - */ - int status() const; - - /** - * Retrieve the error code in this object. - * - * This function will return NoError if we are not in - * an error condition. See @ref status and @ref StatusCodes to - * find out what the current status is. - * - * @see errorString for getting a textual representation of - * this error - */ - int error() const; - - /** - * Retrieve the associated system error code in this object. - * - * Many resolution operations may generate an extra error code - * as given by the C errno variable. That value is stored in the - * object and can be retrieved by this function. - */ - int systemError() const; - - /** - * Returns the textual representation of the error in this object. - */ - inline TQString errorString() const - { return errorString(error(), systemError()); } - - /** - * Returns true if this object is currently running - */ - bool isRunning() const; - - /** - * The nodename to which the resolution was/is to be performed. - */ - TQString nodeName() const; - - /** - * The service name to which the resolution was/is to be performed. - */ - TQString serviceName() const; - - /** - * Sets the nodename for the resolution. - * - * Set the nodename to TQString::null to unset it. - * @param nodename The nodename to be resolved. - */ - void setNodeName(const TQString& nodename); - - /** - * Sets the service name to be resolved. - * - * Set it to TQString::null to unset it. - * @param service The service to be resolved. - */ - void setServiceName(const TQString& service); - - /** - * Sets both the host and the service names. - * - * Setting either value to TQString::null will unset them. - * @param node The nodename - * @param service The service name - */ - void setAddress(const TQString& node, const TQString& service); - - /** - * Retrieves the flags set for the resolution. - * - * @see Flags for an explanation on what flags are possible - */ - int flags() const; - - /** - * Sets the flags. - * - * @param flags the new flags - * @return the old flags - * @see Flags for an explanation on the flags - */ - int setFlags(int flags); - - /** - * Sets the allowed socket families. - * - * @param families the families that we want/accept - * @see SocketFamilies for possible values - */ - void setFamily(int families); - - /** - * Sets the socket type we want. - * - * The values for the @p type parameter are the SOCK_* - * constants, defined in <sys/socket.h>. The most common - * values are: - * @li SOCK_STREAM streaming socket (= reliable, sequenced, - * connection-based) - * @li SOCK_DGRAM datagram socket (= unreliable, connectionless) - * @li SOCK_RAW raw socket, with direct access to the - * container protocol (such as IP) - * - * These three are the only values to which it is guaranteed that - * resolution will work. Some systems may define other constants (such as - * SOCK_RDM for reliable datagrams), but support is implementation-defined. - * - * @param type the wanted socket type (SOCK_* constants). Set - * 0 to use the default. - */ - void setSocketType(int type); - - /** - * Sets the protocol we want. - * - * Protocols are dependant on the selected address family, so you should know - * what you are doing if you use this function. Besides, protocols generally - * are either stream-based or datagram-based, so the value of the socket - * type is also important. The resolution will fail if these values don't match. - * - * When using an Internet socket, the values for the protocol are the - * IPPROTO_* constants, defined in <netinet/in.h>. - * - * You may choose to set the protocol either by its number or by its name, or - * by both. If you set: - * @li the number and the name: both values will be stored internally; you - * may set the name to an empty value, if wanted - * @li the number only (name = NULL): the name will be searched in the - * protocols database - * @li the name only (number = 0): the number will be searched in the - * database - * @li neither name nor number: reset to default behaviour - * - * @param protonum the protocol number we want - * @param name the protocol name - */ - void setProtocol(int protonum, const char *name = 0L); - - /** - * Starts the name resolution asynchronously. - * - * This function will queue this object for resolution - * and will return immediately. The status upon exit will either be - * Queued or InProgress or Failed. - * - * This function does nothing if the object is already queued. But if - * it had already succeeded or failed, this function will re-start it. - * - * Note: if both the nodename and the servicename are unset, this function - * will not queue, but will set a success state and emit the signal. Also - * note that in this case and maybe others, the signal @ref finished might - * be emitted before this function returns. - * - * @return true if this request was successfully queued for asynchronous - * resolution - */ - bool start(); - - /** - * Waits for a request to finish resolving. - * - * This function will wait on a running request for its termination. The - * status upon exit will either be Success or Failed or Canceled. - * - * This function may be called from any thread, even one that is not the - * GUI thread or the one that started the resolution process. But note this - * function is not thread-safe nor reentrant: i.e., only one thread can be - * waiting on one given object. - * - * Also note that this function ensures that the @ref finished signal is - * emitted before it returns. That means that, as a side-effect, whenever - * wait() is called, the signal is emitted on the thread calling wait(). - * - * @param msec the time to wait, in milliseconds or 0 to - * wait forever - * @return true if the resolution has finished processing, even when it - * failed or was canceled. False means the wait timed out and - * the resolution is still running. - */ - bool wait(int msec = 0); - - /** - * Cancels a running request - * - * This function will cancel a running request. If the request is not - * currently running or queued, this function does nothing. - * - * Note: if you tell the signal to be emitted, be aware that it might - * or might not be emitted before this function returns. - * - * @param emitSignal whether to emit the @ref finished signal or not - */ - void cancel(bool emitSignal = true); - - /** - * Retrieves the results of this resolution - * - * Use this function to retrieve the results of the resolution. If no - * data was resolved (yet) or if we failed, this function will return - * an empty object. - * - * @return the resolved data - * @see status for information on finding out if the resolution was successful - */ - KResolverResults results() const; - - /** - * Handles events. Reimplemented from TQObject. - * - * This function handles the events generated by the manager indicating that - * this object has finished processing. - * - * Do not post events to this object. - */ - virtual bool event(TQEvent*); - -signals: - // signals - - /** - * This signal is emitted whenever the resolution is finished, one - * way or another (success or failure). The @p results parameter - * will contain the resolved data. - * - * Note: if you are doing multiple resolutions, you can use the - * TQObject::sender() function to distinguish one Resolver object from - * another. - * - * @param results the resolved data; might be empty if the resolution - * failed - * @see results for information on what the results are - * - * @note This signal is @b always delivered in the GUI event thread, even for - * resolutions that were started in secondary threads. - */ - void finished(KResolverResults results); - -private: - void emitFinished(); - -public: - // Static functions - - /** - * Returns the string representation of this error code. - * - * @param errorcode the error code. See @ref ErrorCodes. - * @param syserror the system error code associated. - * @return the string representation. This is already - * i18n'ed. - */ - static TQString errorString(int errorcode, int syserror = 0); - - /** - * Resolve the nodename and service name synchronously - * - * This static function is provided as convenience for simplifying - * name resolution. It resolves the given host and service names synchronously - * and returns the results it found. It is equivalent to the following code: - * - * \code - * KResolver qres(host, service); - * qres.setFlags(flags); - * qres.setFamily(families) - * qres.start(); - * qres.wait(); - * return qres.results(); - * \endcode - * - * @param host the nodename to resolve - * @param service the service to resolve - * @param flags flags to be used - * @param families the families to be searched - * @return a KResolverResults object containing the results - * @see KResolverResults for information on how to obtain the error code - */ - static KResolverResults resolve(const TQString& host, const TQString& service, - int flags = 0, int families = KResolver::InternetFamily); - - /** - * Start an asynchronous name resolution - * - * This function is provided as a convenience to simplify the resolution - * process. It creates an internal KResolver object, connects the - * @ref finished signal to the given slot and starts the resolution - * asynchronously. It is more or less equivalent to the following code: - * - * \b Note: this function may trigger the signal before it returns, so - * your code must be prepared for this situation. - * - * \code - * KResolver* qres = new KResolver(host, service); - * TQObject::connect(qres, TQT_SIGNAL(finished(KResolverResults)), - * userObj, userSlot); - * qres->setFlags(flags); - * qres->setFamily(families); - * return qres->start(); - * \endcode - * - * You should use it like this in your code: - * \code - * KResolver::resolveAsync(myObj, TQT_SLOT(mySlot(KResolverResults)), host, service); - * \endcode - * - * @param userObj the object whose slot @p userSlot we will connect - * @param userSlot the slot to which we'll connect - * @param host the nodename to resolve - * @param service the service to resolve - * @param flags flags to be used - * @param families families to be searcheed - * @return true if the queueing was successful, false if not - * @see KResolverResults for information on how to obtain the error code - */ - static bool resolveAsync(TQObject* userObj, const char *userSlot, - const TQString& host, const TQString& service, - int flags = 0, int families = KResolver::InternetFamily); - - /** - * Returns the domain name in an ASCII Compatible Encoding form, suitable - * for DNS lookups. This is the base for International Domain Name support - * over the Internet. - * - * Note this function may fail, in which case it'll return a null - * TQCString. Reasons for failure include use of unknown code - * points (Unicode characters). - * - * Note that the encoding is illegible and, thus, should not be presented - * to the user, except if requested. - * - * @param tqunicodeDomain the domain name to be encoded - * @return the ACE-encoded suitable for DNS queries if successful, a null - * TQCString if failure. - */ - static TQCString domainToAscii(const TQString& tqunicodeDomain); - - /** - * Does the inverse of @ref domainToAscii and return an Unicode domain - * name from the given ACE-encoded domain. - * - * This function may fail if the given domain cannot be successfully - * converted back to Unicode. Reasons for failure include a malformed - * domain name or good ones whose reencoding back to ACE don't match - * the form given here (e.g., ACE-encoding of an already - * ASCII-compatible domain). - * - * It is, however, guaranteed that domains returned - * by @ref domainToAscii will work. - * - * @param asciiDomain the ACE-encoded domain name to be decoded - * @return the Unicode representation of the given domain name - * if successful, the original string if not - * @note ACE = ASCII-Compatible Encoding, i.e., 7-bit - */ - static TQString domainToUnicode(const TQCString& asciiDomain); - - /** - * The same as above, but taking a TQString argument. - * - * @param asciiDomain the ACE-encoded domain name to be decoded - * @return the Unicode representation of the given domain name - * if successful, TQString::null if not. - */ - static TQString domainToUnicode(const TQString& asciiDomain); - - /** - * Normalise a domain name. - * - * In order to prevent simple mistakes in International Domain - * Names (IDN), it has been decided that certain code points - * (characters in Unicode) would be instead converted to others. - * This includes turning them all to lower case, as well certain - * other specific operations, as specified in the documents. - * - * For instance, the German 'ß' will be changed into 'ss', while - * the micro symbol 'µ' will be changed to the Greek mu 'μ'. - * - * Two equivalent domains have the same normalised form. And the - * normalised form of a normalised domain is itself (i.e., if - * d is normalised, the following is true: d == normalizeDomain(d) ) - * - * This operation is equivalent to encoding and the decoding a Unicode - * hostname. - * - * @param domain a domain to be normalised - * @return the normalised domain, or TQString::null if the domain is - * invalid. - */ - static TQString normalizeDomain(const TQString& domain); - - /** - * Resolves a protocol number to its names - * - * Note: the returned TQStrList operates on deep-copies. - * - * @param protonum the protocol number to be looked for - * @return all the protocol names in a list. The first is the "proper" - * name. - */ - static TQStrList protocolName(int protonum); - - /** - * Finds all aliases for a given protocol name - * - * @param protoname the protocol name to be looked for - * @return all the protocol names in a list. The first is the "proper" - * name. - */ - static TQStrList protocolName(const char *protoname); - - /** - * Resolves a protocol name to its number - * - * @param protoname the protocol name to be looked for - * @return the protocol number or -1 if we couldn't locate it - */ - static int protocolNumber(const char *protoname); - - /** - * Resolves a service name to its port number - * - * @param servname the service name to be looked for - * @param protoname the protocol it is associated with - * @return the port number in host byte-order or -1 in case of error - */ - static int servicePort(const char *servname, const char *protoname); - - /** - * Finds all the aliases for a given service name - * - * Note: the returned TQStrList operates on deep-copies. - * - * @param servname the service alias to be looked for - * @param protoname the protocol it is associated with - * @return all the service names in a list. The first is the "proper" - * name. - */ - static TQStrList serviceName(const char *servname, const char *protoname); - - /** - * Resolves a port number to its names - * - * Note: the returned TQStrList operates on deep copies. - * - * @param port the port number, in host byte-order - * @param protoname the protocol it is associated with - * @return all the service names in a list. The first is the "proper" - * name. - */ - static TQStrList serviceName(int port, const char *protoname); - - /** - * Returns this machine's local hostname. - * - * @return this machine's local hostname - * @since 3.5 - */ - static TQString localHostName(); - -protected: - - /** - * Sets the error codes - */ - void setError(int errorcode, int systemerror = 0); - - virtual void virtual_hook( int id, void* data ); -private: - KResolverPrivate* d; - friend class KResolverResults; - friend class ::KNetwork::Internal::KResolverManager; - - static TQStringList *idnDomains; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kresolver_p.h b/kdecore/network/kresolver_p.h deleted file mode 100644 index 7f74c6fe6..000000000 --- a/kdecore/network/kresolver_p.h +++ /dev/null @@ -1,353 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KRESOLVER_P_H -#define KRESOLVER_P_H - -#include <config.h> -#include <sys/types.h> - -#include <tqstring.h> -#include <tqcstring.h> -#include <tqvaluelist.h> -#include <tqptrlist.h> -#include <tqptrqueue.h> -#include <tqthread.h> -#include <tqmutex.h> -#include <tqwaitcondition.h> -#include <tqsemaphore.h> -#include <tqevent.h> - -#include "kresolver.h" - -/* decide whether we need a mutex */ -#if !defined(HAVE_GETPROTOBYNAME_R) || !defined(HAVE_GETSERVBYNAME_R) || !defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETSERVBYPORT_R) -# define NEED_MUTEX -extern TQMutex getXXbyYYmutex; -#endif - -/* some systems have the functions, but don't declare them */ -#if defined(HAVE_GETSERVBYNAME_R) && !HAVE_DECL_GETSERVBYNAME_R -extern "C" { - struct servent; - extern int getservbyname_r(const char* serv, const char* proto, - struct servent* servbuf, - char* buf, size_t buflen, - struct servent** result); - extern int getservbyport_r(int port, const char* proto, - struct servent* servbuf, - char* buf, size_t buflen, - struct servent** result); - - struct protoent; - extern int getprotobyname_r(const char* proto, struct protoent* protobuf, - char *buf, size_t buflen, - struct protoent** result); - extern int getprotobynumber_r(int proto, struct protoent* protobuf, - char *buf, size_t buflen, - struct protoent** result); -} -#endif - -/* decide whether res_init is thread-safe or not */ -#if defined(__GLIBC__) -# undef RES_INIT_THREADSAFE -#endif - -namespace KNetwork -{ - // defined in network/qresolverworkerbase.h - class KResolverWorkerBase; - class KResolverWorkerFactoryBase; - class KResolverPrivate; - - namespace Internal - { - class KResolverManager; - class KResolverThread; - struct RequestData; - - struct InputData - { - TQString node, service; - TQCString protocolName; - int flags; - int familyMask; - int socktype; - int protocol; - }; - } - - class KResolverPrivate - { - public: - // parent class. Should never be changed! - KResolver* parent; - bool deleteWhenDone : 1; - bool waiting : 1; - - // class status. Should not be changed by worker threads! - volatile int status; - volatile int errorcode, syserror; - - // input data. Should not be changed by worker threads! - Internal::InputData input; - - // mutex - TQMutex mutex; - - // output data - KResolverResults results; - - KResolverPrivate(KResolver* _parent, - const TQString& _node = TQString::null, - const TQString& _service = TQString::null) - : parent(_parent), deleteWhenDone(false), waiting(false), - status(0), errorcode(0), syserror(0) - { - input.node = _node; - input.service = _service; - input.flags = 0; - input.familyMask = KResolver::AnyFamily; - input.socktype = 0; - input.protocol = 0; - - results.setAddress(_node, _service); - } - }; - - namespace Internal - { - struct RequestData - { - // worker threads should not change values in the input data - KNetwork::KResolverPrivate *obj; - const KNetwork::Internal::InputData *input; - KNetwork::KResolverWorkerBase *worker; // worker class - RequestData *requestor; // class that requested us - - volatile int nRequests; // how many requests that we made we still have left - }; - - /* - * @internal - * This class is the resolver manager - */ - class KResolverManager - { - public: - enum EventTypes - { ResolutionCompleted = 1576 }; // arbitrary value; - - /* - * This wait condition is used to notify wait states (KResolver::wait) that - * the resolver manager has finished processing one or more objects. All - * objects in wait state will be woken up and will check if they are done. - * If they aren't, they will go back to sleeping. - */ - TQWaitCondition notifyWaiters; - - private: - /* - * This variable is used to count the number of threads that are running - */ - volatile unsigned short runningThreads; - - /* - * This variable is used to count the number of threads that are currently - * waiting for data. - */ - unsigned short availableThreads; - - /* - * This wait condition is used to notify worker threads that there is new - * data available that has to be processed. All worker threads wait on this - * waitcond for a limited amount of time. - */ - TQWaitCondition feedWorkers; - - // this mutex protects the data in this object - TQMutex mutex; - - // hold a list of all the current threads we have - TQPtrList<KResolverThread> workers; - - // hold a list of all the new requests we have - TQPtrList<RequestData> newRequests; - - // hold a list of all the requests in progress we have - TQPtrList<RequestData> currentRequests; - - // hold a list of all the workers we have - TQPtrList<KNetwork::KResolverWorkerFactoryBase> workerFactories; - - // private constructor - KResolverManager(); - - public: - static KResolverManager* manager() KDE_NO_EXPORT; // creates and returns the global manager - - // destructor - ~KResolverManager(); - - /* - * Register this thread in the pool - */ - void registerThread(KResolverThread* id); - - /* - * Unregister this thread from the pool - */ - void unregisterThread(KResolverThread* id); - - /* - * Requests new data to work on. - * - * This function should only be called from a worker thread. This function - * is thread-safe. - * - * If there is data to be worked on, this function will return it. If there is - * none, this function will return a null pointer. - */ - RequestData* requestData(KResolverThread* id, int maxWaitTime); - - /* - * Releases the resources and returns the resolved data. - * - * This function should only be called from a worker thread. It is - * thread-safe. It does not post the event to the manager. - */ - void releaseData(KResolverThread *id, RequestData* data); - - /* - * Registers a new worker class by way of its factory. - * - * This function is NOT thread-safe. - */ - void registerNewWorker(KNetwork::KResolverWorkerFactoryBase *factory); - - /* - * Enqueues new resolutions. - */ - void enqueue(KNetwork::KResolver *obj, RequestData* requestor); - - /* - * Dispatch a new request - */ - void dispatch(RequestData* data); - - /* - * Dequeues a resolution. - */ - void dequeue(KNetwork::KResolver *obj); - - /* - * Notifies the manager that the given resolution is about to - * be deleted. This function should only be called by the - * KResolver destructor. - */ - void aboutToBeDeleted(KNetwork::KResolver *obj); - - /* - * Notifies the manager that new events are ready. - */ - void newEvent(); - - /* - * This function is called by the manager to receive a new event. It operates - * on the @ref eventSemaphore semaphore, which means it will block till there - * is at least one event to go. - */ - void receiveEvent(); - - private: - /* - * finds a suitable worker for this request - */ - KNetwork::KResolverWorkerBase *findWorker(KNetwork::KResolverPrivate *p); - - /* - * finds data for this request - */ - RequestData* findData(KResolverThread*); - - /* - * Handle completed requests. - * - * This function is called by releaseData above - */ - void handleFinished(); - - /* - * Handle one completed request. - * - * This function is called by handleFinished above. - */ - bool handleFinishedItem(RequestData* item); - - /* - * Notifies the parent class that this request is done. - * - * This function deletes the request - */ - void doNotifying(RequestData *p); - - /* - * Dequeues and notifies an object that is in Queued state - * Returns true if the object is no longer queued; false if it could not - * be dequeued (i.e., it's running) - */ - bool dequeueNew(KNetwork::KResolver* obj); - }; - - /* - * @internal - * This class is a worker thread in the resolver system. - * This class must be thread-safe. - */ - class KResolverThread: public TQThread - { - private: - // private constructor. Only the manager can create worker threads - KResolverThread(); - RequestData* data; - - protected: - virtual void run(); // here the thread starts - - friend class KNetwork::Internal::KResolverManager; - friend class KNetwork::KResolverWorkerBase; - - public: - bool checkResolver(); // see KResolverWorkerBase::checkResolver - void acquireResolver(); // see KResolverWorkerBase::acquireResolver - void releaseResolver(); // see KResolverWorkerBase::releaseResolver - }; - - } // namespace Internal - -} // namespace KNetwork - - -#endif diff --git a/kdecore/network/kresolvermanager.cpp b/kdecore/network/kresolvermanager.cpp deleted file mode 100644 index b3c7172ae..000000000 --- a/kdecore/network/kresolvermanager.cpp +++ /dev/null @@ -1,822 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -#include <sys/types.h> -#include <netinet/in.h> -#include <limits.h> -#include <unistd.h> // only needed for pid_t - -#ifdef HAVE_RES_INIT -# include <sys/stat.h> -extern "C" { -# include <arpa/nameser.h> -} -# include <time.h> -# include <resolv.h> -#endif - -#include <tqapplication.h> -#include <tqstring.h> -#include <tqcstring.h> -#include <tqptrlist.h> -#include <tqtimer.h> -#include <tqmutex.h> -#include <tqthread.h> -#include <tqwaitcondition.h> -#include <tqsemaphore.h> - -#include <kde_file.h> -#include <kdebug.h> -#include "kresolver.h" -#include "kresolver_p.h" -#include "kresolverworkerbase.h" - -namespace KNetwork -{ - namespace Internal - { - void initSrvWorker(); - void initStandardWorkers(); - } -} - -using namespace KNetwork; -using namespace KNetwork::Internal; - -/* - * Explanation on how the resolver system works - - When KResolver::start is called, it calls KResolverManager::enqueue to add - an entry to the queue. KResolverManager::enqueue will verify the availability - of a worker thread: if one is available, it will dispatch the request to it. - If no threads are available, it will then decide whether to launch a thread - or to queue for the future. - - (This process is achieved by always queueing the new request, starting a - new thread if necessary and then notifying of the availability of data - to all worker threads). - - * Worker thread - A new thread, when started, will enter its event loop - immediately. That is, it'll first try to acquire new data to - process, which means it will lock and unlock the manager mutex in - the process. - - If it finds no new data, it'll wait on the feedWorkers condition - for a certain maximum time. If that time expires and there's still - no data, the thread will exit, in order to save system resources. - - If it finds data, however, it'll set up and call the worker class - that has been selected by the manager. Once that worker is done, - the thread releases the data through KResolverManager::releaseData. - - * Data requesting/releasing - A worker thread always calls upon functions on the resolver manager - in order to acquire and release data. - - When data is being requested, the KResolverManager::requestData - function will look the currentRequests list and return the first - Queued request it finds, while marking it to be InProgress. - - When the worker class has returned, the worker thread will release - that data through the KResolverManager::releaseData function. If the - worker class has requested no further data (nRequests == 0), the - request's status is marked to be Done. It'll then look at the - requestor for that data: if it was requested by another worker, - it'll decrement the requests count for that one and add the results - to a list. And, finally, if the requests count for the requestor - becomes 0, it'll repeat this process for the requestor as well - (change status to Done, check for a requestor). - */ - -namespace -{ - -/* - * This class is used to control the access to the - * system's resolver API. - * - * It is necessary to periodically poll /etc/resolv.conf and reload - * it if any changes are noticed. This class does exactly that. - * - * However, there's also the problem of reloading the structure while - * some threads are in progress. Therefore, we keep a usage reference count. - */ -class ResInitUsage -{ -public: - -#ifdef HAVE_RES_INIT - time_t mTime; - int useCount; - -# ifndef RES_INIT_THREADSAFE - TQWaitCondition cond; - TQMutex mutex; -# endif - - bool shouldResInit() - { - // check if /etc/resolv.conf has changed - KDE_struct_stat st; - if (KDE_stat("/etc/resolv.conf", &st) != 0) - return false; - - if (mTime != st.st_mtime) - { - kdDebug(179) << "shouldResInit: /etc/resolv.conf updated" << endl; - return true; - } - return false; - } - - void callResInit() - { - if (mTime != 0) - { - // don't call it the first time - // let it be initialised naturally - kdDebug(179) << "callResInit: calling res_init()" << endl; - res_init(); - } - - KDE_struct_stat st; - if (KDE_stat("/etc/resolv.conf", &st) == 0) - mTime = st.st_mtime; - } - - ResInitUsage() - : mTime(0), useCount(0) - { } - - /* - * Marks the end of usage to the resolver tools - */ - void release() - { -# ifndef RES_INIT_THREADSAFE - TQMutexLocker locker(&mutex); - if (--useCount == 0) - { - if (shouldResInit()) - callResInit(); - - // we've reached 0, wake up anyone that's waiting to call res_init - cond.wakeAll(); - } -# else - // do nothing -# endif - } - - /* - * Marks the beginning of usage of the resolver API - */ - void acquire() - { -# ifndef RES_INIT_THREADSAFE - mutex.lock(); - - if (shouldResInit()) - { - if (useCount) - { - // other threads are already using the API, so wait till - // it's all clear - // the thread that emits this condition will also call res_init - //qDebug("ResInitUsage: waiting for libresolv to be clear"); - cond.wait(&mutex); - } - else - // we're clear - callResInit(); - } - useCount++; - mutex.unlock(); - -# else - if (shouldResInit()) - callResInit(); - -# endif - } - -#else - ResInitUsage() - { } - - bool shouldResInit() - { return false; } - - void acquire() - { } - - void release() - { } -#endif - -} resInit; - -} // anonymous namespace - -/* - * parameters - */ -// a thread will try maxThreadRetries to get data, waiting at most -// maxThreadWaitTime milliseconds between each attempt. After that, it'll -// exit -static const int maxThreadWaitTime = 2000; // 2 seconds -static const int maxThreads = 5; - -static pid_t pid; // FIXME -- disable when everything is ok - -KResolverThread::KResolverThread() - : data(0L) -{ -} - -// remember! This function runs in a separate thread! -void KResolverThread::run() -{ - // initialisation - // enter the loop already - - //qDebug("KResolverThread(thread %u/%p): started", pid, (void*)TQThread::currentThread()); - KResolverManager::manager()->registerThread(this); - while (true) - { - data = KResolverManager::manager()->requestData(this, ::maxThreadWaitTime); - //qDebug("KResolverThread(thread %u/%p) got data %p", KResolverManager::pid, - // (void*)TQThread::currentThread(), (void*)data); - if (data) - { - // yes, we got data - // process it! - - // 1) set up - ; - - // 2) run it - data->worker->run(); - - // 3) release data - KResolverManager::manager()->releaseData(this, data); - - // now go back to the loop - } - else - break; - } - - KResolverManager::manager()->unregisterThread(this); - //qDebug("KResolverThread(thread %u/%p): exiting", pid, (void*)TQThread::currentThread()); -} - -bool KResolverThread::checkResolver() -{ - return resInit.shouldResInit(); -} - -void KResolverThread::acquireResolver() -{ -#if defined(NEED_MUTEX) && !defined(Q_OS_FREEBSD) - getXXbyYYmutex.lock(); -#endif - - resInit.acquire(); -} - -void KResolverThread::releaseResolver() -{ -#if defined(NEED_MUTEX) && !defined(Q_OS_FREEBSD) - getXXbyYYmutex.unlock(); -#endif - - resInit.release(); -} - -static KResolverManager *globalManager; - -KResolverManager* KResolverManager::manager() -{ - if (globalManager == 0L) - new KResolverManager(); - return globalManager; -} - -KResolverManager::KResolverManager() - : runningThreads(0), availableThreads(0) -{ - globalManager = this; - workers.setAutoDelete(true); - currentRequests.setAutoDelete(true); - initSrvWorker(); - initStandardWorkers(); - - pid = getpid(); -} - -KResolverManager::~KResolverManager() -{ - // this should never be called - - // kill off running threads - for (workers.first(); workers.current(); workers.next()) - workers.current()->terminate(); -} - -void KResolverManager::registerThread(KResolverThread* ) -{ -} - -void KResolverManager::unregisterThread(KResolverThread*) -{ - runningThreads--; -} - -// this function is called by KResolverThread::run -RequestData* KResolverManager::requestData(KResolverThread *th, int maxWaitTime) -{ - ///// - // This function is called in a worker thread!! - ///// - - // lock the mutex, so that the manager thread or other threads won't - // interfere. - TQMutexLocker locker(&mutex); - RequestData *data = findData(th); - - if (data) - // it found something, that's good - return data; - - // nope, nothing found; sleep for a while - availableThreads++; - feedWorkers.wait(&mutex, maxWaitTime); - availableThreads--; - - data = findData(th); - return data; -} - -RequestData* KResolverManager::findData(KResolverThread* th) -{ - ///// - // This function is called by @ref requestData above and must - // always be called with a locked mutex - ///// - - // now find data to be processed - for (RequestData *curr = newRequests.first(); curr; curr = newRequests.next()) - if (!curr->worker->m_finished) - { - // found one - if (curr->obj) - curr->obj->status = KResolver::InProgress; - curr->worker->th = th; - - // move it to the currentRequests list - currentRequests.append(newRequests.take()); - - return curr; - } - - // found nothing! - return 0L; -} - -// this function is called by KResolverThread::run -void KResolverManager::releaseData(KResolverThread *, RequestData* data) -{ - ///// - // This function is called in a worker thread!! - ///// - - //qDebug("KResolverManager::releaseData(%u/%p): %p has been released", pid, -// (void*)TQThread::currentThread(), (void*)data); - - if (data->obj) - { - data->obj->status = KResolver::PostProcessing; - } - - data->worker->m_finished = true; - data->worker->th = 0L; // this releases the object - - // handle finished requests - handleFinished(); -} - -// this function is called by KResolverManager::releaseData above -void KResolverManager::handleFinished() -{ - bool redo = false; - TQPtrQueue<RequestData> doneRequests; - - mutex.lock(); - - // loop over all items on the currently running list - // we loop from the last to the first so that we catch requests with "requestors" before - // we catch the requestor itself. - RequestData *curr = currentRequests.last(); - while (curr) - { - if (curr->worker->th == 0L) - { - if (handleFinishedItem(curr)) - { - doneRequests.enqueue(currentRequests.take()); - if (curr->requestor && - curr->requestor->nRequests == 0 && - curr->requestor->worker->m_finished) - // there's a requestor that is now finished - redo = true; - } - } - - curr = currentRequests.prev(); - } - - //qDebug("KResolverManager::handleFinished(%u): %d requests to notify", pid, doneRequests.count()); - while (RequestData *d = doneRequests.dequeue()) - doNotifying(d); - - mutex.unlock(); - - if (redo) - { - //qDebug("KResolverManager::handleFinished(%u): restarting processing to catch requestor", - // pid); - handleFinished(); - } -} - -// This function is called by KResolverManager::handleFinished above -bool KResolverManager::handleFinishedItem(RequestData* curr) - -{ - // for all items that aren't currently running, remove from the list - // this includes all finished or cancelled requests - - if (curr->worker->m_finished && curr->nRequests == 0) - { - // this one has finished - if (curr->obj) - curr->obj->status = KResolver::PostProcessing; // post-processing is run in doNotifying() - - if (curr->requestor) - --curr->requestor->nRequests; - - //qDebug("KResolverManager::handleFinishedItem(%u): removing %p since it's done", - // pid, (void*)curr); - return true; - } - return false; -} - - - -void KResolverManager::registerNewWorker(KResolverWorkerFactoryBase *factory) -{ - workerFactories.append(factory); -} - -KResolverWorkerBase* KResolverManager::findWorker(KResolverPrivate* p) -{ - ///// - // this function can be called on any user thread - ///// - - // this function is called with an unlocked mutex and it's expected to be - // thread-safe! - // but the factory list is expected not to be changed asynchronously - - // This function is responsible for finding a suitable worker for the given - // input. That means we have to do a costly operation to create each worker - // class and call their preprocessing functions. The first one that - // says they can process (i.e., preprocess() returns true) will get the job. - - KResolverWorkerBase *worker; - for (KResolverWorkerFactoryBase *factory = workerFactories.first(); factory; - factory = workerFactories.next()) - { - worker = factory->create(); - - // set up the data the worker needs to preprocess - worker->input = &p->input; - - if (worker->preprocess()) - { - // good, this one says it can process - if (worker->m_finished) - p->status = KResolver::PostProcessing; - else - p->status = KResolver::Queued; - return worker; - } - - // no, try again - delete worker; - } - - // found no worker - return 0L; -} - -void KResolverManager::doNotifying(RequestData *p) -{ - ///// - // This function may be called on any thread - // any thread at all: user threads, GUI thread, manager thread or worker thread - ///// - - // Notification and finalisation - // - // Once a request has finished the normal processing, we call the - // post processing function. - // - // After that is done, we will consolidate all results in the object's - // KResolverResults and then post an event indicating that the signal - // be emitted - // - // In case we detect that the object is waiting for completion, we do not - // post the event, for KResolver::wait will take care of emitting the - // signal. - // - // Once we release the mutex on the object, we may no longer reference it - // for it might have been deleted. - - // "User" objects are those that are not created by the manager. Note that - // objects created by worker threads are considered "user" objects. Objects - // created by the manager are those created for KResolver::resolveAsync. - // We should delete them. - - if (p->obj) - { - // lock the object - p->obj->mutex.lock(); - KResolver* parent = p->obj->parent; // is 0 for non-"user" objects - KResolverResults& r = p->obj->results; - - if (p->obj->status == KResolver::Canceled) - { - p->obj->status = KResolver::Canceled; - p->obj->errorcode = KResolver::Canceled; - p->obj->syserror = 0; - r.setError(KResolver::Canceled, 0); - } - else if (p->worker) - { - // post processing - p->worker->postprocess(); // ignore the result - - // copy the results from the worker thread to the final - // object - r = p->worker->results; - - // reset address - r.setAddress(p->input->node, p->input->service); - - //qDebug("KResolverManager::doNotifying(%u/%p): for %p whose status is %d and has %d results", - //pid, (void*)TQThread::currentThread(), (void*)p, p->obj->status, r.count()); - - p->obj->errorcode = r.error(); - p->obj->syserror = r.systemError(); - p->obj->status = !r.isEmpty() ? - KResolver::Success : KResolver::Failed; - } - else - { - r.empty(); - r.setError(p->obj->errorcode, p->obj->syserror); - } - - // check whether there's someone waiting - if (!p->obj->waiting && parent) - // no, so we must post an event requesting that the signal be emitted - // sorry for the C-style cast, but neither static nor reintepret cast work - // here; I'd have to do two casts - TQApplication::postEvent(parent, new TQEvent((TQEvent::Type)(ResolutionCompleted))); - - // release the mutex - p->obj->mutex.unlock(); - } - else - { - // there's no object! - if (p->worker) - p->worker->postprocess(); - } - - delete p->worker; - - // ignore p->requestor and p->nRequests - // they have been dealt with by the main loop - - delete p; - - // notify any objects waiting in KResolver::wait - notifyWaiters.wakeAll(); -} - -// enqueue a new request -// this function is called from KResolver::start and -// from KResolverWorkerBase::enqueue -void KResolverManager::enqueue(KResolver *obj, RequestData *requestor) -{ - RequestData *newrequest = new RequestData; - newrequest->nRequests = 0; - newrequest->obj = obj->d; - newrequest->input = &obj->d->input; - newrequest->requestor = requestor; - - // when processing a new request, find the most - // suitable worker - if ((newrequest->worker = findWorker(obj->d)) == 0L) - { - // oops, problem - // cannot find a worker class for this guy - obj->d->status = KResolver::Failed; - obj->d->errorcode = KResolver::UnsupportedFamily; - obj->d->syserror = 0; - - doNotifying(newrequest); - return; - } - - // no, queue it - // p->status was set in findWorker! - if (requestor) - requestor->nRequests++; - - if (!newrequest->worker->m_finished) - dispatch(newrequest); - else if (newrequest->nRequests > 0) - { - mutex.lock(); - currentRequests.append(newrequest); - mutex.unlock(); - } - else - // already done - doNotifying(newrequest); -} - -// a new request has been created -// dispatch it -void KResolverManager::dispatch(RequestData *data) -{ - // As stated in the beginning of the file, this function - // is supposed to verify the availability of threads, start - // any if necessary - - TQMutexLocker locker(&mutex); - - // add to the queue - newRequests.append(data); - - // check if we need to start a new thread - // - // we depend on the variables availableThreads and runningThreads to - // know if we are supposed to start any threads: - // - if availableThreads > 0, then there is at least one thread waiting, - // blocked in KResolverManager::requestData. It can't unblock - // while we are holding the mutex locked, therefore we are sure that - // our event will be handled - // - if availableThreads == 0: - // - if runningThreads < maxThreads - // we will start a new thread, which will certainly block in - // KResolverManager::requestData because we are holding the mutex locked - // - if runningThreads == maxThreads - // This situation generally means that we have already maxThreads running - // and that all of them are processing. We will not start any new threads, - // but will instead wait for one to finish processing and request new data - // - // There's a possible race condition here, which goes unhandled: if one of - // threads has timed out waiting for new data and is in the process of - // exiting. In that case, availableThreads == 0 and runningThreads will not - // have decremented yet. This means that we will not start a new thread - // that we could have. However, since there are other threads working, our - // event should be handled soon. - // It won't be handled if and only if ALL threads are in the process of - // exiting. That situation is EXTREMELY unlikely and is not handled either. - // - if (availableThreads == 0 && runningThreads < maxThreads) - { - // yes, a new thread should be started - - // find if there's a finished one - KResolverThread *th = workers.first(); - while (th && th->running()) - th = workers.next(); - - if (th == 0L) - // no, create one - th = new KResolverThread; - else - workers.take(); - - th->start(); - workers.append(th); - runningThreads++; - } - - feedWorkers.wakeAll(); - - // clean up idle threads - workers.first(); - while (workers.current()) - { - if (!workers.current()->running()) - workers.remove(); - else - workers.next(); - } -} - -// this function is called by KResolverManager::dequeue -bool KResolverManager::dequeueNew(KResolver* obj) -{ - // This function must be called with a locked mutex - // Deadlock warning: - // always lock the global mutex first if both mutexes must be locked - - KResolverPrivate *d = obj->d; - - // check if it's in the new request list - RequestData *curr = newRequests.first(); - while (curr) - if (curr->obj == d) - { - // yes, this object is still in the list - // but it has never been processed - d->status = KResolver::Canceled; - d->errorcode = KResolver::Canceled; - d->syserror = 0; - newRequests.take(); - - delete curr->worker; - delete curr; - - return true; - } - else - curr = newRequests.next(); - - // check if it's running - curr = currentRequests.first(); - while (curr) - if (curr->obj == d) - { - // it's running. We cannot simply take it out of the list. - // it will be handled when the thread that is working on it finishes - d->mutex.lock(); - - d->status = KResolver::Canceled; - d->errorcode = KResolver::Canceled; - d->syserror = 0; - - // disengage from the running threads - curr->obj = 0L; - curr->input = 0L; - if (curr->worker) - curr->worker->input = 0L; - - d->mutex.unlock(); - } - else - curr = currentRequests.next(); - - return false; -} - -// this function is called by KResolver::cancel -// it's expected to be thread-safe -void KResolverManager::dequeue(KResolver *obj) -{ - TQMutexLocker locker(&mutex); - dequeueNew(obj); -} diff --git a/kdecore/network/kresolverstandardworkers.cpp b/kdecore/network/kresolverstandardworkers.cpp deleted file mode 100644 index 6236cc15d..000000000 --- a/kdecore/network/kresolverstandardworkers.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2004 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <netinet/in.h> -#include <netdb.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#ifdef HAVE_NET_IF_H -#include <net/if.h> -#endif - -#include <tqthread.h> -#include <tqmutex.h> -#include <tqstrlist.h> -#include <tqfile.h> - -#include "kdebug.h" -#include "kglobal.h" -#include "kstandarddirs.h" -#include "kapplication.h" - -#include "kresolver.h" -#include "ksocketaddress.h" -#include "kresolverstandardworkers_p.h" - -struct hostent; -struct addrinfo; - -using namespace KNetwork; -using namespace KNetwork::Internal; - -static bool hasIPv6() -{ -#ifndef AF_INET6 - return false; -#else - if (getenv("KDE_NO_IPV6") != 0L) - return false; - - int fd = ::socket(AF_INET6, SOCK_STREAM, 0); - if (fd == -1) - return false; - - ::close(fd); - return true; -#endif -} - -// blacklist management -static TQMutex blacklistMutex; // KDE4: change to a QReadWriteLock -TQStringList KBlacklistWorker::blacklist; - -void KBlacklistWorker::init() -{ - // HACK! - // FIXME KDE4: How do I detect there is an instance, without triggering - // its creation or an assertion fault? - if (!KGlobal::_instance) - return; - - static bool beenhere = false; - - if (beenhere) - return; - - beenhere = true; - loadBlacklist(); -} - -void KBlacklistWorker::loadBlacklist() -{ - TQMutexLocker locker(&blacklistMutex); - TQStringList filelist = KGlobal::dirs()->findAllResources("config", "ipv6blacklist"); - - TQStringList::ConstIterator it = filelist.constBegin(), - end = filelist.constEnd(); - for ( ; it != end; ++it) - { - // for each file, each line is a domainname to be blacklisted - TQFile f(*it); - if (!f.open(IO_ReadOnly)) - continue; - - TQTextStream stream(&f); - stream.setEncoding(TQTextStream::Latin1); - for (TQString line = stream.readLine(); !line.isNull(); - line = stream.readLine()) - { - if (line.isEmpty()) - continue; - - // make sure there are no surrounding whitespaces - // and that it starts with . - line = line.stripWhiteSpace(); - if (line[0] != '.') - line.prepend('.'); - - blacklist.append(line.lower()); - } - } -} - -// checks the blacklist to see if the domain is listed -// it matches the domain ending part -bool KBlacklistWorker::isBlacklisted(const TQString& host) -{ - KBlacklistWorker::init(); - - // empty hostnames cannot be blacklisted - if (host.isEmpty()) - return false; - - // KDE4: QLatin1String - TQString ascii = TQString::tqfromLatin1(KResolver::domainToAscii(host)); - - TQMutexLocker locker(&blacklistMutex); - - // now find out if this hostname is present - TQStringList::ConstIterator it = blacklist.constBegin(), - end = blacklist.constEnd(); - for ( ; it != end; ++it) - if (ascii.endsWith(*it)) - return true; - - // no match: - return false; -} - -bool KBlacklistWorker::preprocess() -{ - if (isBlacklisted(nodeName())) - { - results.setError(KResolver::NoName); - finished(); - return true; - } - return false; -} - -bool KBlacklistWorker::run() -{ - results.setError(KResolver::NoName); - finished(); - return false; // resolution failure -} - -namespace -{ - /* - * Note on the use of the system resolver functions: - * - * In all cases, we prefer to use the new getaddrinfo(3) call. That means - * it will always be used if it is found. - * - * If it's not found, we have the option to use gethostbyname2_r, - * gethostbyname_r, gethostbyname2 and gethostbyname. If gethostbyname2_r - * is defined, we will use it. - * - * If it's not defined, we have to choose between the non-reentrant - * gethostbyname2 and the reentrant but IPv4-only gethostbyname_r: - * we will choose gethostbyname2 if AF_INET6 is defined. - * - * Lastly, gethostbyname will be used if nothing else is present. - */ - -#ifndef HAVE_GETADDRINFO - -# if defined(HAVE_GETHOSTBYNAME2_R) -# define USE_GETHOSTBYNAME2_R -# elif defined(HAVE_GETHOSTBYNAME_R) && (!defined(AF_INET6) || !defined(HAVE_GETHOSTBYNAME2)) -# define USE_GETHOSTBYNAME_R -# elif defined(HAVE_GETHOSTBYNAME2) -# define USE_GETHOSTBYNAME2) -# else -# define USE_GETHOSTBYNAME -# endif - - class GetHostByNameThread: public KResolverWorkerBase - { - public: - TQCString m_hostname; // might be different! - TQ_UINT16 m_port; - int m_scopeid; - int m_af; - KResolverResults& results; - - GetHostByNameThread(const char * hostname, TQ_UINT16 port, - int scopeid, int af, KResolverResults* res) : - m_hostname(hostname), m_port(port), m_scopeid(scopeid), m_af(af), - results(*res) - { } - - ~GetHostByNameThread() - { } - - virtual bool preprocess() - { return true; } - - virtual bool run(); - - void processResults(hostent* he, int my_h_errno); - }; - - bool GetHostByNameThread::run() - { - - hostent *resultptr; - hostent my_results; - unsigned buflen = 1024; - int res; - int my_h_errno; - char *buf = 0L; - - // qDebug("ResolveThread::run(): started threaded gethostbyname for %s (af = %d)", - // m_hostname.data(), m_af); - - ResolverLocker resLock( this ); - do - { - res = 0; - my_h_errno = HOST_NOT_FOUND; - - // check blacklist - if (m_af != AF_INET && - KBlacklistWorker::isBlacklisted(TQString::tqfromLatin1(m_hostname))) - break; - -# ifdef USE_GETHOSTBYNAME2_R - buf = new char[buflen]; - res = gethostbyname2_r(m_hostname, m_af, &my_results, buf, buflen, - &resultptr, &my_h_errno); - -# elif defined(USE_GETHOSTBYNAME_R) - if (m_af == AF_INET) - { - buf = new char[buflen]; - res = gethostbyname_r(m_hostname, &my_results, buf, buflen, - &resultptr, &my_h_errno); - } - else - resultptr = 0; // signal error - -# elif defined(USE_GETHOSTBYNAME2) - // must lock mutex - resultptr = gethostbyname2(m_hostname, m_af); - my_h_errno = h_errno; - -# else - if (m_af == AF_INET) - { - // must lock mutex - resultptr = gethostbyname(m_hostname); - my_h_errno = h_errno; - } - else - resultptr = 0; -# endif - - if (resultptr != 0L) - my_h_errno = 0; - // qDebug("GetHostByNameThread::run(): gethostbyname for %s (af = %d) returned: %d", - // m_hostname.data(), m_af, my_h_errno); - - if (res == ERANGE) - { - // Enlarge the buffer - buflen += 1024; - delete [] buf; - buf = new char[buflen]; - } - - if ((res == ERANGE || my_h_errno != 0) && checkResolver()) - { - // resolver needs updating, so we might as well do it now - resLock.openClose(); - } - } - while (res == ERANGE); - processResults(resultptr, my_h_errno); - - delete [] buf; - - finished(); - return results.error() == KResolver::NoError; - } - - void GetHostByNameThread::processResults(hostent *he, int herrno) - { - if (herrno) - { - qDebug("KStandardWorker::processResults: got error %d", herrno); - switch (herrno) - { - case HOST_NOT_FOUND: - results.setError(KResolver::NoName); - return; - - case TRY_AGAIN: - results.setError(KResolver::TryAgain); - return; - - case NO_RECOVERY: - results.setError(KResolver::NonRecoverable); - return; - - case NO_ADDRESS: - results.setError(KResolver::NoName); - return; - - default: - results.setError(KResolver::UnknownError); - return; - } - } - else if (he == 0L) - { - results.setError(KResolver::NoName); - return; // this was an error - } - - // clear any errors - setError(KResolver::NoError); - results.setError(KResolver::NoError); - - // we process results in the reverse order - // that is, we prepend each result to the list of results - int proto = protocol(); - int socktype = socketType(); - if (socktype == 0) - socktype = SOCK_STREAM; // default - - TQString canon = KResolver::domainToUnicode(TQString::tqfromLatin1(he->h_name)); - KInetSocketAddress sa; - sa.setPort(m_port); - if (he->h_addrtype != AF_INET) - sa.setScopeId(m_scopeid); // this will also change the socket into IPv6 - - for (int i = 0; he->h_addr_list[i]; i++) - { - sa.setHost(KIpAddress(he->h_addr_list[i], he->h_addrtype == AF_INET ? 4 : 6)); - results.prepend(KResolverEntry(sa, socktype, proto, canon, m_hostname)); - // qDebug("KStandardWorker::processResults: adding %s", sa.toString().latin1()); - } - // qDebug("KStandardWorker::processResults: added %d entries", i); - } - -#else // HAVE_GETADDRINFO - - class GetAddrInfoThread: public KResolverWorkerBase - { - public: - TQCString m_node; - TQCString m_serv; - int m_af; - int m_flags; - KResolverResults& results; - - GetAddrInfoThread(const char* node, const char* serv, int af, int flags, - KResolverResults* res) : - m_node(node), m_serv(serv), m_af(af), m_flags(flags), results(*res) - { } - - ~GetAddrInfoThread() - { } - - virtual bool preprocess() - { return true; } - - virtual bool run(); - - void processResults(addrinfo* ai, int ret_code, KResolverResults& rr); - }; - - bool GetAddrInfoThread::run() - { - // check blacklist - if ((m_af != AF_INET && m_af != AF_UNSPEC) && - KBlacklistWorker::isBlacklisted(TQString::tqfromLatin1(m_node))) - { - results.setError(KResolver::NoName); - finished(); - return false; // failed - } - - do - { - ResolverLocker resLock( this ); - - // process hints - addrinfo hint; - memset(&hint, 0, sizeof(hint)); - hint.ai_family = m_af; - hint.ai_socktype = socketType(); - hint.ai_protocol = protocol(); - - if (hint.ai_socktype == 0) - hint.ai_socktype = SOCK_STREAM; // default - - if (m_flags & KResolver::Passive) - hint.ai_flags |= AI_PASSIVE; - if (m_flags & KResolver::CanonName) - hint.ai_flags |= AI_CANONNAME; -# ifdef AI_NUMERICHOST - if (m_flags & KResolver::NoResolve) - hint.ai_flags |= AI_NUMERICHOST; -# endif -# ifdef AI_ADDRCONFIG - hint.ai_flags |= AI_ADDRCONFIG; -# endif - - // now we do the blocking processing - if (m_node.isEmpty()) - m_node = "*"; - - addrinfo *result; - int res = getaddrinfo(m_node, m_serv, &hint, &result); - // kdDebug(179) << k_funcinfo << "getaddrinfo(\"" - // << m_node << "\", \"" << m_serv << "\", af=" - // << m_af << ") returned " << res << endl; - - if (res != 0) - { - if (checkResolver()) - { - // resolver requires reinitialisation - resLock.openClose(); - continue; - } - - switch (res) - { - case EAI_BADFLAGS: - results.setError(KResolver::BadFlags); - break; - -#ifdef EAI_NODATA - // In some systems, EAI_NODATA was #define'd to EAI_NONAME which would break this case. -#if EAI_NODATA != EAI_NONAME - case EAI_NODATA: // it was removed in RFC 3493 -#endif -#endif - case EAI_NONAME: - results.setError(KResolver::NoName); - break; - - case EAI_AGAIN: - results.setError(KResolver::TryAgain); - break; - - case EAI_FAIL: - results.setError(KResolver::NonRecoverable); - break; - - case EAI_FAMILY: - results.setError(KResolver::UnsupportedFamily); - break; - - case EAI_SOCKTYPE: - results.setError(KResolver::UnsupportedSocketType); - break; - - case EAI_SERVICE: - results.setError(KResolver::UnsupportedService); - break; - - case EAI_MEMORY: - results.setError(KResolver::Memory); - break; - - case EAI_SYSTEM: - results.setError(KResolver::SystemError, errno); - break; - - default: - results.setError(KResolver::UnknownError, errno); - break; - } - - finished(); - return false; // failed - } - - // if we are here, lookup succeeded - TQString canon; - const char *previous_canon = 0L; - - for (addrinfo* p = result; p; p = p->ai_next) - { - // cache the last canon name to avoid doing the ToUnicode processing unnecessarily - if ((previous_canon && !p->ai_canonname) || - (!previous_canon && p->ai_canonname) || - (p->ai_canonname != previous_canon && - strcmp(p->ai_canonname, previous_canon) != 0)) - { - canon = KResolver::domainToUnicode(TQString::fromAscii(p->ai_canonname)); - previous_canon = p->ai_canonname; - } - - results.append(KResolverEntry(p->ai_addr, p->ai_addrlen, p->ai_socktype, - p->ai_protocol, canon, m_node)); - } - - freeaddrinfo(result); - results.setError(KResolver::NoError); - finished(); - return results.error() == KResolver::NoError; - } - while (true); - } - -#endif // HAVE_GETADDRINFO -} // namespace - -bool KStandardWorker::sanityCheck() -{ - // check that the requested values are sensible - - if (!nodeName().isEmpty()) - { - TQString node = nodeName(); - if (node.find('%') != -1) - node.truncate(node.find('%')); - - if (node.isEmpty() || node == TQString::tqfromLatin1("*") || - node == TQString::tqfromLatin1("localhost")) - m_encodedName.truncate(0); - else - { - m_encodedName = KResolver::domainToAscii(node); - - if (m_encodedName.isNull()) - { - qDebug("could not encode hostname '%s' (UTF-8)", node.utf8().data()); - setError(KResolver::NoName); - return false; // invalid hostname! - } - - // qDebug("Using encoded hostname '%s' for '%s' (UTF-8)", m_encodedName.data(), - // node.utf8().data()); - } - } - else - m_encodedName.truncate(0); // just to be sure, but it should be clear already - - if (protocol() == -1) - { - setError(KResolver::NonRecoverable); - return false; // user passed invalid protocol name - } - - return true; // it's sane -} - -bool KStandardWorker::resolveScopeId() -{ - // we must test the original name, not the encoded one - scopeid = 0; - int pos = nodeName().findRev('%'); - if (pos == -1) - return true; - - TQString scopename = nodeName().mid(pos + 1); - - bool ok; - scopeid = scopename.toInt(&ok); - if (!ok) - { - // it's not a number - // therefore, it's an interface name -#ifdef HAVE_IF_NAMETOINDEX - scopeid = if_nametoindex(scopename.latin1()); -#else - scopeid = 0; -#endif - } - - return true; -} - -bool KStandardWorker::resolveService() -{ - // find the service first - bool ok; - port = serviceName().toUInt(&ok); - if (!ok) - { - // service name does not contain a port number - // must be a name - - if (serviceName().isEmpty() || serviceName().compare(TQString::tqfromLatin1("*")) == 0) - port = 0; - else - { - // it's a name. We need the protocol name in order to lookup. - TQCString protoname = protocolName(); - - if (protoname.isEmpty() && protocol()) - { - protoname = KResolver::protocolName(protocol()).first(); - - // if it's still empty... - if (protoname.isEmpty()) - { - // lookup failed! - setError(KResolver::NoName); - return false; - } - } - else - protoname = "tcp"; - - // it's not, so we can do a port lookup - int result = KResolver::servicePort(serviceName().latin1(), protoname); - if (result == -1) - { - // lookup failed! - setError(KResolver::NoName); - return false; - } - - // it worked, we have a port number - port = (TQ_UINT16)result; - } - } - - // we found a port - return true; -} - -KResolver::ErrorCodes KStandardWorker::addUnix() -{ - // before trying to add, see if the user wants Unix sockets - if ((familyMask() & KResolver::UnixFamily) == 0) - // no, Unix sockets are not wanted - return KResolver::UnsupportedFamily; - - // now check if the requested data are good for a Unix socket - if (!m_encodedName.isEmpty()) - return KResolver::AddrFamily; // non local hostname - - if (protocol() || !protocolName().isEmpty()) - return KResolver::BadFlags; // cannot have Unix sockets with protocols - - TQString pathname = serviceName(); - if (pathname.isEmpty()) - return KResolver::NoName;; // no path? - - if (pathname[0] != '/') - // non absolute pathname - // put it in /tmp - pathname.prepend("/tmp/"); - - // qDebug("QNoResolveWorker::addUnix(): adding Unix socket for %s", pathname.local8Bit().data()); - KUnixSocketAddress sa(pathname); - int socktype = socketType(); - if (socktype == 0) - socktype = SOCK_STREAM; // default - - results.append(KResolverEntry(sa, socktype, 0)); - setError(KResolver::NoError); - - return KResolver::NoError; -} - -bool KStandardWorker::resolveNumerically() -{ - // if the NoResolve flag is active, our result from this point forward - // will always be true, even if the resolution failed. - // that indicates that our result is authoritative. - - bool wantV4 = familyMask() & KResolver::IPv4Family, - wantV6 = familyMask() & KResolver::IPv6Family; - - if (!wantV6 && !wantV4) - // no Internet address is wanted! - return (flags() & KResolver::NoResolve); - - // now try to find results - if (!resolveScopeId() || !resolveService()) - return (flags() & KResolver::NoResolve); - - // we have scope IDs and port numbers - // now try to resolve the hostname numerically - KInetSocketAddress sa; - setError(KResolver::NoError); - sa.setHost(KIpAddress(TQString::tqfromLatin1(m_encodedName))); - - // if it failed, the length was reset to 0 - bool ok = sa.length() != 0; - - sa.setPort(port); - if (sa.ipVersion() == 6) - sa.setScopeId(scopeid); - int proto = protocol(); - int socktype = socketType(); - if (socktype == 0) - socktype = SOCK_STREAM; - - if (ok) - { - // the given hostname was successfully converted to an IP address - // check if the user wanted this kind of address - - if ((sa.ipVersion() == 4 && wantV4) || - (sa.ipVersion() == 6 && wantV6)) - results.append(KResolverEntry(sa, socktype, proto)); - else - { - // Note: the address *IS* a numeric IP - // but it's not of the kind the user asked for - // - // that means that it cannot be a Unix socket (because it's an IP) - // and that means that no resolution will tell us otherwise - // - // This is a failed resolution - - setError(KResolver::AddrFamily); - return true; - } - } - else if (m_encodedName.isEmpty()) - { - // user wanted localhost - if (flags() & KResolver::Passive) - { - if (wantV6) - { - sa.setHost(KIpAddress::anyhostV6); - results.append(KResolverEntry(sa, socktype, proto)); - } - - if (wantV4) - { - sa.setHost(KIpAddress::anyhostV4); - results.append(KResolverEntry(sa, socktype, proto)); - } - } - else - { - if (wantV6) - { - sa.setHost(KIpAddress::localhostV6); - results.append(KResolverEntry(sa, socktype, proto)); - } - - if (wantV4) - { - sa.setHost(KIpAddress::localhostV4); - results.append(KResolverEntry(sa, socktype, proto)); - } - } - - ok = true; - } - else - { - // probably bad flags, since the address is not convertible without - // resolution - - setError(KResolver::BadFlags); - ok = false; - } - - return ok || (flags() & KResolver::NoResolve); -} - -bool KStandardWorker::preprocess() -{ - // check sanity - if (!sanityCheck()) - return false; - - // this worker class can only handle known families - if (familyMask() & KResolver::UnknownFamily) - { - setError(KResolver::UnsupportedFamily); - return false; // we don't know about this - } - - // check the socket types - if (socketType() != SOCK_STREAM && socketType() != SOCK_DGRAM && socketType() != 0) - { - setError(KResolver::UnsupportedSocketType); - return false; - } - - // check if we can resolve all numerically - // resolveNumerically always returns true if the NoResolve flag is set - if (resolveNumerically() || m_encodedName.isEmpty()) - { - // indeed, we have resolved numerically - setError(addUnix()); - if (results.count()) - setError(KResolver::NoError); - finished(); - return true; - } - - // check if the user wants something we know about -#ifdef AF_INET6 -# define mask (KResolver::IPv6Family | KResolver::IPv4Family | KResolver::UnixFamily) -#else -# define mask (KResolver::IPv4Family | KResolver::UnixFamily) -#endif - - if ((familyMask() & mask) == 0) - // errr... nothing we know about - return false; - -#undef mask - - return true; // it's ok -} - -bool KStandardWorker::run() -{ -#ifndef HAVE_GETADDRINFO - // check the scope id first - // since most of the resolutions won't have a scope id, this should be fast - // and we won't have wasted time on services if this fails - if (!resolveScopeId()) - return false; - - // resolve the service now, before entering the blocking operation - if (!resolveService()) - return false; -#endif - - // good - // now we need the hostname - setError(KResolver::NoName); - - // these are the family types that we know of - struct - { - KResolver::SocketFamilies mask; - int af; - } families[] = { { KResolver::IPv4Family, AF_INET } -#ifdef AF_INET6 - , { KResolver::IPv6Family, AF_INET6 } -#endif - }; - int familyCount = sizeof(families)/sizeof(families[0]); - bool skipIPv6 = !hasIPv6(); - resultList.setAutoDelete(true); - - for (int i = 0; i < familyCount; i++) - if (familyMask() & families[i].mask) - { -#ifdef AF_INET6 - if (skipIPv6 && families[i].af == AF_INET6) - continue; -#endif - - KResolverWorkerBase *worker; - KResolverResults *res = new KResolverResults; - resultList.append(res); -#ifdef HAVE_GETADDRINFO - worker = new GetAddrInfoThread(m_encodedName, - serviceName().latin1(), - families[i].af, flags(), res); -#else - worker = new GetHostByNameThread(m_encodedName, port, scopeid, - families[i].af, res); -#endif - - enqueue(worker); - } - - // not finished - return true; -} - -bool KStandardWorker::postprocess() -{ - if (results.count()) - return true; // no need - // now copy over what we need from the underlying results - - // start backwards because IPv6 was launched later (if at all) - if (resultList.isEmpty()) - { - results.setError(KResolver::NoName); - return true; - } - - KResolverResults *rr = resultList.last(); - while (rr) - { - if (!rr->isEmpty()) - { - results.setError(KResolver::NoError); - KResolverResults::Iterator it = rr->begin(); - for ( ; it != rr->end(); ++it) - results.append(*it); - } - else if (results.isEmpty()) - // this generated an error - // copy the error code over - setError(rr->error(), rr->systemError()); - - rr = resultList.prev(); - } - - resultList.clear(); - return true; -} - -#ifdef HAVE_GETADDRINFO -KGetAddrinfoWorker::~KGetAddrinfoWorker() -{ -} - -bool KGetAddrinfoWorker::preprocess() -{ - // getaddrinfo(3) can always handle any kind of request that makes sense - if (!sanityCheck()) - return false; - - if (flags() & KResolver::NoResolve) - // oops, numeric resolution? - return run(); - - return true; -} - -bool KGetAddrinfoWorker::run() -{ - // make an AF_UNSPEC getaddrinfo(3) call - GetAddrInfoThread worker(m_encodedName, serviceName().latin1(), - AF_UNSPEC, flags(), &results); - - if (!worker.run()) - { - if (wantThis(AF_UNIX)) - { - if (addUnix() == KResolver::NoError) - setError(KResolver::NoError); - } - else - setError(worker.results.error(), worker.results.systemError()); - - return false; - } - - // The worker has finished working - // now copy over only what we may want - // keep track of any Unix-domain sockets - - bool seen_unix = false; - KResolverResults::Iterator it = results.begin(); - for ( ; it != results.end(); ) - { - if ((*it).family() == AF_UNIX) - seen_unix = true; - if (!wantThis((*it).family())) - it = results.remove(it); - else - ++it; - } - - if (!seen_unix) - addUnix(); - - finished(); - return true; -} - -bool KGetAddrinfoWorker::wantThis(int family) -{ - // tells us if the user wants a socket of this family - -#ifdef AF_INET6 - if (family == AF_INET6 && familyMask() & KResolver::IPv6Family) - return true; -#endif - if (family == AF_INET && familyMask() & KResolver::IPv4Family) - return true; - if (family == AF_UNIX && familyMask() & KResolver::UnixFamily) - return true; - - // it's not a family we know about... - if (familyMask() & KResolver::UnknownFamily) - return true; - - return false; -} - -#endif - -void KNetwork::Internal::initStandardWorkers() -{ - //KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KBlacklistWorker>); - KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KStandardWorker>); - -#ifdef HAVE_GETADDRINFO - KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KGetAddrinfoWorker>); -#endif -} diff --git a/kdecore/network/kresolverstandardworkers_p.h b/kdecore/network/kresolverstandardworkers_p.h deleted file mode 100644 index 2db460bef..000000000 --- a/kdecore/network/kresolverstandardworkers_p.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KRESOLVERSTANDARDWORKERS_P_H -#define KRESOLVERSTANDARDWORKERS_P_H - -#include <sys/types.h> -#include <netdb.h> - -#include <tqptrlist.h> -#include <tqcstring.h> -#include <tqstringlist.h> - -#include "kresolver.h" -#include "kresolverworkerbase.h" - -#include <config.h> - -namespace KNetwork { namespace Internal -{ - extern void initStandardWorkers() KDE_NO_EXPORT; - - /** - * @internal - * The blacklist worker. - */ - class KBlacklistWorker: public KNetwork::KResolverWorkerBase - { - public: - static TQStringList blacklist; - - static void loadBlacklist(); - static void init(); - static bool isBlacklisted(const TQString&); - - virtual bool preprocess(); - virtual bool run(); - virtual bool postprocess() { return true; } - }; - - /** @internal - * Standard worker. - */ - class KStandardWorker: public KNetwork::KResolverWorkerBase - { - protected: - mutable TQCString m_encodedName; - TQ_UINT16 port; - int scopeid; - TQPtrList<KNetwork::KResolverResults> resultList; - - public: - bool sanityCheck(); - - virtual bool preprocess(); - virtual bool run(); - virtual bool postprocess(); - - bool resolveScopeId(); - bool resolveService(); - bool resolveNumerically(); - - KNetwork::KResolver::ErrorCodes addUnix(); - }; - -#if defined(HAVE_GETADDRINFO) - /** @internal - * Worker class based on getaddrinfo(3). - * - * This class does not do post-processing. - */ - class KGetAddrinfoWorker: public KStandardWorker - { - public: - KGetAddrinfoWorker() - { } - - virtual ~KGetAddrinfoWorker(); - virtual bool preprocess(); - virtual bool run(); - virtual bool postprocess() { return true; } - - bool wantThis(int family); - }; -#endif // HAVE_GETADDRINFO - -} } // namespace KNetwork::Internal - - -#endif diff --git a/kdecore/network/kresolverworkerbase.cpp b/kdecore/network/kresolverworkerbase.cpp deleted file mode 100644 index ee6ee1011..000000000 --- a/kdecore/network/kresolverworkerbase.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2004 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -#include <assert.h> - -#include <tqcstring.h> -#include <tqstring.h> - -#include "kresolver.h" -#include "kresolver_p.h" -#include "kresolverworkerbase.h" - -using namespace KNetwork; -using namespace KNetwork::Internal; - -KResolverWorkerBase::KResolverWorkerBase() - : th(0L), input(0L), m_finished(0), m_reserved(0) -{ -} - -KResolverWorkerBase::~KResolverWorkerBase() -{ -} - -TQString KResolverWorkerBase::nodeName() const -{ - if (input) - return input->node; - return TQString::null; -} - -TQString KResolverWorkerBase::serviceName() const -{ - if (input) - return input->service; - return TQString::null; -} - -int KResolverWorkerBase::flags() const -{ - if (input) - return input->flags; - return 0; -} - -int KResolverWorkerBase::familyMask() const -{ - if (input) - return input->familyMask; - return 0; -} - -int KResolverWorkerBase::socketType() const -{ - if (input) - return input->socktype; - return 0; -} - -int KResolverWorkerBase::protocol() const -{ - if (input) - return input->protocol; - return 0; -} - -TQCString KResolverWorkerBase::protocolName() const -{ - TQCString res; - if (input) - res = input->protocolName; - return res; -} - -void KResolverWorkerBase::finished() -{ - m_finished = true; -} - -bool KResolverWorkerBase::postprocess() -{ - return true; // no post-processing is a always successful postprocessing -} - -bool KResolverWorkerBase::enqueue(KResolver* res) -{ - KResolverManager::manager()->enqueue(res, th->data); - return true; -} - -bool KResolverWorkerBase::enqueue(KResolverWorkerBase* worker) -{ - RequestData *myself = th->data; - RequestData *newrequest = new RequestData; - newrequest->obj = 0; - newrequest->input = input; // same input - newrequest->requestor = myself; - newrequest->nRequests = 0; - newrequest->worker = worker; - myself->nRequests++; - KResolverManager::manager()->dispatch(newrequest); - return true; -} - -bool KResolverWorkerBase::checkResolver() -{ - return th->checkResolver(); -} - -void KResolverWorkerBase::acquireResolver() -{ - th->acquireResolver(); -} - -void KResolverWorkerBase::releaseResolver() -{ - th->releaseResolver(); -} - -void KResolverWorkerFactoryBase::registerNewWorker(KResolverWorkerFactoryBase* factory) -{ - KResolverManager::manager()->registerNewWorker(factory); -} - diff --git a/kdecore/network/kresolverworkerbase.h b/kdecore/network/kresolverworkerbase.h deleted file mode 100644 index 4dee33239..000000000 --- a/kdecore/network/kresolverworkerbase.h +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2004 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KRESOLVERWORKERBASE_H -#define KRESOLVERWORKERBASE_H - -#include "kresolver.h" - -// forward declarations -class TQString; -template <class T> class TQValueList; - -namespace KNetwork { - - namespace Internal - { - class KResolverThread; - struct InputData; - } - -/** @internal - * This class is the base functionality for a resolver worker. That is, - * the class that does the actual work. - * - * In the future, this class might be exposed to allow plug-ins. So, try and - * make it binary compatible. - * - * Note that hostnames are still encoded in Unicode at this point. It's up to - * the worker class to decide which encoding to use. In the case of DNS, - * an ASCII Compatible Encoding (ACE) must be used. - * See @ref KResolver::domainToAscii. - * - * Also specially note that the run method in this class is called in a - * thread that is not the program's main thread. So do not do anything there - * that you shouldn't! - * - * @class KResolverWorkerBase kresolverworkerbase.h kresolverworkerbase.h - */ -class KResolverWorkerBase -{ -public: - - /** - * Helper class for locking the resolver subsystem. - * Similar to TQMutexLocker. - * - * @author LuÃs Pedro Coelho - * @since 3.4 - */ - class ResolverLocker - { - public: - /** - * Constructor. Acquires a lock. - */ - ResolverLocker(KResolverWorkerBase* parent) - : parent( parent ) - { - parent->acquireResolver(); - } - - /** - * Destructor. Releases the lock. - */ - ~ResolverLocker() - { - parent->releaseResolver(); - } - - /** - * Releases the lock and then reacquires it. - * It may be necessary to call this if the resolving function - * decides to retry. - */ - void openClose() - { - parent->releaseResolver(); - parent->acquireResolver(); - } - - private: - /// @internal - KResolverWorkerBase* parent; - }; -private: - // this will be like our d pointer - KNetwork::Internal::KResolverThread *th; - const KNetwork::Internal::InputData *input; - friend class KNetwork::Internal::KResolverThread; - friend class KNetwork::Internal::KResolverManager; - friend class KResolverWorkerBase::ResolverLocker; - - int m_finished : 1; - int m_reserved : 31; // reserved - -public: - /** - * Derived classes will put their resolved data in this list, or will - * leave it empty in case of error. - * - * Status and error codes should also be stored in this object (the - * @ref setError function does that). - */ - KResolverResults results; - -public: - // default constructor - KResolverWorkerBase(); - - // virtual destructor - virtual ~KResolverWorkerBase(); - - /** - * This is the hostname to be looked for - */ - TQString nodeName() const; - - /** - * And this is the service name - */ - TQString serviceName() const; - - /** - * gets the flags - */ - int flags() const; - - /** - * gets the family mask - */ - int familyMask() const; - - /** - * gets the socket type - */ - int socketType() const; - - /** - * gets the protocol number - */ - int protocol() const; - - /** - * gets the protocol name, if applicable - */ - TQCString protocolName() const; - - /** - * Call this function to indicate that processing - * has finished. This is useful in the preprocessing - * stage, to indicate that @ref run doesn't have to be - * called. - */ - void finished(); - -protected: - // like a QThread - /** - * This is the function that should be overriden in derived classes. - * - * Derived classes will do their blocking job in this function and return - * either success or failure to work (not the lookup). That is, whether the - * lookup result was a domain found or not, if we got our answer, we should - * indicate success. The error itself must be set with @ref setError. - * - * \b Important: this function gets called in a separate thread! - * - * @return true on success - */ - virtual bool run() = 0; - - /** - * This function gets called during pre processing for this class and you must - * override it. - * - * \b Important: this function gets called in the main event thread. And it MUST - * NOT block. - * - * This function can be used for an object to determine if it will be able - * to resolve the given data or not even before launching into a blocking - * operation. This function should return true if the object is capable of - * handling this kind of data; false otherwise. Note that the return value - * of 'true' means that the object's blocking answer will be considered authoritative. - * - * This function MUST NOT queue further requests. Leave that to @ref run. - * - * This function is pure virtual; you must override it. - * - * @return true on success - */ - virtual bool preprocess() = 0; - - /** - * This function gets called during post processing for this class. - * - * \b Important: this function gets called in the main event thread. And it MUST - * NOT block. - * - * @returns true on success - */ - virtual bool postprocess(); - - /** - * Sets the error - */ - inline void setError(int errorcode, int syserror = 0) - { results.setError(errorcode, syserror); } - - /** - * Enqueue the given resolver for post-processing. - * - * Use this function to make the manager call for another resolution. - * This is suitable for workers that do post-processing. - * - * The manager will make sure that any requests enqueued by this function - * are done before calling the postprocessing function, which you should - * override. - * - * \b Important: do use KResolver's own enqueueing functions (i.e., @ref KResolver::start). - * Instead, use this function. - * - * @returns true on successful queueing or false if a problem ocurred - */ - bool enqueue(KResolver* other); - - /** - * @overload - */ - bool enqueue(KResolverWorkerBase* worker); - - /** - * Checks the resolver subsystem status. - * @returns true if the resolver subsystem changed, false otherwise. - * If this function returns true, it might be necessary to - * restart the resolution altogether. - * @since 3.4 - */ - bool checkResolver(); - - /** - * This function has to be called from the resolver workers that require - * use of the DNS resolver code (i.e., res_* functions, generally in - * libresolv). It indicates that the function is starting a resolution - * and that the resolver backend shouldn't change asynchronously. - * - * If any pending res_init's are required, they will be performed before - * this function returns. - * - * @since 3.4 - */ - void acquireResolver(); - - /** - * This function is the counterpart for @ref acquireResolver: the worker - * thread indicates that it's done with the resolver. - * - * @since 3.4 - */ - void releaseResolver(); - -}; - -/** @internal - * This class provides functionality for creating and registering worker classes. - * - * @class KResolverWorkerFactoryBase kresolverworkerbase.h kresolverworkerbase.h - */ -class KResolverWorkerFactoryBase -{ -public: - virtual KResolverWorkerBase* create() const = 0; - - /** - * Wrapper call to register workers - * - * It is NOT thread-safe! - */ - static void registerNewWorker(KResolverWorkerFactoryBase* factory); -}; - -/** @internal - * This class provides functionality for creating and registering worker classes. - * - * @class KResolverWorkerFactory kresolverworkerbase.h kresolverworkerbase.h - */ -template<class Worker> -class KResolverWorkerFactory: public KResolverWorkerFactoryBase -{ -public: - virtual KResolverWorkerBase* create() const - { return new Worker; } -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kreverseresolver.cpp b/kdecore/network/kreverseresolver.cpp deleted file mode 100644 index 00ef7f81d..000000000 --- a/kdecore/network/kreverseresolver.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -// System includes -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <signal.h> - -// Qt -#include <tqevent.h> -#include <tqmutex.h> -#include <tqapplication.h> - -// Us -#include "kreverseresolver.h" -#include "kresolver_p.h" -#include "kresolverworkerbase.h" -#include "ksocketaddress.h" - -#ifndef HAVE_GETNAMEINFO -// FIXME KDE4: -// move to syssocket or adapt -# include "netsupp.h" -#endif - -using namespace KNetwork; -using namespace KNetwork::Internal; - -namespace -{ - class ReverseThread: public KResolverWorkerBase - { - public: - ReverseThread(const KSocketAddress& addr, int flags) - : m_addr(addr), m_flags(flags), m_parent(0L) - { } - - virtual ~ReverseThread() - { } - - virtual bool preprocess() - { return true; } - virtual bool run(); - virtual bool postprocess(); - - // input: - KSocketAddress m_addr; - int m_flags; - KReverseResolver *m_parent; - - // output: - TQString node; - TQString service; - bool success; - }; - - class KReverseResolverEvent: public TQEvent - { - public: - static const int myType = TQEvent::User + 63; // arbitrary value - TQString node; - TQString service; - bool success; - - KReverseResolverEvent(const TQString& _node, const TQString& _service, - bool _success) - : TQEvent((Type)myType), node(_node), - service(_service), success(_success) - { } - }; -} - -class KNetwork::KReverseResolverPrivate -{ -public: - TQString node; - TQString service; - KSocketAddress addr; - int flags; - - ReverseThread* worker; - bool success; - - inline KReverseResolverPrivate(const KSocketAddress& _addr) - : addr(_addr), worker(0L), success(false) - { } -}; - -KReverseResolver::KReverseResolver(const KSocketAddress& addr, int flags, - TQObject *parent, const char* name) - : TQObject(parent, name), d(new KReverseResolverPrivate(addr)) -{ - d->flags = flags; -} - -KReverseResolver::~KReverseResolver() -{ - if (d->worker) - d->worker->m_parent = 0L; -} - -bool KReverseResolver::isRunning() const -{ - return d->worker != 0L; -} - -bool KReverseResolver::success() const -{ - return !isRunning() && d->success; -} - -bool KReverseResolver::failure() const -{ - return !isRunning() && !d->success; -} - -TQString KReverseResolver::node() const -{ - return d->node; -} - -TQString KReverseResolver::service() const -{ - return d->service; -} - -const KSocketAddress& KReverseResolver::address() const -{ - return d->addr; -} - -bool KReverseResolver::start() -{ - if (d->worker != 0L) - return true; // already started - - d->worker = new ReverseThread(d->addr, d->flags); - d->worker->m_parent = this; - - RequestData *req = new RequestData; - req->obj = 0L; - req->input = 0L; - req->requestor = 0L; - req->worker = d->worker; - KResolverManager::manager()->dispatch(req); - return true; -} - -bool KReverseResolver::event(TQEvent *e) -{ - if (e->type() != KReverseResolverEvent::myType) - return TQObject::event(e); // call parent - - KReverseResolverEvent *re = static_cast<KReverseResolverEvent*>(e); - d->node = re->node; - d->service = re->service; - d->success = re->success; - - // don't delete d->worker! - // KResolverManager::doNotifying takes care of that, if it hasn't already - d->worker = 0L; - - // emit signal - emit finished(*this); - - return true; -} - -bool KReverseResolver::resolve(const KSocketAddress& addr, TQString& node, - TQString& serv, int flags) -{ - ReverseThread th(addr, flags); - if (th.run()) - { - node = th.node; - serv = th.service; - return true; - } - return false; -} - -bool KReverseResolver::resolve(const struct sockaddr* sa, TQ_UINT16 salen, - TQString& node, TQString& serv, int flags) -{ - return resolve(KSocketAddress(sa, salen), node, serv, flags); -} - -bool ReverseThread::run() -{ - int err; - char h[NI_MAXHOST], s[NI_MAXSERV]; - int niflags = 0; - - h[0] = s[0] = '\0'; - - if (m_flags & KReverseResolver::NumericHost) - niflags |= NI_NUMERICHOST; - if (m_flags & KReverseResolver::NumericService) - niflags |= NI_NUMERICSERV; - if (m_flags & KReverseResolver::NodeNameOnly) - niflags |= NI_NOFQDN; - if (m_flags & KReverseResolver::Datagram) - niflags |= NI_DGRAM; - if (m_flags & KReverseResolver::ResolutionRequired) - niflags |= NI_NAMEREQD; - - { -#ifdef NEED_MUTEX - TQMutexLocker locker(&::getXXbyYYmutex); -#endif - err = ::getnameinfo(m_addr, m_addr.length(), - h, sizeof(h) - 1, s, sizeof(s) - 1, niflags); - } - - if (err == 0) - { - node = KResolver::domainToUnicode(TQString::tqfromLatin1(h)); - service = TQString::tqfromLatin1(s); - success = true; - } - else - { - node = service = TQString::null; - success = false; - } - - return success; -} - -bool ReverseThread::postprocess() -{ - // post an event - if (m_parent) - TQApplication::postEvent(m_parent, - new KReverseResolverEvent(node, service, success)); - return true; -} - -#include "kreverseresolver.moc" diff --git a/kdecore/network/kreverseresolver.h b/kdecore/network/kreverseresolver.h deleted file mode 100644 index 1f26f4a2a..000000000 --- a/kdecore/network/kreverseresolver.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KREVERSERESOLVER_H -#define KREVERSERESOLVER_H - -////////////////// -// Needed includes -#include <tqobject.h> -#include <tqstring.h> - -#include "ksocketaddress.h" - -namespace KNetwork { - -class KReverseResolverPrivate; -/** @class KReverseResolver kreverseresolver.h kreverseresolver.h - * @brief Run a reverse-resolution on a socket address. - * - * This class is provided as a counterpart to KResolver in such a way - * as it produces a reverse resolution: it resolves a socket address - * from its binary representations into a textual representation. - * - * Most users will use the static functions @ref resolve, which work - * both synchronously (blocking) and asynchronously (non-blocking). - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KReverseResolver: public TQObject -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Flags for the reverse resolution. - * - * These flags are used by the reverse resolution functions for - * setting resolution parameters. The possible values are: - * @li NumericHost: don't try to resolve the host address to a text form. - * Instead, convert the address to its numeric textual representation. - * @li NumericService: the same as NumericHost, but for the service name - * @li NodeNameOnly: returns the node name only (i.e., not the Fully - * Qualified Domain Name) - * @li Datagram: in case of ambiguity in the service name, prefer the - * name associated with the datagram protocol - * @li NumericScope: for those addresses which have the concept of scope, - * resolve using the numeric value instead of the proper scope name. - * @li ResolutionRequired: normally, when resolving, if the name resolution - * fails, the process normally converts the numeric address into its - * presentation forms. This flag causes the function to return - * with error instead. - */ - enum Flags - { - NumericHost = 0x01, - NumericService = 0x02, - NodeNameOnly = 0x04, - Datagram = 0x08, - NumericScope = 0x10, - ResolutionRequired = 0x20 - }; - - /** - * Constructs this object to resolve the given socket address. - * - * @param addr the address to resolve - * @param flags the flags to use, see @ref Flags - */ - KReverseResolver(const KSocketAddress& addr, int flags = 0, - TQObject * = 0L, const char * = 0L); - - /** - * Destructor. - */ - virtual ~KReverseResolver(); - - /** - * This function returns 'true' if the processing is still running. - */ - bool isRunning() const; - - /** - * This function returns true if the processing has finished with - * success, false if it's still running or failed. - */ - bool success() const; - - /** - * This function returns true if the processing has finished with - * failure, false if it's still running or succeeded. - */ - bool failure() const; - - /** - * Returns the resolved node name, if the resolution has finished - * successfully, or TQString::null otherwise. - */ - TQString node() const; - - /** - * Returns the resolved service name, if the resolution has finished - * successfully, or TQString::null otherwise. - */ - TQString service() const; - - /** - * Returns the socket address which was subject to resolution. - */ - const KSocketAddress& address() const; - - /** - * Starts the resolution. This function returns 'true' - * if the resolution has started successfully. - */ - bool start(); - - /** - * Overrides event handling - */ - virtual bool event(TQEvent* ); - -signals: - /** - * This signal is emitted when the resolution has finished. - * - * @param obj this class, which contains the results - */ - void finished(const KReverseResolver& obj); - -public: - /** - * Resolves a socket address to its textual representation - * - * FIXME!! How can we do this in a non-blocking manner!? - * - * This function is used to resolve a socket address from its - * binary representation to a textual form, even if numeric only. - * - * @param addr the socket address to be resolved - * @param node the TQString where we will store the resolved node - * @param serv the TQString where we will store the resolved service - * @param flags flags to be used for this resolution. - * @return true if the resolution succeeded, false if not - * @see ReverseFlags for the possible values for @p flags - */ - static bool resolve(const KSocketAddress& addr, TQString& node, - TQString& serv, int flags = 0); - - /** - * Resolves a socket address to its textual representation - * - * FIXME!! How can we do this in a non-blocking manner!? - * - * This function behaves just like the above one, except it takes - * a sockaddr structure and its size as parameters. - * - * @param sa the sockaddr structure containing the address to be resolved - * @param salen the length of the sockaddr structure - * @param node the TQString where we will store the resolved node - * @param serv the TQString where we will store the resolved service - * @param flags flags to be used for this resolution. - * @return true if the resolution succeeded, false if not - * @see ReverseFlags for the possible values for @p flags - */ - static bool resolve(const struct sockaddr* sa, TQ_UINT16 salen, - TQString& node, TQString& serv, int flags = 0); - -private: - KReverseResolverPrivate* d; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/kserversocket.cpp b/kdecore/network/kserversocket.cpp deleted file mode 100644 index bd63d6306..000000000 --- a/kdecore/network/kserversocket.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <tqsocketnotifier.h> -#include <tqmutex.h> - -#include "ksocketaddress.h" -#include "kresolver.h" -#include "ksocketbase.h" -#include "ksocketdevice.h" -#include "kstreamsocket.h" -#include "kbufferedsocket.h" -#include "kserversocket.h" - -using namespace KNetwork; - -class KNetwork::KServerSocketPrivate -{ -public: - KResolver resolver; - KResolverResults resolverResults; - - enum { None, LookupDone, Bound, Listening } state; - int backlog; - int timeout; - - bool bindWhenFound : 1, listenWhenBound : 1, useKBufferedSocket : 1; - - KServerSocketPrivate() - : state(None), timeout(0), bindWhenFound(false), listenWhenBound(false), - useKBufferedSocket(true) - { - resolver.setFlags(KResolver::Passive); - resolver.setFamily(KResolver::KnownFamily); - } -}; - -KServerSocket::KServerSocket(TQObject* parent, const char *name) - : TQObject(parent, name), d(new KServerSocketPrivate) -{ - TQObject::connect(&d->resolver, TQT_SIGNAL(finished(KResolverResults)), - this, TQT_SLOT(lookupFinishedSlot())); -} - -KServerSocket::KServerSocket(const TQString& service, TQObject* parent, const char *name) - : TQObject(parent, name), d(new KServerSocketPrivate) -{ - TQObject::connect(&d->resolver, TQT_SIGNAL(finished(KResolverResults)), - this, TQT_SLOT(lookupFinishedSlot())); - d->resolver.setServiceName(service); -} - -KServerSocket::KServerSocket(const TQString& node, const TQString& service, - TQObject* parent, const char* name) - : TQObject(parent, name), d(new KServerSocketPrivate) -{ - TQObject::connect(&d->resolver, TQT_SIGNAL(finished(KResolverResults)), - this, TQT_SLOT(lookupFinishedSlot())); - setAddress(node, service); -} - -KServerSocket::~KServerSocket() -{ - close(); - delete d; -} - -bool KServerSocket::setSocketOptions(int opts) -{ - TQMutexLocker locker(mutex()); - KSocketBase::setSocketOptions(opts); // call parent - bool result = socketDevice()->setSocketOptions(opts); // and set the implementation - copyError(); - return result; -} - -KResolver& KServerSocket::resolver() const -{ - return d->resolver; -} - -const KResolverResults& KServerSocket::resolverResults() const -{ - return d->resolverResults; -} - -void KServerSocket::setResolutionEnabled(bool enable) -{ - if (enable) - d->resolver.setFlags(d->resolver.flags() & ~KResolver::NoResolve); - else - d->resolver.setFlags(d->resolver.flags() | KResolver::NoResolve); -} - -void KServerSocket::setFamily(int families) -{ - d->resolver.setFamily(families); -} - -void KServerSocket::setAddress(const TQString& service) -{ - d->resolver.setNodeName(TQString::null); - d->resolver.setServiceName(service); - d->resolverResults.empty(); - if (d->state <= KServerSocketPrivate::LookupDone) - d->state = KServerSocketPrivate::None; -} - -void KServerSocket::setAddress(const TQString& node, const TQString& service) -{ - d->resolver.setNodeName(node); - d->resolver.setServiceName(service); - d->resolverResults.empty(); - if (d->state <= KServerSocketPrivate::LookupDone) - d->state = KServerSocketPrivate::None; -} - -void KServerSocket::setTimeout(int msec) -{ - d->timeout = msec; -} - -bool KServerSocket::lookup() -{ - setError(NoError); - if (d->resolver.isRunning() && !blocking()) - return true; // already doing lookup - - if (d->state >= KServerSocketPrivate::LookupDone) - return true; // results are already available - - // make sure we have at least one parameter for lookup - if (d->resolver.serviceName().isNull() && - !d->resolver.nodeName().isNull()) - d->resolver.setServiceName(TQString::tqfromLatin1("")); - - // don't restart the lookups if they had succeeded and - // the input values weren't changed - - // reset results - d->resolverResults = KResolverResults(); - - if (d->resolver.status() <= 0) - // if it's already running, there's no harm in calling again - d->resolver.start(); // signal may emit - - if (blocking()) - { - // we're in blocking mode operation - // wait for the results - - d->resolver.wait(); // signal may be emitted again - // lookupFinishedSlot has been called - } - - return true; -} - -bool KServerSocket::bind(const KResolverEntry& address) -{ - if (socketDevice()->bind(address)) - { - setError(NoError); - - d->state = KServerSocketPrivate::Bound; - emit bound(address); - return true; - } - copyError(); - return false; -} - -bool KServerSocket::bind(const TQString& node, const TQString& service) -{ - setAddress(node, service); - return bind(); -} - -bool KServerSocket::bind(const TQString& service) -{ - setAddress(service); - return bind(); -} - -bool KServerSocket::bind() -{ - if (d->state >= KServerSocketPrivate::Bound) - return true; - - if (d->state < KServerSocketPrivate::LookupDone) - { - if (!blocking()) - { - d->bindWhenFound = true; - bool ok = lookup(); // will call doBind - if (d->state >= KServerSocketPrivate::Bound) - d->bindWhenFound = false; - return ok; - } - - // not blocking - if (!lookup()) - return false; - } - - return doBind(); -} - -bool KServerSocket::listen(int backlog) -{ - // WARNING - // this function has to be reentrant - // due to the mechanisms used for binding, this function might - // end up calling itself - - if (d->state == KServerSocketPrivate::Listening) - return true; // already listening - - d->backlog = backlog; - - if (d->state < KServerSocketPrivate::Bound) - { - // we must bind - // note that we can end up calling ourselves here - d->listenWhenBound = true; - if (!bind()) - { - d->listenWhenBound = false; - return false; - } - - if (d->state < KServerSocketPrivate::Bound) - // asynchronous lookup in progress... - // we can't be blocking here anyways - return true; - - d->listenWhenBound = false; - } - - if (d->state < KServerSocketPrivate::Listening) - return doListen(); - - return true; -} - -void KServerSocket::close() -{ - socketDevice()->close(); - if (d->resolver.isRunning()) - d->resolver.cancel(false); - d->state = KServerSocketPrivate::None; - emit closed(); -} - -void KServerSocket::setAcceptBuffered(bool enable) -{ - d->useKBufferedSocket = enable; -} - -KActiveSocketBase* KServerSocket::accept() -{ - if (d->state < KServerSocketPrivate::Listening) - { - if (!blocking()) - { - listen(); - setError(WouldBlock); - return NULL; - } - else if (!listen()) - // error happened during listen - return false; - } - - // check to see if we're doing a timeout - if (blocking() && d->timeout > 0) - { - bool timedout; - if (!socketDevice()->poll(d->timeout, &timedout)) - { - copyError(); - return NULL; - } - - if (timedout) - return 0L; - } - - // we're listening here - KSocketDevice* accepted = socketDevice()->accept(); - if (!accepted) - { - // error happened during accept - copyError(); - return NULL; - } - - KStreamSocket* streamsocket; - if (d->useKBufferedSocket) - streamsocket = new KBufferedSocket(); - else - streamsocket = new KStreamSocket(); - streamsocket->setSocketDevice(accepted); - - // FIXME! - // when KStreamSocket can find out the state of the socket passed through - // setSocketDevice, this will probably be unnecessary: - streamsocket->setState(KStreamSocket::Connected); - streamsocket->setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); - - return streamsocket; -} - -KSocketAddress KServerSocket::localAddress() const -{ - return socketDevice()->localAddress(); -} - -KSocketAddress KServerSocket::externalAddress() const -{ - return socketDevice()->externalAddress(); -} - -void KServerSocket::lookupFinishedSlot() -{ - if (d->resolver.isRunning() || d->state > KServerSocketPrivate::LookupDone) - return; - - if (d->resolver.status() < 0) - { - setError(LookupFailure); - emit gotError(LookupFailure); - d->bindWhenFound = d->listenWhenBound = false; - d->state = KServerSocketPrivate::None; - return; - } - - // lookup succeeded - d->resolverResults = d->resolver.results(); - d->state = KServerSocketPrivate::LookupDone; - emit hostFound(); - - if (d->bindWhenFound) - doBind(); -} - -void KServerSocket::copyError() -{ - setError(socketDevice()->error()); -} - -bool KServerSocket::doBind() -{ - d->bindWhenFound = false; - // loop through the results and bind to the first that works - - KResolverResults::ConstIterator it = d->resolverResults.begin(); - for ( ; it != d->resolverResults.end(); ++it) - if (bind(*it)) - { - if (d->listenWhenBound) - return doListen(); - return true; - } - else - socketDevice()->close(); // didn't work, try again - - // failed to bind - emit gotError(error()); - return false; -} - -bool KServerSocket::doListen() -{ - if (!socketDevice()->listen(d->backlog)) - { - copyError(); - emit gotError(error()); - return false; // failed to listen - } - - // set up ready accept signal - TQObject::connect(socketDevice()->readNotifier(), TQT_SIGNAL(activated(int)), - this, TQT_SIGNAL(readyAccept())); - d->state = KServerSocketPrivate::Listening; - return true; -} - - -#include "kserversocket.moc" diff --git a/kdecore/network/kserversocket.h b/kdecore/network/kserversocket.h deleted file mode 100644 index a07ed54a1..000000000 --- a/kdecore/network/kserversocket.h +++ /dev/null @@ -1,436 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago@kde.org> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KSERVERSOCKET_H -#define KSERVERSOCKET_H - -#include <tqobject.h> -#include "ksocketbase.h" - -namespace KNetwork { - -class KSocketDevice; -class KStreamSocket; -class KResolver; -class KResolverResults; - -class KServerSocketPrivate; -/** - * @class KServerSocket kserversocket.h kserversocket.h - * @brief A server socket for accepting connections. - * - * This class provides functionality for creating a socket to - * listen for incoming connections and subsequently accept them. - * - * To use this class, you must first set the parameters for the listening - * socket's address, then place it in listening mode. - * - * A typical example would look like: - * \code - * TQString service = "http"; - * KServerSocket *ss = new KServerSocket(service); - * connect(ss, TQT_SIGNAL(readyAccept()), this, TQT_SLOT(slotReadyAccept())); - * connect(ss, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotSocketError(int))); - * ss->listen(); - * \endcode - * - * In this case, this class will place the socket into listening mode on the - * service pointed to by @p service and will emit the @ref readyAccept signal - * when a connection is ready for accepting. The called slot is responsible for - * calling @ref accept. - * - * The location of the services file (where @p service is looked up) - * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is - * usually set to /etc/services. - * See RFC 1700 for more information on services. - * You can specify @p service as a port number directly, rather than as a service - * name. This is discouraged as it prevents the end user from easily modifying - * the port number. - * - * For another example of usage, this below code attempts to make a connection on any port within a range: - * \code - * KServerSocket *ss = new KServerSocket(); - * ss->setFamily(KResolver::InetFamily); - * bool found = false; - * for( unsigned int port = firstport; port <= lastport; ++port) { - * ss->setAddress( TQString::number( port ) ); - * bool success = ss->listen(); - * if( found = ( success && ss->error() == - * KSocketBase::NoError ) ) - * break; - * ss->close(); - * } - * if( !found ) { - * // Couldn't connect to any port. - * } else { - * connect(ss, TQT_SIGNAL(readyAccept()), this, TQT_SLOT(slotReadyAccept())); - * connect(ss, TQT_SIGNAL(gotError(int)), this, TQT_SLOT(slotSocketError(int))); - * ss->listen(); - * } - * \endcode - * - * The called slot slotReadyAccept() is responsible for calling - * @ref accept. - * - * It is important to note that @ref accept can return either an - * object of type KNetwork::KStreamSocket or - * KNetwork::KBufferedSocket (default). If you want to accept a - * non-buffered socket, you must first call setAcceptBuffered. - * - * @warning If you use KServerSocket in an auxiliary (non-GUI) thread, - * you need to accept only KNetwork::KStreamSocket objects. - * - * @see KNetwork::KStreamSocket, KNetwork::KBufferedSocket - * @author Thiago Macieira <thiago@kde.org> - */ -class KDECORE_EXPORT KServerSocket: public TQObject, public KPassiveSocketBase -{ - Q_OBJECT - TQ_OBJECT -public: - /** - * Default constructor. - * - * If the binding address isn't changed by setAddress, this socket will - * bind to all interfaces on this node and the port will be selected by the - * operating system. - * - * @param parent the parent TQObject object - * @param name the name of this object - */ - KServerSocket(TQObject* parent = 0L, const char *name = 0L); - - /** - * Construct this object specifying the service to listen on. - * - * If the binding address isn't changed by setAddress, this socket will - * bind to all interfaces and will listen on the port specified by - * @p service. This is either a service name (e.g. 'www') or a port - * number (e.g. '80'). - * - * The location of the services file (where @p service is looked up) - * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is - * usually set to /etc/services. - * See RFC 1700 for more information on services. - * - * @param service the service name to listen on - * @param parent the parent TQObject object - * @param name the name of this object - */ - KServerSocket(const TQString& service, TQObject* parent = 0L, const char *name = 0L); - - /** - * Construct this object specifying the node and service names to listen on. - * - * If the binding address isn't changed by setAddress, this socket will - * bind to the interface specified by @p node and the port specified by - * @p service. This is either a service name (e.g. 'www') or a port - * number (e.g. '80'). - * - * The location of the services file (where @p service is looked up) - * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is - * usually set to /etc/services. - * See RFC 1700 for more information on services. - * - * @param node the node to bind to - * @param service the service port to listen on - * @param parent the parent TQObject object - * @param name the name of this object - */ - KServerSocket(const TQString& node, const TQString& service, - TQObject* parent = 0L, const char *name = 0L); - - /** - * Destructor. This will close the socket, if open. - * - * Note, however, that accepted sockets do not get closed when this - * object closes. - */ - ~KServerSocket(); - -protected: - /** - * Sets the socket options. Reimplemented from KSocketBase. - */ - virtual bool setSocketOptions(int opts); - -public: - /** - * Returns the internal KResolver object used for - * looking up the host name and service. - * - * This can be used to set extra options to the - * lookup process other than the default values, as well - * as obtaining the error codes in case of lookup failure. - */ - KResolver& resolver() const; - - /** - * Returns the internal list of resolved results for the binding address. - */ - const KResolverResults& resolverResults() const; - - /** - * Enables or disables name resolution. If this flag is set to true, - * the @ref bind operation will trigger name lookup - * operations (i.e., converting a hostname into its binary form). - * If the flag is set to false, those operations will instead - * try to convert a string representation of an address without - * attempting name resolution. - * - * This is useful, for instance, when IP addresses are in - * their string representation (such as "1.2.3.4") or come - * from other sources like @ref KSocketAddress. - * - * @param enable whether to enable - */ - void setResolutionEnabled(bool enable); - - /** - * Sets the allowed families for the resolutions. - * - * @param families the families that we want/accept - * @see KResolver::SocketFamilies for possible values - */ - void setFamily(int families); - - /** - * Sets the address on which we will listen. The port to listen on is given by - * @p service, and we will bind to all interfaces. To let the operating system choose a - * port, set the service to "0". @p service can either be a service name - * (e.g. 'www') or a port number (e.g. '80'). - * - * The location of the services file (where @p service is looked up) - * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is - * usually set to /etc/services. - * See RFC 1700 for more information on services. - * - * @param service the service name to listen on - */ - void setAddress(const TQString& service); - - /** - * @overload - * Sets the address on which we will listen. This will cause the socket to listen - * only on the interface given by @p node and on the port given by @p service. - * @p service can either be a service name (e.g. 'www') or a port number - * (e.g. '80'). - * - * The location of the services file (where @p service is looked up) - * is defined by _PATH_SERVICES in /usr/include/netdb.h. This is - * usually set to /etc/services. - * See RFC 1700 for more information on services. - * - * @param node the node to bind to - * @param service the service port to listen on - */ - void setAddress(const TQString& node, const TQString& service); - - /** - * Sets the timeout for accepting. When you call @ref accept, - * it will wait at most @p msecs milliseconds or return with an error - * (returning a NULL object). - * - * @param msecs the time in milliseconds to wait, 0 to wait forever - */ - void setTimeout(int msecs); - - /** - * Starts the lookup for peer and local hostnames as - * well as their services. - * - * If the blocking mode for this object is on, this function will - * wait for the lookup results to be available (by calling the - * @ref KResolver::wait method on the resolver objects). - * - * When the lookup is done, the signal @ref hostFound will be - * emitted (only once, even if we're doing a double lookup). - * If the lookup failed (for any of the two lookups) the - * @ref gotError signal will be emitted with the appropriate - * error condition (see @ref KSocketBase::SocketError). - * - * This function returns true on success and false on error. Note that - * this is not the lookup result! - */ - virtual bool lookup(); - - /** - * Binds this socket to the given nodename and service, - * or use the default ones if none are given. - * - * Upon successful binding, the @ref bound signal will be - * emitted. If an error is found, the @ref gotError - * signal will be emitted. - * - * This function returns true on success. - * - * @param node the nodename - * @param service the service - */ - virtual bool bind(const TQString& node, const TQString& service); - - /** - * Binds the socket to the given service name. - * @overload - * - * @param service the service - */ - virtual bool bind(const TQString& service); - - /** - * Binds the socket to the addresses previously set with @ref setAddress. - * @overload - * - */ - virtual bool bind(); - - /** - * Connect this socket to this specific address. Reimplemented from KSocketBase. - * - * Unlike @ref bind(const TQString&, const TQString&) above, this function - * really does bind the socket. No lookup is performed. The @ref bound signal - * will be emitted. - */ - virtual bool bind(const KResolverEntry& address); - - /** - * Puts this socket into listening mode. Reimplemented from @ref KPassiveSocketBase. - * - * Placing a socket into listening mode means it will be able to receive incoming - * connections through the @ref accept method. - * - * If you do not call this method but call @ref accept directly, the socket will - * be placed into listening mode automatically. - * - * @param backlog the number of connection the system is to - * queue without @ref accept being called - * @returns true if the socket is now in listening mode. - */ - virtual bool listen(int backlog = 5); // 5 is arbitrary - - /** - * Closes this socket. - */ - virtual void close(); - - /** - * Toggles whether the accepted socket will be buffered or not. - * That is, the @ref accept function will always return a KStreamSocket - * object or descended from it. If buffering is enabled, the class - * to be returned will be KBufferedSocket. - * - * By default, this flag is set to true. - * - * @param enable whether to set the accepted socket to - * buffered mode - */ - void setAcceptBuffered(bool enable); - - /** - * Accepts one incoming connection and return the associated, open - * socket. - * - * If this function cannot accept a new connection, it will return NULL. - * The specific object class returned by this function may vary according - * to the implementation: derived classes may return specialised objects - * descended from KStreamSocket. - * - * @note This function should return a KStreamSocket object, but compiler - * deficiencies prevent such an adjustment. Therefore, we return - * the base class for active sockets, but it is guaranteed - * that the object will be a KStreamSocket or derived from it. - * - * @sa KBufferedSocket - * @sa setAcceptBuffered - */ - virtual KActiveSocketBase* accept(); - - /** - * Returns this socket's local address. - */ - virtual KSocketAddress localAddress() const; - - /** - * Returns this socket's externally-visible address if know. - */ - virtual KSocketAddress externalAddress() const; - -private slots: - void lookupFinishedSlot(); - -signals: - /** - * This signal is emitted when this object finds an error. - * The @p code parameter contains the error code that can - * also be found by calling @ref error. - */ - void gotError(int code); - - /** - * This signal is emitted when the lookup is successfully completed. - */ - void hostFound(); - - /** - * This signal is emitted when the socket successfully binds - * to an address. - * - * @param local the local address we bound to - */ - void bound(const KResolverEntry& local); - - /** - * This signal is emitted when the socket completes the - * closing/shut down process. - */ - void closed(); - - /** - * This signal is emitted whenever the socket is ready for - * accepting -- i.e., there is at least one connection waiting to - * be accepted. - */ - void readyAccept(); - -protected: - /** - * Convenience function to set this object's error code to match - * that of the socket device. - */ - void copyError(); - -private: - bool doBind(); - bool doListen(); - -private: - KServerSocket(const KServerSocket&); - KServerSocket& operator=(const KServerSocket&); - - KServerSocketPrivate *d; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/ksocketaddress.cpp b/kdecore/network/ksocketaddress.cpp deleted file mode 100644 index feaabfab5..000000000 --- a/kdecore/network/ksocketaddress.cpp +++ /dev/null @@ -1,957 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "config.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include <tqfile.h> -#include <tqobject.h> - -#include "klocale.h" -#include "ksocketaddress.h" - -#include "netsupp.h" - -using namespace KNetwork; - -#if 0 -class KIpAddress_localhostV4 : public KIpAddress -{ -public: - KIpAddress_localhostV4() - { - *m_data = htonl(0x7f000001); - m_version = 4; - } -}; - -class KIpAddress_localhostV6 : public KIpAddress -{ -public: - KIpAddress_localhostV6() - : KIpAddress(0L, 6) - { - m_data[3] = htonl(1); - } -}; -#endif - -static const char localhostV4_data[] = { 127, 0, 0, 1 }; -static const char localhostV6_data[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1 }; - -const KIpAddress KIpAddress::localhostV4(&localhostV4_data, 4); -const KIpAddress KIpAddress::localhostV6(&localhostV6_data, 6); -const KIpAddress KIpAddress::anyhostV4(0L, 4); -const KIpAddress KIpAddress::anyhostV6(0L, 6); - -// helper function to test if an IPv6 v4-mapped address is equal to its IPv4 counterpart -static bool check_v4mapped(const TQ_UINT32* v6addr, TQ_UINT32 v4addr) -{ - // check that the v6 is a v4-mapped address - if (!(v6addr[0] == 0 && v6addr[1] == 0 && v6addr[2] == htonl(0x0000ffff))) - return false; // not a v4-mapped address - - return v6addr[3] == v4addr; -} - -// copy operator -KIpAddress& KIpAddress::operator =(const KIpAddress& other) -{ - m_version = other.m_version; - if (m_version == 4 || m_version == 6) - memcpy(m_data, other.m_data, sizeof(m_data)); - return *this; -} - -// comparison -bool KIpAddress::compare(const KIpAddress& other, bool checkMapped) const -{ - if (m_version == other.m_version) - switch (m_version) - { - case 0: - // both objects are empty - return true; - - case 4: - // IPv4 address - return *m_data == *other.m_data; - - case 6: - // IPv6 address - // they are 128-bit long, that is, 16 bytes - return memcmp(m_data, other.m_data, 16) == 0; - } - - if (checkMapped) - { - // check the possibility of a v4-mapped address being compared to an IPv4 one - if (m_version == 6 && other.m_version == 4 && check_v4mapped(m_data, *other.m_data)) - return true; - - if (other.m_version == 6 && m_version == 4 && check_v4mapped(other.m_data, *m_data)) - return true; - } - - return false; -} - -// sets the address to the given address -bool KIpAddress::setAddress(const TQString& address) -{ - m_version = 0; - - // try to guess the address version - if (address.find(':') != -1) - { -#ifdef AF_INET6 - // guessing IPv6 - - TQ_UINT32 buf[4]; - if (inet_pton(AF_INET6, address.latin1(), buf)) - { - memcpy(m_data, buf, sizeof(m_data)); - m_version = 6; - return true; - } -#endif - - return false; - } - else - { - TQ_UINT32 buf; - if (inet_pton(AF_INET, address.latin1(), &buf)) - { - *m_data = buf; - m_version = 4; - return true; - } - - return false; - } - - return false; // can never happen! -} - -bool KIpAddress::setAddress(const char* address) -{ - return setAddress(TQString::tqfromLatin1(address)); -} - -// set from binary data -bool KIpAddress::setAddress(const void* raw, int version) -{ - // this always succeeds - // except if version is invalid - if (version != 4 && version != 6) - return false; - - m_version = version; - if (raw != 0L) - memcpy(m_data, raw, version == 4 ? 4 : 16); - else - memset(m_data, 0, 16); - - return true; -} - -// presentation form -TQString KIpAddress::toString() const -{ - char buf[sizeof "1111:2222:3333:4444:5555:6666:255.255.255.255" + 2]; - buf[0] = '\0'; - switch (m_version) - { - case 4: - inet_ntop(AF_INET, m_data, buf, sizeof(buf) - 1); - return TQString::tqfromLatin1(buf); - - case 6: -#ifdef AF_INET6 - inet_ntop(AF_INET6, m_data, buf, sizeof(buf) - 1); -#endif - return TQString::tqfromLatin1(buf); - } - - return TQString::null; -} - -TQ_UINT32 KIpAddress::hostIPv4Addr(bool convertMapped) const -{ - TQ_UINT32 addr = IPv4Addr(convertMapped); - return ntohl(addr); -} - -/* - * An IPv6 socket address - * This is taken from RFC 2553. - */ -struct our_sockaddr_in6 -{ -# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - TQ_UINT8 sin6_len; - TQ_UINT8 sin6_family; -# else //!HAVE_STRUCT_SOCKADDR_SA_LEN - TQ_UINT16 sin6_family; -# endif - TQ_UINT16 sin6_port; /* RFC says in_port_t */ - TQ_UINT32 sin6_flowinfo; - TQ_UINT8 sin6_addr[16]; // 24 bytes up to here - TQ_UINT32 sin6_scope_id; // 28 bytes total -}; - -// useful definitions -#define MIN_SOCKADDR_LEN sizeof(TQ_UINT16) -#define SOCKADDR_IN_LEN sizeof(sockaddr_in) -#define MIN_SOCKADDR_IN6_LEN ((unsigned long) &(((our_sockaddr_in6*)0)->sin6_scope_id)) -#define SOCKADDR_IN6_LEN sizeof(our_sockaddr_in6) -#define MIN_SOCKADDR_UN_LEN (sizeof(TQ_UINT16) + sizeof(char)) - - -class KNetwork::KSocketAddressData -{ -public: - /* - * Note: maybe this should be virtual - * But since the data is shared via the d pointer, it doesn't really matter - * what one class sees, so will the other - */ - class QMixSocketAddressRef : public KInetSocketAddress, public KUnixSocketAddress - { - public: - QMixSocketAddressRef(KSocketAddressData* d) - : KInetSocketAddress(d), KUnixSocketAddress(d) - { - } - }; - QMixSocketAddressRef ref; - - union - { - struct sockaddr *generic; - struct sockaddr_in *in; - struct our_sockaddr_in6 *in6; - struct sockaddr_un *un; - } addr; - TQ_UINT16 curlen, reallen; - - KSocketAddressData() - : ref(this) - { - addr.generic = 0L; - curlen = 0; - tqinvalidate(); - } - - ~KSocketAddressData() - { - if (addr.generic != 0L) - free(addr.generic); - } - - inline bool invalid() const - { return reallen == 0; } - - inline void tqinvalidate() - { reallen = 0; } - - void dup(const sockaddr* sa, TQ_UINT16 len, bool clear = true); - - void makeipv4() - { - short oldport = 0; - if (!invalid()) - switch (addr.generic->sa_family) - { - case AF_INET: - return; // nothing to do here -#ifdef AF_INET6 - case AF_INET6: - oldport = addr.in6->sin6_port; - break; -#endif - } - - // create new space - dup(0L, SOCKADDR_IN_LEN); - - addr.in->sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - addr.in->sin_len = SOCKADDR_IN_LEN; -#endif - addr.in->sin_port = oldport; - } - - void makeipv6() - { - short oldport = 0; - if (!invalid()) - switch (addr.generic->sa_family) - { - case AF_INET: - oldport = addr.in->sin_port; - break; - -#ifdef AF_INET6 - case AF_INET6: - return; // nothing to do here -#endif - } - - // make room - dup(0L, SOCKADDR_IN6_LEN); -#ifdef AF_INET6 - addr.in6->sin6_family = AF_INET6; -#endif -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - addr.in6->sin6_len = SOCKADDR_IN6_LEN; -#endif - addr.in6->sin6_port = oldport; - // sin6_scope_id and sin6_flowid are zero - } - -}; - -// create duplicates of -void KSocketAddressData::dup(const sockaddr* sa, TQ_UINT16 len, bool clear) -{ - if (len < MIN_SOCKADDR_LEN) - { - // certainly invalid - tqinvalidate(); - return; - } - - if (sa && ((sa->sa_family == AF_INET && len < SOCKADDR_IN_LEN) || -#ifdef AF_INET6 - (sa->sa_family == AF_INET6 && len < MIN_SOCKADDR_IN6_LEN) || -#endif - (sa->sa_family == AF_UNIX && len < MIN_SOCKADDR_UN_LEN))) - { - // also invalid - tqinvalidate(); - return; - } - - // good - reallen = len; - if (len > curlen) - { - if (len < 32) - curlen = 32; // big enough for sockaddr_in and sockaddr_in6 - else - curlen = len; - addr.generic = (sockaddr*)realloc(addr.generic, curlen); - } - - if (sa != 0L) - { - memcpy(addr.generic, sa, len); // copy - - // now, normalise the data - if (addr.generic->sa_family == AF_INET) - reallen = SOCKADDR_IN_LEN; // no need to be larger -#ifdef AF_INET6 - else if (addr.generic->sa_family == AF_INET6) - { - // set the extra field (sin6_scope_id) - - // the buffer is never smaller than 32 bytes, so this is always - // allowed - if (reallen < SOCKADDR_IN6_LEN) - addr.in6->sin6_scope_id = 0; - - reallen = SOCKADDR_IN6_LEN; - } -#endif - else if (addr.generic->sa_family == AF_UNIX) - reallen = MIN_SOCKADDR_UN_LEN + strlen(addr.un->sun_path); - } - else if (clear) - { - memset(addr.generic, 0, len); - addr.generic->sa_family = AF_UNSPEC; - } -} - -// default constructor -KSocketAddress::KSocketAddress() - : d(new KSocketAddressData) -{ -} - -// constructor from binary data -KSocketAddress::KSocketAddress(const sockaddr *sa, TQ_UINT16 len) - : d(new KSocketAddressData) -{ - setAddress(sa, len); -} - -KSocketAddress::KSocketAddress(const KSocketAddress& other) - : d(new(KSocketAddressData)) -{ - *this = other; -} - -KSocketAddress::KSocketAddress(KSocketAddressData *d2) - : d(d2) -{ -} - -KSocketAddress::~KSocketAddress() -{ - // prevent double-deletion, since we're already being deleted - if (d) - { - d->ref.KInetSocketAddress::d = 0L; - d->ref.KUnixSocketAddress::d = 0L; - delete d; - } -} - -KSocketAddress& KSocketAddress::operator =(const KSocketAddress& other) -{ - if (other.d && !other.d->invalid()) - d->dup(other.d->addr.generic, other.d->reallen); - else - d->tqinvalidate(); - return *this; -} - -const sockaddr* KSocketAddress::address() const -{ - if (d->invalid()) - return 0L; - return d->addr.generic; -} - -sockaddr* KSocketAddress::address() -{ - if (d->invalid()) - return 0L; - return d->addr.generic; -} - -KSocketAddress& KSocketAddress::setAddress(const sockaddr* sa, TQ_UINT16 len) -{ - if (sa != 0L && len >= MIN_SOCKADDR_LEN) - d->dup(sa, len); - else - d->tqinvalidate(); - - return *this; -} - -TQ_UINT16 KSocketAddress::length() const -{ - if (d->invalid()) - return 0; - return d->reallen; -} - -KSocketAddress& KSocketAddress::setLength(TQ_UINT16 len) -{ - d->dup((sockaddr*)0L, len, false); - - return *this; -} - -int KSocketAddress::family() const -{ - if (d->invalid()) - return AF_UNSPEC; - return d->addr.generic->sa_family; -} - -KSocketAddress& KSocketAddress::setFamily(int family) -{ - if (d->invalid()) - d->dup((sockaddr*)0L, MIN_SOCKADDR_LEN); - d->addr.generic->sa_family = family; - - return *this; -} - -bool KSocketAddress::operator ==(const KSocketAddress& other) const -{ - // if this is invalid, it's only equal if the other one is invalid as well - if (d->invalid()) - return other.d->invalid(); - - // check the family to make sure we don't do unnecessary comparison - if (d->addr.generic->sa_family != other.d->addr.generic->sa_family) - return false; // not the same family, not equal - - // same family then - // check the ones we know already - switch (d->addr.generic->sa_family) - { - case AF_INET: - Q_ASSERT(d->reallen == SOCKADDR_IN_LEN); - Q_ASSERT(other.d->reallen == SOCKADDR_IN_LEN); - return memcmp(d->addr.in, other.d->addr.in, SOCKADDR_IN_LEN) == 0; - -#ifdef AF_INET6 - case AF_INET6: - Q_ASSERT(d->reallen >= MIN_SOCKADDR_IN6_LEN); - Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_IN6_LEN); - -# if !defined(HAVE_STRUCT_SOCKADDR_IN6) || defined(HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID) - // check for the case where sin6_scope_id isn't present - if (d->reallen != other.d->reallen) - { - if (memcmp(d->addr.in6, other.d->addr.in6, MIN_SOCKADDR_IN6_LEN) != 0) - return false; // not equal - if (d->reallen > other.d->reallen) - return d->addr.in6->sin6_scope_id == 0; - else - return other.d->addr.in6->sin6_scope_id == 0; - } -# endif - - return memcmp(d->addr.in6, other.d->addr.in6, d->reallen) == 0; -#endif - - case AF_UNIX: - Q_ASSERT(d->reallen >= MIN_SOCKADDR_UN_LEN); - Q_ASSERT(other.d->reallen >= MIN_SOCKADDR_UN_LEN); - - // do a string comparison here - return strcmp(d->addr.un->sun_path, other.d->addr.un->sun_path) == 0; - - default: - // something else we don't know about - // they are equal if and only if they are exactly equal - if (d->reallen == other.d->reallen) - return memcmp(d->addr.generic, other.d->addr.generic, d->reallen) == 0; - } - - return false; // not equal in any other case -} - -TQString KSocketAddress::nodeName() const -{ - if (d->invalid()) - return TQString::null; - - switch (d->addr.generic->sa_family) - { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: - - TQString scopeid("%"); - if (d->addr.generic->sa_family == AF_INET6 && d->addr.in6->sin6_scope_id) - scopeid += TQString::number(d->addr.in6->sin6_scope_id); - else - scopeid.truncate(0); - return d->ref.ipAddress().toString() + scopeid; -#else - return d->ref.ipAddress().toString(); -#endif - } - - // any other case, including AF_UNIX - return TQString::null; -} - -TQString KSocketAddress::serviceName() const -{ - if (d->invalid()) - return TQString::null; - - switch (d->addr.generic->sa_family) - { - case AF_INET: -#ifdef AF_INET6 - case AF_INET6: -#endif - return TQString::number(d->ref.port()); - - case AF_UNIX: - return d->ref.pathname(); - } - - return TQString::null; -} - -TQString KSocketAddress::toString() const -{ - if (d->invalid()) - return TQString::null; - - TQString fmt; - - if (d->addr.generic->sa_family == AF_INET) - fmt = "%1:%2"; -#ifdef AF_INET6 - else if (d->addr.generic->sa_family == AF_INET6) - fmt = "[%1]:%2"; -#endif - else if (d->addr.generic->sa_family == AF_UNIX) - return TQString::tqfromLatin1("unix:%1").arg(serviceName()); - else - return i18n("1: the unknown socket address family number", - "Unknown family %1").arg(d->addr.generic->sa_family); - - return fmt.arg(nodeName()).arg(serviceName()); -} - -KInetSocketAddress& KSocketAddress::asInet() -{ - return d->ref; -} - -KInetSocketAddress KSocketAddress::asInet() const -{ - return d->ref; -} - -KUnixSocketAddress& KSocketAddress::asUnix() -{ - return d->ref; -} - -KUnixSocketAddress KSocketAddress::asUnix() const -{ - return d->ref; -} - -int KSocketAddress::ianaFamily(int af) -{ - switch (af) - { - case AF_INET: - return 1; - -#ifdef AF_INET6 - case AF_INET6: - return 2; -#endif - - default: - return 0; - } -} - -int KSocketAddress::fromIanaFamily(int iana) -{ - switch (iana) - { - case 1: - return AF_INET; - -#ifdef AF_INET6 - case 2: - return AF_INET6; -#endif - - default: - return AF_UNSPEC; - } -} - -// default constructor -KInetSocketAddress::KInetSocketAddress() -{ -} - -// binary data constructor -KInetSocketAddress::KInetSocketAddress(const sockaddr* sa, TQ_UINT16 len) - : KSocketAddress(sa, len) -{ - if (!d->invalid()) - update(); -} - -// create from IP and port -KInetSocketAddress::KInetSocketAddress(const KIpAddress& host, TQ_UINT16 port) -{ - setHost(host); - setPort(port); -} - -// copy constructor -KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress& other) - : KSocketAddress(other) -{ -} - -// special copy constructor -KInetSocketAddress::KInetSocketAddress(const KSocketAddress& other) - : KSocketAddress(other) -{ - if (!d->invalid()) - update(); -} - -// special constructor -KInetSocketAddress::KInetSocketAddress(KSocketAddressData *d) - : KSocketAddress(d) -{ -} - -// destructor -KInetSocketAddress::~KInetSocketAddress() -{ - /* nothing to do */ -} - -// copy operator -KInetSocketAddress& KInetSocketAddress::operator =(const KInetSocketAddress& other) -{ - KSocketAddress::operator =(other); - return *this; -} - -// IP version -int KInetSocketAddress::ipVersion() const -{ - if (d->invalid()) - return 0; - - switch (d->addr.generic->sa_family) - { - case AF_INET: - return 4; - -#ifdef AF_INET6 - case AF_INET6: - return 6; -#endif - } - - return 0; // for all other cases -} - -KIpAddress KInetSocketAddress::ipAddress() const -{ - if (d->invalid()) - return KIpAddress(); // return an empty address as well - - switch (d->addr.generic->sa_family) - { - case AF_INET: - return KIpAddress(&d->addr.in->sin_addr, 4); -#ifdef AF_INET6 - case AF_INET6: - return KIpAddress(&d->addr.in6->sin6_addr, 6); -#endif - } - - return KIpAddress(); // empty in all other cases -} - -KInetSocketAddress& KInetSocketAddress::setHost(const KIpAddress& ip) -{ - switch (ip.version()) - { - case 4: - makeIPv4(); - memcpy(&d->addr.in->sin_addr, ip.addr(), sizeof(d->addr.in->sin_addr)); - break; - - case 6: - makeIPv6(); - memcpy(&d->addr.in6->sin6_addr, ip.addr(), sizeof(d->addr.in6->sin6_addr)); - break; - - default: - // empty - d->tqinvalidate(); - } - - return *this; -} - -// returns the port -TQ_UINT16 KInetSocketAddress::port() const -{ - if (d->invalid()) - return 0; - - switch (d->addr.generic->sa_family) - { - case AF_INET: - return ntohs(d->addr.in->sin_port); - -#ifdef AF_INET6 - case AF_INET6: - return ntohs(d->addr.in6->sin6_port); -#endif - } - - return 0; -} - -KInetSocketAddress& KInetSocketAddress::setPort(TQ_UINT16 port) -{ - if (d->invalid()) - makeIPv4(); - - switch (d->addr.generic->sa_family) - { - case AF_INET: - d->addr.in->sin_port = htons(port); - break; - -#ifdef AF_INET6 - case AF_INET6: - d->addr.in6->sin6_port = htons(port); - break; -#endif - - default: - d->tqinvalidate(); // setting the port on something else - } - - return *this; -} - -KInetSocketAddress& KInetSocketAddress::makeIPv4() -{ - d->makeipv4(); - return *this; -} - -KInetSocketAddress& KInetSocketAddress::makeIPv6() -{ - d->makeipv6(); - return *this; -} - -TQ_UINT32 KInetSocketAddress::flowinfo() const -{ -#ifndef AF_INET6 - return 0; -#else - - if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) - return d->addr.in6->sin6_flowinfo; - return 0; -#endif -} - -KInetSocketAddress& KInetSocketAddress::setFlowinfo(TQ_UINT32 flowinfo) -{ - makeIPv6(); // must set here - d->addr.in6->sin6_flowinfo = flowinfo; - return *this; -} - -int KInetSocketAddress::scopeId() const -{ -#ifndef AF_INET6 - return 0; -#else - - if (!d->invalid() && d->addr.in6->sin6_family == AF_INET6) - return d->addr.in6->sin6_scope_id; - return 0; -#endif -} - -KInetSocketAddress& KInetSocketAddress::setScopeId(int scopeid) -{ - makeIPv6(); // must set here - d->addr.in6->sin6_scope_id = scopeid; - return *this; -} - -void KInetSocketAddress::update() -{ - if (d->addr.generic->sa_family == AF_INET) - return; -#ifdef AF_INET6 - else if (d->addr.generic->sa_family == AF_INET6) - return; -#endif - else - d->tqinvalidate(); -} - -KUnixSocketAddress::KUnixSocketAddress() -{ -} - -KUnixSocketAddress::KUnixSocketAddress(const sockaddr* sa, TQ_UINT16 len) - : KSocketAddress(sa, len) -{ - if (!d->invalid() && d->addr.un->sun_family != AF_UNIX) - d->tqinvalidate(); -} - -KUnixSocketAddress::KUnixSocketAddress(const KUnixSocketAddress& other) - : KSocketAddress(other) -{ -} - -KUnixSocketAddress::KUnixSocketAddress(const TQString& pathname) -{ - setPathname(pathname); -} - -KUnixSocketAddress::KUnixSocketAddress(KSocketAddressData* d) - : KSocketAddress(d) -{ -} - -KUnixSocketAddress::~KUnixSocketAddress() -{ -} - -KUnixSocketAddress& KUnixSocketAddress::operator =(const KUnixSocketAddress& other) -{ - KSocketAddress::operator =(other); - return *this; -} - -TQString KUnixSocketAddress::pathname() const -{ - if (!d->invalid() && d->addr.un->sun_family == AF_UNIX) - return TQFile::decodeName(d->addr.un->sun_path); - return TQString::null; -} - -KUnixSocketAddress& KUnixSocketAddress::setPathname(const TQString& path) -{ - d->dup(0L, MIN_SOCKADDR_UN_LEN + path.length()); - d->addr.un->sun_family = AF_UNIX; - strcpy(d->addr.un->sun_path, TQFile::encodeName(path)); - -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - d->addr.un->sun_len = d->reallen; -#endif - - return *this; -} diff --git a/kdecore/network/ksocketaddress.h b/kdecore/network/ksocketaddress.h deleted file mode 100644 index 75deb60ae..000000000 --- a/kdecore/network/ksocketaddress.h +++ /dev/null @@ -1,912 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KSOCKETADDRESS_H -#define KSOCKETADDRESS_H - -#include <tqstring.h> -#include <tqcstring.h> - -#include <kdelibs_export.h> - -struct sockaddr; -struct sockaddr_in; -struct sockaddr_in6; -struct sockaddr_un; - -namespace KNetwork { - -class KIpAddress; -class KSocketAddress; -class KInetSocketAddress; -class KUnixSocketAddress; - -/** @class KIpAddress ksocketaddress.h ksocketaddress.h - * @brief An IP address. - * - * This class represents one IP address, version 4 or 6. This is only - * the address, not including port information or other data. - * - * It is not a good programming practice to create address from objects - * like this. Instead, prefer a more thorough function like - * @ref KResolver::resolve, which also handle extra information like scope - * ids. - * - * This is a light-weight class. Most of the member functions are inlined and - * there are no virtual functions. This object's size should be less than 20 - * bytes. Also note that there is no sharing of data. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KIpAddress -{ -public: - /** - * Default constructor. Creates an empty address. - * It defaults to IP version 4. - */ - inline KIpAddress() : m_version(0) - { } - - /** - * Copy constructor. Copies the data from the other - * object. - * - * Data is not shared. - * - * @param other the other - */ - inline KIpAddress(const KIpAddress& other) - { *this = other; } - - /** - * Creates an object from the given string representation. - * - * The IP version is guessed from the address format. - * - * @param addr the address - */ - inline KIpAddress(const TQString& addr) - { setAddress(addr); } - - /** - * Creates an object from the given string representation. - * - * The IP version is guessed from the address format. - * - * @param addr the address - */ - inline KIpAddress(const char* addr) - { setAddress(addr); } - - /** - * Creates an object from the given raw data and IP version. - * - * @param addr the raw data - * @param version the IP version (4 or 6) - */ - inline KIpAddress(const void* addr, int version = 4) - { setAddress(addr, version); } - - /** - * This is a convenience constructor. Constructs an object - * from the given IPv4 address in the form of an integer. - * - * Note: do not write code to depend on IPv4 addresses being - * integer types. Instead, treat them as a special type, like - * a KIpAddress or the system's in_addr. - * - * @param ip4addr the IPv4 address - */ - inline KIpAddress(TQ_UINT32 ip4addr) - { setAddress(&ip4addr, 4); } - - /** - * Destructor. This frees resources associated with this object. - * - * Note: destructor is non-virtual. The compiler will happily optimise it - * out of the way. - */ - inline ~KIpAddress() - { } - - /** - * Copy operator. - * - * Copies the data from the other object into this one. - * - * @param other the object to copy - */ - KIpAddress& operator =(const KIpAddress& other); - - /** - * Returns true if the two addresses match. - * This function performs a v4-mapped check. - * @see compare - */ - inline bool operator ==(const KIpAddress& other) const - { return compare(other, true); } - - /** - * Compares this address against the other, supplied one and return - * true if they match. The @p checkMapped parameter controls whether - * a check for an IPv6 v4-mapped address will be performed. - * - * An IPv6 v4-mapped address is an IPv6 address that is, for all purposes, - * equivalent to an IPv4 one. The default behaviour of this function - * is to take that into account. If you want a strict matching, - * pass @b false to the @p checkMapped parameter. - * - * @param other the other IP address - * @param checkMapped whether v4-mapped addresses will be taken into account - */ - bool compare(const KIpAddress& other, bool checkMapped = true) const; - - /** - * Retrieves the IP version in this object. - * - * @returns the version: 4 or 6 - */ - inline int version() const - { return m_version; } - - /** - * Returns true if this is an IPv4 address. - */ - inline bool isIPv4Addr() const - { return version() == 4; } - - /** - * Returns true if this is an IPv6 address. - */ - inline bool isIPv6Addr() const - { return version() == 6; } - - /** - * Sets the address to the given string representation. - * - * @return true if the address was successfully parsed; otherwise returns - * false and leaves the object unchanged. - */ - bool setAddress(const TQString& address); - - /** - * Sets the address to the given string representation. - * - * @return true if the address was successfully parsed; otherwise returns - * false and leaves the object unchanged. - */ - bool setAddress(const char* address); - - /** - * Sets the address to the given raw binary representation. - * - * @param raw a pointer to the raw binary data - * @param version the IP version - * @return true if the address was successfully parsed; otherwise returns - * false and leaves the object unchanged. - */ - bool setAddress(const void* raw, int version = 4); - - /** - * Returns the address as a string. - */ - TQString toString() const; - - /** - * Returns a pointer to binary raw data representing the address. - */ - inline const void *addr() const - { return m_data; } - - /** - * This is a convenience function. Returns the IPv4 address in a - * 32-bit integer. The result is only valid if @ref isIPv4Addr returns - * true. Alternatively, if the contained IPv6 address is a v4-mapped one - * and the @p convertMapped parameter is true, the result will also be - * valid. The address returned is in network byte order. - * - * Note: you should not treat IP addresses as integers. Instead, - * use types defined for that purpose, such as KIpAddress or the - * system's in_addr type. - * - */ - inline TQ_UINT32 IPv4Addr(bool convertMapped = true) const - { - return (convertMapped && isV4Mapped()) ? m_data[3] : m_data[0]; - } - - /** - * This is a convenience function. Returns the IPv4 address in a - * 32-bit integer. The result is only valid if @ref isIPv4Addr returns - * true. Alternatively, if the contained IPv6 address is a v4-mapped one - * and the @p convertMapped parameter is true, the result will also be - * valid. The address returned is in host byte order. - * - */ - TQ_UINT32 hostIPv4Addr(bool convertMapped = true) const; - -public: - /*-- tests --*/ - - /** - * Returns true if this is the IPv4 or IPv6 unspecified address. - */ - inline bool isUnspecified() const - { return version() == 0 ? true : (*this == anyhostV4 || *this == anyhostV6); } - - /** - * Returns true if this is either the IPv4 or the IPv6 localhost address. - */ - inline bool isLocalhost() const - { return version() == 0 ? false : (*this == localhostV4 || *this == localhostV6); } - - /** - * This is an alias for @ref isLocalhost. - */ - inline bool isLoopback() const - { return isLocalhost(); } - - /** - * Returns true if this is an IPv4 class A address, i.e., - * from 0.0.0.0 to 127.255.255.255. - * - * This function does not test for v4-mapped addresses. - */ - inline bool isClassA() const - { return version() != 4 ? false : (hostIPv4Addr() & 0x80000000) == 0; } - - /** - * Returns true if this is an IPv4 class B address, i.e., one from - * 128.0.0.0 to 191.255.255.255. - * - * This function does not test for v4-mapped addresses. - */ - inline bool isClassB() const - { return version() != 4 ? false : (hostIPv4Addr() & 0xc0000000) == 0x80000000; } - - /** - * Returns true if this is an IPv4 class C address, i.e., one from - * 192.0.0.0 to 223.255.255.255. - * - * This function does not test for v4-mapped addresses. - */ - inline bool isClassC() const - { return version() != 4 ? false : (hostIPv4Addr() & 0xe0000000) == 0xc0000000; } - - /** - * Returns true if this is an IPv4 class D (a.k.a. multicast) address. - * - * Note: this function is not the same as @ref isMulticast. isMulticast also - * tests for IPv6 multicast addresses. - */ - inline bool isClassD() const - { return version() != 4 ? false : (hostIPv4Addr() & 0xf0000000) == 0xe0000000; } - - /** - * Returns true if this is a multicast address, be it IPv4 or IPv6. - */ - inline bool isMulticast() const - { - if (version() == 4) return isClassD(); - if (version() == 6) return ((TQ_UINT8*)addr())[0] == 0xff; - return false; - } - - /** - * Returns true if this is an IPv6 link-local address. - */ - inline bool isLinkLocal() const - { - if (version() != 6) return false; - TQ_UINT8* addr = (TQ_UINT8*)this->addr(); - return (addr[0] & 0xff) == 0xfe && - (addr[1] & 0xc0) == 0x80; - } - - /** - * Returns true if this is an IPv6 site-local address. - */ - inline bool isSiteLocal() const - { - if (version() != 6) return false; - TQ_UINT8* addr = (TQ_UINT8*)this->addr(); - return (addr[0] & 0xff) == 0xfe && - (addr[1] & 0xc0) == 0xc0; - } - - /** - * Returns true if this is a global IPv6 address. - */ - inline bool isGlobal() const - { return version() != 6 ? false : !(isMulticast() || isLinkLocal() || isSiteLocal()); } - - /** - * Returns true if this is a v4-mapped IPv6 address. - */ - inline bool isV4Mapped() const - { - if (version() != 6) return false; - TQ_UINT32* addr = (TQ_UINT32*)this->addr(); - return addr[0] == 0 && addr[1] == 0 && - ((TQ_UINT16*)&addr[2])[0] == 0 && - ((TQ_UINT16*)&addr[2])[1] == 0xffff; - } - - /** - * Returns true if this is a v4-compat IPv6 address. - */ - inline bool isV4Compat() const - { - if (version() != 6 || isLocalhost()) return false; - TQ_UINT32* addr = (TQ_UINT32*)this->addr(); - return addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] != 0; - } - - /** - * Returns true if this is an IPv6 node-local multicast address. - */ - inline bool isMulticastNodeLocal() const - { return version() == 6 && isMulticast() && (((TQ_UINT32*)addr())[0] & 0xf) == 0x1; } - - /** - * Returns true if this is an IPv6 link-local multicast address. - */ - inline bool isMulticastLinkLocal() const - { return version() == 6 && isMulticast() && (((TQ_UINT32*)addr())[0] & 0xf) == 0x2; } - - /** - * Returns true if this is an IPv6 site-local multicast address. - */ - inline bool isMulticastSiteLocal() const - { return version() == 6 && isMulticast() && (((TQ_UINT32*)addr())[0] & 0xf) == 0x5; } - - /** - * Returns true if this is an IPv6 organisational-local multicast address. - */ - inline bool isMulticastOrgLocal() const - { return version() == 6 && isMulticast() && (((TQ_UINT32*)addr())[0] & 0xf) == 0x8; } - - /** - * Returns true if this is an IPv6 global multicast address. - */ - inline bool isMulticastGlobal() const - { return version() == 6 && isMulticast() && (((TQ_UINT32*)addr())[0] & 0xf) == 0xe; } - -protected: - TQ_UINT32 m_data[4]; // 16 bytes, needed for an IPv6 address - - char m_version; - -public: - /// localhost in IPv4 (127.0.0.1) - static const KIpAddress localhostV4; - /// the any host or undefined address in IPv4 (0.0.0.0) - static const KIpAddress anyhostV4; - - /// localhost in IPv6 (::1) - static const KIpAddress localhostV6; - /// the any host or undefined address in IPv6 (::) - static const KIpAddress anyhostV6; -}; - - -class KSocketAddressData; -/** @class KSocketAddress ksocketaddress.h ksocketaddress.h - * @brief A generic socket address. - * - * This class holds one generic socket address. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KSocketAddress -{ -public: - /** - * Default constructor. - * - * Creates an empty object - */ - KSocketAddress(); - - /** - * Creates this object with the given data. - * The raw socket address is copied into this object. - * - * @param sa the socket address structure - * @param len the socket address length - */ - KSocketAddress(const sockaddr* sa, TQ_UINT16 len); - - /** - * Copy constructor. This creates a copy of the other - * object. - * - * Data is not shared. - * - * @param other the object to copy from - */ - KSocketAddress(const KSocketAddress& other); - - /** - * Destructor. Frees any associated resources. - */ - virtual ~KSocketAddress(); - - /** - * Performs a shallow copy of the other object into this one. - * Data will be copied. - * - * @param other the object to copy from - */ - KSocketAddress& operator =(const KSocketAddress& other); - - /** - * Returns the socket address structure, to be passed down to - * low level functions. - * - * Note that this function returns NULL for invalid or empty sockets, - * so you may use to to test for validity. - */ - const sockaddr* address() const; - - /** - * Returns the socket address structure, to be passed down to - * low level functions. - * - * Note that this function returns NULL for invalid or empty sockets, - * so you may use to to test for validity. - * - * The returned value, if not NULL, is an internal buffer which is guaranteed - * to be at least @ref length() bytes long. - */ - sockaddr* address(); - - /** - * Sets the address to the given address. - * The raw socket address is copied into this object. - * - * @param sa the socket address structure - * @param len the socket address length - */ - KSocketAddress& setAddress(const sockaddr *sa, TQ_UINT16 len); - - /** - * Returns the socket address structure, to be passed down to - * low level functions. - */ - inline operator const sockaddr*() const - { return address(); } - - /** - * Returns the length of this socket address structure. - */ - TQ_UINT16 length() const; - - /** - * Sets the length of this socket structure. - * - * Use this function with care. It allows you to resize the internal - * buffer to fit needs. This function should not be used except for handling - * unknown socket address structures. - * - * Also note that this function may tqinvalidate the socket if a known - * family is set (Internet or Unix socket) and the new length would be - * too small to hold the system's sockaddr_* structure. If unsure, reset - * the family: - * - * \code - * KSocketAddress qsa; - * [...] - * qsa.setFamily(AF_UNSPEC).setLength(newlen); - * \endcode - * - * @param len the new length - */ - KSocketAddress& setLength(TQ_UINT16 len); - - /** - * Returns the family of this address. - * @return the family of this address, AF_UNSPEC if it's undefined - */ - int family() const; - - /** - * Sets the family of this object. - * - * Note: setting the family will probably tqinvalidate any address data - * contained in this object. Use this function with care. - * - * @param family the new family to set - */ - virtual KSocketAddress& setFamily(int family); - - /** - * Returns the IANA family number of this address. - * @return the IANA family number of this address (1 for AF_INET. - * 2 for AF_INET6, otherwise 0) - */ - inline int ianaFamily() const - { return ianaFamily(family()); } - - /** - * Returns true if this equals the other socket. - * - * Socket addresses are considered matching if and only if all data is the same. - * - * @param other the other socket - * @return true if both sockets are equal - */ - bool operator ==(const KSocketAddress& other) const; - - /** - * Returns the node name of this socket. - * - * In the case of Internet sockets, this is string representation of the IP address. - * The default implementation returns TQString::null. - * - * @return the node name, can be TQString::null - * @bug use KResolver to resolve unknown families - */ - virtual TQString nodeName() const; - - /** - * Returns the service name for this socket. - * - * In the case of Internet sockets, this is the port number. - * The default implementation returns TQString::null. - * - * @return the service name, can be TQString::null - * @bug use KResolver to resolve unknown families - */ - virtual TQString serviceName() const; - - /** - * Returns this socket address as a string suitable for - * printing. Family, node and service are part of this address. - * - * @bug use KResolver to resolve unknown families - */ - virtual TQString toString() const; - - /** - * Returns an object reference that can be used to manipulate this socket - * as an Internet socket address. Both objects share the same data. - */ - KInetSocketAddress& asInet(); - - /** - * Returns an object is equal to this object's data, but they don't share it. - */ - KInetSocketAddress asInet() const; - - /** - * Returns an object reference that can be used to manipulate this socket - * as a Unix socket address. Both objects share the same data. - */ - KUnixSocketAddress& asUnix(); - - /** - * Returns an object is equal to this object's data, but they don't share it. - */ - KUnixSocketAddress asUnix() const; - -protected: - /// @internal - /// private data - KSocketAddressData *d; - - /// @internal - /// extra constructor - KSocketAddress(KSocketAddressData* d); - -public: // static - /** - * Returns the IANA family number of the given address family. - * Returns 0 if there is no corresponding IANA family number. - * @param af the address family, in AF_* constants - * @return the IANA family number of this address (1 for AF_INET. - * 2 for AF_INET6, otherwise 0) - */ - static int ianaFamily(int af); - - /** - * Returns the address family of the given IANA family number. - * @return the address family, AF_UNSPEC for unknown IANA family numbers - */ - static int fromIanaFamily(int iana); -}; - - -/** @class KInetSocketAddress ksocketaddress.h ksocketaddress.h - * @brief an Internet socket address - * - * An Inet (IPv4 or IPv6) socket address - * - * This is an IPv4 or IPv6 address of the Internet. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KInetSocketAddress: public KSocketAddress -{ - friend class KSocketAddress; -public: - /** - * Public constructor. Creates an empty object. - */ - KInetSocketAddress(); - - /** - * Creates an object from raw data. - * - * Note: if the socket address @p sa does not contain a valid Internet - * socket (IPv4 or IPv6), this object will be empty. - * - * @param sa the sockaddr structure - * @param len the structure's length - */ - KInetSocketAddress(const sockaddr* sa, TQ_UINT16 len); - - /** - * Creates an object from an IP address and port. - * - * @param host the IP address - * @param port the port number - */ - KInetSocketAddress(const KIpAddress& host, TQ_UINT16 port); - - /** - * Copy constructor. - * - * Data is not shared. - * - * @param other the other object - */ - KInetSocketAddress(const KInetSocketAddress& other); - - /** - * Copy constructor. - * - * If the other, generic socket address contains an Internet address, - * it will be copied. Otherwise, this object will be empty. - * - * @param other the other object - */ - KInetSocketAddress(const KSocketAddress& other); - - /** - * Destroys this object. - */ - virtual ~KInetSocketAddress(); - - /** - * Copy operator. - * - * Copies the other object into this one. - * - * @param other the other object - */ - KInetSocketAddress& operator =(const KInetSocketAddress& other); - - /** - * Cast operator to sockaddr_in. - */ - inline operator const sockaddr_in*() const - { return (const sockaddr_in*)address(); } - - /** - * Cast operator to sockaddr_in6. - */ - inline operator const sockaddr_in6*() const - { return (const sockaddr_in6*)address(); } - - /** - * Returns the IP version of the address this object holds. - * - * @return 4 or 6, if IPv4 or IPv6, respectively; 0 if this object is empty - */ - int ipVersion() const; - - /** - * Returns the IP address component. - */ - KIpAddress ipAddress() const; - - /** - * Sets the IP address to the given raw address. - * - * This call will preserve port numbers accross IP versions, but will lose - * IPv6 specific data if the address is set to IPv4. - * - * @param addr the address to set to - * @return a reference to itself - */ - KInetSocketAddress& setHost(const KIpAddress& addr); - - /** - * Retrieves the port number stored in this object. - * - * @return a port number in the range 0 to 65535, inclusive. An empty or - * invalid object will have a port number of 0. - */ - TQ_UINT16 port() const; - - /** - * Sets the port number. If this object is empty, this function will default to - * creating an IPv4 address. - * - * @param port the port number to set - * @return a reference to itself - */ - KInetSocketAddress& setPort(TQ_UINT16 port); - - /** - * Converts this object to an IPv4 socket address. It has no effect if the object - * is already an IPv4 socket address. - * - * If this object is an IPv6 address, the port number is preserved. All other information - * is lost. - * - * @return a reference to itself - */ - KInetSocketAddress& makeIPv4(); - - /** - * Converts this object to an IPv6 socket address. It has no effect if the object - * is already an IPv6 socket address. - * - * If this object is an IPv4 address, the port number is preserved. - * - * @return a reference to itself - */ - KInetSocketAddress& makeIPv6(); - - /** - * Returns the flowinfo information from the IPv6 socket address. - * - * @return the flowinfo information or 0 if this object is empty or IPv4 - */ - TQ_UINT32 flowinfo() const; - - /** - * Sets the flowinfo information for an IPv6 socket address. If this is not - * an IPv6 socket address, this function converts it to one. See makeIPv6. - * - * @param flowinfo the flowinfo to set - * @return a reference to itself - */ - KInetSocketAddress& setFlowinfo(TQ_UINT32 flowinfo); - - /** - * Returns the scope id this IPv6 socket is bound to. - * - * @return the scope id, or 0 if this is not an IPv6 object - */ - int scopeId() const; - - /** - * Sets the scope id for this IPv6 object. If this is not an IPv6 socket - * address, this function converts it to one. See makeIPv6 - * - * @param scopeid the scopeid to set - * @return a reference to itself - */ - KInetSocketAddress& setScopeId(int scopeid); - -protected: - /// @internal - /// extra constructor - KInetSocketAddress(KSocketAddressData* d); - -private: - void update(); -}; - -/* - * External definition - */ - -/** @class KUnixSocketAddress ksocketaddress.h ksocketaddress.h - * @brief A Unix (local) socket address. - * - * This is a Unix socket address. - * - * Note that this class uses QStrings to represent filenames, which means - * the proper encoding is used to translate into valid filesystem file names. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KUnixSocketAddress: public KSocketAddress -{ - friend class KSocketAddress; -public: - /** - * Default constructor. Creates an empty object. - */ - KUnixSocketAddress(); - - /** - * Creates this object with the given raw data. If - * the sockaddr structure does not contain a Local namespace - * (Unix) socket, this object will be created empty. - * - * @param sa the socket address structure - * @param len the structure's length - */ - KUnixSocketAddress(const sockaddr* sa, TQ_UINT16 len); - - /** - * Copy constructor. Creates a copy of the other object, - * sharing the data explicitly. - * - * @param other the other object - */ - KUnixSocketAddress(const KUnixSocketAddress& other); - - /** - * Constructs an object from the given pathname. - */ - KUnixSocketAddress(const TQString& pathname); - - /** - * Destructor. - */ - virtual ~KUnixSocketAddress(); - - /** - * Copy operator. Copies the contents of the other object into - * this one. Data is explicitly shared. - * - * @param other the other - */ - KUnixSocketAddress& operator =(const KUnixSocketAddress& other); - - /** - * Cast operator to sockaddr_un. - */ - inline operator const sockaddr_un*() const - { return (const sockaddr_un*)address(); } - - /** - * Returns the pathname associated with this object. Will return - * TQString::null if this object is empty. - */ - TQString pathname() const; - - /** - * Sets the pathname for the object. - * - * @return a reference to itself - */ - KUnixSocketAddress& setPathname(const TQString& path); - -protected: - /// @internal - /// extra constructor - KUnixSocketAddress(KSocketAddressData* d); -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/ksocketbase.cpp b/kdecore/network/ksocketbase.cpp deleted file mode 100644 index f5410f3e8..000000000 --- a/kdecore/network/ksocketbase.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003-2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> -#include <tqmutex.h> -#include "klocale.h" - -#include "ksocketbase.h" -#include "ksocketdevice.h" - -using namespace KNetwork; - -class KNetwork::KSocketBasePrivate -{ -public: - int socketOptions; - int socketError; - int capabilities; - - mutable KSocketDevice* device; - - TQMutex mutex; - - KSocketBasePrivate() - : mutex(true) // create recursive - { } -}; - -KSocketBase::KSocketBase() - : d(new KSocketBasePrivate) -{ - d->socketOptions = Blocking; - d->socketError = 0; - d->device = 0L; - d->capabilities = 0; -} - -KSocketBase::~KSocketBase() -{ - delete d->device; - delete d; -} - -bool KSocketBase::setSocketOptions(int opts) -{ - d->socketOptions = opts; - return true; -} - -int KSocketBase::socketOptions() const -{ - return d->socketOptions; -} - -bool KSocketBase::setBlocking(bool enable) -{ - return setSocketOptions((socketOptions() & ~Blocking) | (enable ? Blocking : 0)); -} - -bool KSocketBase::blocking() const -{ - return socketOptions() & Blocking; -} - -bool KSocketBase::setAddressReuseable(bool enable) -{ - return setSocketOptions((socketOptions() & ~AddressReuseable) | (enable ? AddressReuseable : 0)); -} - -bool KSocketBase::addressReuseable() const -{ - return socketOptions() & AddressReuseable; -} - -bool KSocketBase::setIPv6Only(bool enable) -{ - return setSocketOptions((socketOptions() & ~IPv6Only) | (enable ? IPv6Only : 0)); -} - -bool KSocketBase::isIPv6Only() const -{ - return socketOptions() & IPv6Only; -} - -bool KSocketBase::setBroadcast(bool enable) -{ - return setSocketOptions((socketOptions() & ~Broadcast) | (enable ? Broadcast : 0)); -} - -bool KSocketBase::broadcast() const -{ - return socketOptions() & Broadcast; -} - -KSocketDevice* KSocketBase::socketDevice() const -{ - if (d->device) - return d->device; - - // it doesn't exist, so create it - TQMutexLocker locker(mutex()); - if (d->device) - return d->device; - - KSocketBase* that = const_cast<KSocketBase*>(this); - KSocketDevice* dev = 0; - if (d->capabilities) - dev = KSocketDevice::createDefault(that, d->capabilities); - if (!dev) - dev = KSocketDevice::createDefault(that); - that->setSocketDevice(dev); - return d->device; -} - -void KSocketBase::setSocketDevice(KSocketDevice* device) -{ - TQMutexLocker locker(mutex()); - if (d->device == 0L) - d->device = device; -} - -int KSocketBase::setRequestedCapabilities(int add, int remove) -{ - d->capabilities |= add; - d->capabilities &= ~remove; - return d->capabilities; -} - -bool KSocketBase::hasDevice() const -{ - return d->device != 0L; -} - -void KSocketBase::setError(SocketError error) -{ - d->socketError = error; -} - -KSocketBase::SocketError KSocketBase::error() const -{ - return static_cast<KSocketBase::SocketError>(d->socketError); -} - -// static -TQString KSocketBase::errorString(KSocketBase::SocketError code) -{ - TQString reason; - switch (code) - { - case NoError: - reason = i18n("Socket error code NoError", "no error"); - break; - - case LookupFailure: - reason = i18n("Socket error code LookupFailure", - "name lookup has failed"); - break; - - case AddressInUse: - reason = i18n("Socket error code AddressInUse", - "address already in use"); - break; - - case AlreadyBound: - reason = i18n("Socket error code AlreadyBound", - "socket is already bound"); - break; - - case AlreadyCreated: - reason = i18n("Socket error code AlreadyCreated", - "socket is already created"); - break; - - case NotBound: - reason = i18n("Socket error code NotBound", - "socket is not bound"); - break; - - case NotCreated: - reason = i18n("Socket error code NotCreated", - "socket has not been created"); - break; - - case WouldBlock: - reason = i18n("Socket error code WouldBlock", - "operation would block"); - break; - - case ConnectionRefused: - reason = i18n("Socket error code ConnectionRefused", - "connection actively refused"); - break; - - case ConnectionTimedOut: - reason = i18n("Socket error code ConnectionTimedOut", - "connection timed out"); - break; - - case InProgress: - reason = i18n("Socket error code InProgress", - "operation is already in progress"); - break; - - case NetFailure: - reason = i18n("Socket error code NetFailure", - "network failure occurred"); - break; - - case NotSupported: - reason = i18n("Socket error code NotSupported", - "operation is not supported"); - break; - - case Timeout: - reason = i18n("Socket error code Timeout", - "timed operation timed out"); - break; - - case UnknownError: - reason = i18n("Socket error code UnknownError", - "an unknown/unexpected error has happened"); - break; - - case RemotelyDisconnected: - reason = i18n("Socket error code RemotelyDisconnected", - "remote host closed connection"); - break; - - default: - reason = TQString::null; - break; - } - - return reason; -} - -// static -bool KSocketBase::isFatalError(int code) -{ - switch (code) - { - case WouldBlock: - case InProgress: - case NoError: - case RemotelyDisconnected: - return false; - } - - return true; -} - -void KSocketBase::unsetSocketDevice() -{ - d->device = 0L; -} - -TQMutex* KSocketBase::mutex() const -{ - return &d->mutex; -} - -KActiveSocketBase::KActiveSocketBase() -{ -} - -KActiveSocketBase::~KActiveSocketBase() -{ -} - -int KActiveSocketBase::getch() -{ - unsigned char c; - if (tqreadBlock((char*)&c, 1) != 1) - return -1; - - return c; -} - -int KActiveSocketBase::putch(int ch) -{ - unsigned char c = (unsigned char)ch; - if (tqwriteBlock((char*)&c, 1) != 1) - return -1; - - return c; -} - -void KActiveSocketBase::setError(int status, SocketError error) -{ - KSocketBase::setError(error); - setqStatus(status); -} - -void KActiveSocketBase::resetError() -{ - KSocketBase::setError(NoError); - resetStatus(); -} - -KPassiveSocketBase::KPassiveSocketBase() -{ -} - -KPassiveSocketBase::~KPassiveSocketBase() -{ -} diff --git a/kdecore/network/ksocketbase.h b/kdecore/network/ksocketbase.h deleted file mode 100644 index 8a94cbbcb..000000000 --- a/kdecore/network/ksocketbase.h +++ /dev/null @@ -1,771 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Even before our #ifdef, clean up the namespace - */ -#ifdef socket -#undef socket -#endif - -#ifdef bind -#undef bind -#endif - -#ifdef listen -#undef listen -#endif - -#ifdef connect -#undef connect -#endif - -#ifdef accept -#undef accept -#endif - -#ifdef getpeername -#undef getpeername -#endif - -#ifdef getsockname -#undef getsockname -#endif - -#ifndef KSOCKETBASE_H -#define KSOCKETBASE_H - -#include <tqiodevice.h> -#include <tqstring.h> - -#include "ksocketaddress.h" -#include <kdelibs_export.h> - -/* - * This is extending QIODevice's error codes - * - * According to tqiodevice.h, the last error is IO_UnspecifiedError - * These errors will never occur in functions declared in QIODevice - * (except open, but you shouldn't call open) - */ -#define IO_ListenError (IO_UnspecifiedError+1) -#define IO_AcceptError (IO_UnspecifiedError+2) -#define IO_LookupError (IO_UnspecifiedError+3) -#define IO_SocketCreateError (IO_UnspecifiedError+4) -#define IO_BindError (IO_UnspecifiedError+5) - -class TQMutex; - -namespace KNetwork { - -class KResolverEntry; -class KSocketDevice; - -class KSocketBasePrivate; -/** @class KSocketBase ksocketbase.h ksocketbase.h - * @brief Basic socket functionality. - * - * This class provides the basic socket functionlity for descended classes. - * Socket classes are thread-safe and provide a recursive mutex should it be - * needed. - * - * @note This class is abstract. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KSocketBase -{ -public: - /** - * Possible socket options. - * - * These are the options that may be set on a socket: - * - Blocking: whether the socket shall operate in blocking - * or non-blocking mode. This flag defaults to on. - * See @ref setBlocking. - * - AddressReusable: whether the address used by this socket will - * be available for reuse by other sockets. This flag defaults to off. - * See @ref setAddressReuseable. - * - IPv6Only: whether an IPv6 socket will accept IPv4 connections - * through a mapped address. This flag defaults to off. - * See @ref setIPv6Only. - * - KeepAlive: whether TCP should send keepalive probes when a connection - * has gone idle for far too long. - * - Broadcast: whether this socket is allowed to send broadcast packets - * and will receive packets sent to broadcast. - */ - enum SocketOptions - { - Blocking = 0x01, - AddressReuseable = 0x02, - IPv6Only = 0x04, - Keepalive = 0x08, - Broadcast = 0x10 - }; - - /** - * Possible socket error codes. - * - * This is a list of possible error conditions that socket classes may - * be expected to find. - * - * - NoError: no error has been detected - * - LookupFailure: if a name lookup has failed - * - AddressInUse: address is already in use - * - AlreadyBound: cannot bind again - * - AlreadyCreated: cannot recreate the socket - * - NotBound: operation required socket to be bound and it isn't - * - NotCreated: operation required socket to exist and it doesn't - * - WouldBlock: requested I/O operation would block - * - ConnectionRefused: connection actively refused - * - ConnectionTimedOut: connection timed out - * - InProgress: operation (connection) is already in progress - * - NetFailure: a network failure occurred (no route, host down, host unreachable or similar) - * - NotSupported: requested operation is not supported - * - Timeout: a timed operation timed out - * - UnknownError: an unknown/unexpected error has happened - * - RemotelyDisconnected: when a connection is disconnected by the other end (since 3.4) - * - * @sa error, errorString - */ - enum SocketError - { - NoError = 0, - LookupFailure, - AddressInUse, - AlreadyCreated, - AlreadyBound, - AlreadyConnected, - NotConnected, - NotBound, - NotCreated, - WouldBlock, - ConnectionRefused, - ConnectionTimedOut, - InProgress, - NetFailure, - NotSupported, - Timeout, - UnknownError, - RemotelyDisconnected - }; - -public: - /** - * Default constructor. - */ - KSocketBase(); - - /** - * Destructor. - */ - virtual ~KSocketBase(); - - /* - * The following functions are shared by all descended classes and will have - * to be reimplemented. - */ - -protected: - /** - * Set the given socket options. - * - * The default implementation does nothing but store the mask internally. - * Descended classes must override this function to achieve functionality and - * must also call this implementation. - * - * @param opts a mask of @ref SocketOptions or-ed bits of options to set - * or unset - * @returns true on success - * @note this function sets the options corresponding to the bits enabled in @p opts - * but will also unset the optiosn corresponding to the bits not set. - */ - virtual bool setSocketOptions(int opts); - - /** - * Retrieves the socket options that have been set. - * - * The default implementation just retrieves the mask from an internal variable. - * Descended classes may choose to override this function to read the values - * from the operating system. - * - * @returns the mask of the options set - */ - virtual int socketOptions() const; - -public: - /** - * Sets this socket's blocking mode. - * - * In blocking operation, all I/O functions are susceptible to blocking -- - * i.e., will not return unless the I/O can be satisfied. In non-blocking - * operation, if the I/O would block, the function will return an error - * and set the corresponding error code. - * - * The default implementation toggles the Blocking flag with the current - * socket options and calls @ref setSocketOptions. - * - * @param enable whether to set this socket to blocking mode - * @returns whether setting this value was successful; it is NOT the - * final blocking mode. - */ - virtual bool setBlocking(bool enable); - - /** - * Retrieves this socket's blocking mode. - * - * @returns true if this socket is/will be operated in blocking mode, - * false if non-blocking. - */ - bool blocking() const; - - /** - * Sets this socket's address reuseable flag. - * - * When the address reuseable flag is active, the address used by - * this socket is left reuseable for other sockets to bind. If - * the flag is not active, no other sockets may reuse the same - * address. - * - * The default implementation toggles the AddressReuseable flag with the current - * socket options and calls @ref setSocketOptions. - * - * @param enable whether to set the flag on or off - * @returns true if setting this flag was successful - */ - virtual bool setAddressReuseable(bool enable); - - /** - * Retrieves this socket's address reuseability flag. - * - * @returns true if this socket's address can be reused, - * false if it can't. - */ - bool addressReuseable() const; - - /** - * Sets this socket's IPv6 Only flag. - * - * When this flag is on, an IPv6 socket will only accept, connect, send to or - * receive from IPv6 addresses. When it is off, it will also talk to - * IPv4 addresses through v4-mapped addresses. - * - * This option has no effect on non-IPv6 sockets. - * - * The default implementation toggles the IPv6Only flag with the current - * socket options and calls @ref setSocketOptions. - * - * @param enable whether to set the flag on or off - * @returns true if setting this flag was successful - */ - virtual bool setIPv6Only(bool enable); - - /** - * Retrieves this socket's IPv6 Only flag. - * - * @returns true if this socket will ignore IPv4-compatible and IPv4-mapped - * addresses, false if it will accept them. - */ - bool isIPv6Only() const; - - /** - * Sets this socket Broadcast flag. - * - * Datagram-oriented sockets cannot normally send packets to broadcast - * addresses, nor will they receive packets that were sent to a broadcast - * address. To do so, you need to enable the Broadcast flag. - * - * This option has no effect on stream-oriented sockets. - * - * @returns true if setting this flag was successful. - */ - virtual bool setBroadcast(bool enable); - - /** - * Retrieves this socket's Broadcast flag. - * - * @returns true if this socket can send and receive broadcast packets, - * false if it can't. - */ - bool broadcast() const; - - /** - * Retrieves the socket implementation used on this socket. - * - * This function creates the device if none has been set - * using the default factory. - */ - KSocketDevice* socketDevice() const; - - /** - * Sets the socket implementation to be used on this socket. - * - * Note: it is an error to set this if the socket device has - * already been set once. - * - * This function is provided virtual so that derived classes can catch - * the setting of a device and properly set their own states and internal - * variables. The parent class must be called. - * - * This function is called by @ref socketDevice above when the socket is - * first created. - */ - virtual void setSocketDevice(KSocketDevice* device); - - /** - * Sets the internally requested capabilities for a socket device. - * - * Most socket classes can use any back-end implementation. However, a few - * may require specific capabilities not provided in the default - * implementation. By using this function, derived classes can request - * that a backend with those capabilities be created when necessary. - * - * For the possible flags, see @ref KSocketDevice::Capabilities. However, note - * that only the Can* flags make sense in this context. - * - * @note Since socketDevice must always return a valid backend object, it - * is is possible that the created device does not conform to all - * requirements requested. Implementations sensitive to this fact - * should test the object returned by @ref socketDevice (through - * @ref KSocketDevice::capabilities, for instance) the availability. - * - * @param add mask of @ref KSocketDevice::Capabilities to add - * @param remove mask of bits to remove from the requirements - * @return the current mask of requested capabilities - */ - int setRequestedCapabilities(int add, int remove = 0); - -protected: - /** - * Returns true if the socket device has been initialised in this - * object, either by calling @ref socketDevice() or @ref setSocketDevice - */ - bool hasDevice() const; - - /** - * Sets the socket's error code. - * - * @param error the error code - */ - void setError(SocketError error); - -public: - /** - * Retrieves the socket error code. - * @sa errorString - */ - SocketError error() const; - - /** - * Returns the error string corresponding to this error condition. - */ - inline TQString errorString() const - { return errorString(error()); } - - /** - * Returns the internal mutex for this class. - * - * Note on multithreaded use of sockets: - * the socket classes are thread-safe by design, but you should be aware of - * problems regarding socket creation, connection and destruction in - * multi-threaded programs. The classes are guaranteed to work while - * the socket exists, but it's not wise to call connect in multiple - * threads. - * - * Also, this mutex must be unlocked before the object is destroyed, which - * means you cannot use it to guard against other threads accessing the object - * while destroying it. You must ensure there are no further references to this - * object when deleting it. - */ - TQMutex* mutex() const; - -public: - /** - * Returns the string describing the given error code, i18n'ed. - * - * @param code the error code - */ - static TQString errorString(SocketError code); - - /** - * Returns true if the given error code is a fatal one, false - * otherwise. The parameter here is of type int so that - * casting isn't necessary when using the parameter to signal - * QClientSocketBase::gotError. - * - * @param code the code to test - */ - static bool isFatalError(int code); - -private: - /// @internal - /// called by KSocketDevice - void unsetSocketDevice(); - - KSocketBase(const KSocketBase&); - KSocketBase& operator =(const KSocketBase&); - - KSocketBasePrivate *d; - - friend class KSocketDevice; -}; - -/** - * @class KActiveSocketBase ksocketbase.h ksocketbase.h - * @brief Abstract class for active sockets - * - * This class provides the standard interfaces for active sockets, i.e., - * sockets that are used to connect to external addresses. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KActiveSocketBase: public TQIODevice, virtual public KSocketBase -{ -public: - /** - * Constructor. - */ - KActiveSocketBase(); - - /** - * Destructor. - */ - virtual ~KActiveSocketBase(); - - /** - * Binds this socket to the given address. - * - * The socket will be constructed with the address family, - * socket type and protocol as those given in the - * @p address object. - * - * @param address the address to bind to - * @returns true if the binding was successful, false otherwise - */ - virtual bool bind(const KResolverEntry& address) = 0; - - /** - * Connect to a remote host. - * - * This will make this socket try to connect to the remote host. - * If the socket is not yet created, it will be created using the - * address family, socket type and protocol specified in the - * @p address object. - * - * If this function returns with error InProgress, calling it - * again with the same address after a time will cause it to test - * if the connection has succeeded in the mean time. - * - * @param address the address to connect to - * @returns true if the connection was successful or has been successfully - * queued; false if an error occurred. - */ - virtual bool connect(const KResolverEntry& address) = 0; - - /** - * Disconnects this socket from a connection, if possible. - * - * If this socket was connected to an endpoint, the connection - * is severed, but the socket is not closed. If the socket wasn't - * connected, this function does nothing. - * - * If the socket hadn't yet been created, this function does nothing - * either. - * - * Not all socket types can disconnect. Most notably, only - * connectionless datagram protocols such as UDP support this operation. - * - * @return true if the socket is now disconnected or false on error. - */ - virtual bool disconnect() = 0; - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - * This will always return 0. - */ -#ifdef USE_QT4 - virtual qint64 size() const -#else // USE_QT4 - virtual Offset size() const -#endif // USE_QT4 - { return 0; } - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - * This will always return 0. - */ - virtual Offset at() const - { return 0; } - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - * This will always return false. - */ - virtual bool at(Offset) - { return false; } - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - * This will always return true. - */ - virtual bool atEnd() const - { return true; } - - /** - * Returns the number of bytes available for reading without - * blocking. - */ -#ifdef USE_QT3 - virtual TQ_LONG bytesAvailable() const = 0; -#endif -#ifdef USE_QT4 - virtual qint64 bytesAvailable() const = 0; -#endif - - /** - * Waits up to @p msecs for more data to be available on this socket. - * - * If msecs is -1, this call will block indefinetely until more data - * is indeed available; if it's 0, this function returns immediately. - * - * If @p timeout is not NULL, this function will set it to indicate - * if a timeout occurred. - * - * @returns the number of bytes available - */ - virtual TQ_LONG waitForMore(int msecs, bool *timeout = 0L) = 0; - - /** - * Reads data from the socket. - * - * Reimplemented from TQIODevice. See TQIODevice::readBlock for - * more information. - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG len) = 0; - - /** @overload - * Receives data and the source address. - * - * This call will read data in the socket and will also - * place the sender's address in @p from object. - * - * @param data where to write the read data to - * @param maxlen the maximum number of bytes to read - * @param from the address of the sender will be stored here - * @returns the actual number of bytes read - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress& from) = 0; - - /** - * Peeks the data in the socket. - * - * This call will allow you to peek the data to be received without actually - * receiving it -- that is, it will be available for further peekings and - * for the next read call. - * - * @param data where to write the peeked data to - * @param maxlen the maximum number of bytes to peek - * @returns the actual number of bytes copied into @p data - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen) = 0; - - /** @overload - * Peeks the data in the socket and the source address. - * - * This call will allow you to peek the data to be received without actually - * receiving it -- that is, it will be available for further peekings and - * for the next read call. - * - * @param data where to write the peeked data to - * @param maxlen the maximum number of bytes to peek - * @param from the address of the sender will be stored here - * @returns the actual number of bytes copied into @p data - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from) = 0; - - /** - * Writes the given data to the socket. - * - * Reimplemented from TQIODevice. See TQIODevice::writeBlock for - * more information. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len) = 0; - - /** @overload - * Writes the given data to the destination address. - * - * Note that not all socket connections allow sending data to different - * addresses than the one the socket is connected to. - * - * @param data the data to write - * @param len the length of the data - * @param to the address to send to - * @returns the number of bytes actually sent - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to) = 0; - - /** - * Reads one character from the socket. - * Reimplementation from TQIODevice. See TQIODevice::getch for more information. - */ - virtual int getch(); - - /** - * Writes one character to the socket. - * Reimplementation from TQIODevice. See TQIODevice::putch for more information. - */ - virtual int putch(int ch); - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - * This will always return -1; - */ - virtual int ungetch(int) - { return -1; } - - /** - * Returns this socket's local address. - */ - virtual KSocketAddress localAddress() const = 0; - - /** - * Return this socket's peer address, if we are connected. - * If the address cannot be retrieved, the returned object will contain - * an invalid address. - */ - virtual KSocketAddress peerAddress() const = 0; - - // FIXME KDE 4.0: - // enable this function -#if 0 - /** - * Returns this socket's externally-visible address, if known. - */ - virtual KSocketAddress externalAddress() const = 0; -#endif - -protected: - /** - * Sets the socket's error code and the I/O Device's status. - * - * @param status the I/O Device status - * @param error the error code - */ - void setError(int status, SocketError error); - - /** - * Resets the socket error code and the I/O Device's status. - */ - void resetError(); -}; - -/** - * @class KPassiveSocketBase ksocketbase.h ksocketbase.h - * @brief Abstract base class for passive sockets. - * - * This socket provides the initial functionality for passive sockets, - * i.e., sockets that accept incoming connections. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KPassiveSocketBase: virtual public KSocketBase -{ -public: - /** - * Constructor - */ - KPassiveSocketBase(); - - /** - * Destructor - */ - virtual ~KPassiveSocketBase(); - - /** - * Binds this socket to the given address. - * - * The socket will be constructed with the address family, - * socket type and protocol as those given in the - * @p address object. - * - * @param address the address to bind to - * @returns true if the binding was successful, false otherwise - */ - virtual bool bind(const KResolverEntry& address) = 0; - - /** - * Puts this socket into listening mode. - * - * Placing a socket in listening mode means that it will - * be allowed to receive incoming connections from - * remote hosts. - * - * Note that some socket types or protocols cannot be - * put in listening mode. - * - * @param backlog the number of accepted connections to - * hold before starting to refuse - * @returns true if the socket is now in listening mode - */ - virtual bool listen(int backlog) = 0; - - /** - * Closes this socket. All resources used are freed. Note that closing - * a passive socket does not close the connections accepted with it. - */ - virtual void close() = 0; - - /** - * Accepts a new incoming connection. - * - * If this socket was in listening mode, you can call this - * function to accept an incoming connection. - * - * If this function cannot accept a new connection (either - * because it is not listening for one or because the operation - * would block), it will return NULL. - * - * Also note that descended classes will override this function - * to return specialised socket classes. - */ - virtual KActiveSocketBase* accept() = 0; - - /** - * Returns this socket's local address. - */ - virtual KSocketAddress localAddress() const = 0; - - /** - * Returns this socket's externally-visible address if known. - */ - virtual KSocketAddress externalAddress() const = 0; - -private: - KPassiveSocketBase(const KPassiveSocketBase&); - KPassiveSocketBase& operator = (const KPassiveSocketBase&); -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/ksocketbuffer.cpp b/kdecore/network/ksocketbuffer.cpp deleted file mode 100644 index aacffde45..000000000 --- a/kdecore/network/ksocketbuffer.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <assert.h> -#include <string.h> - -#include "ksocketbase.h" -#include "ksocketbuffer_p.h" - -using namespace KNetwork; -using namespace KNetwork::Internal; - -KSocketBuffer::KSocketBuffer(TQ_LONG size) - : m_mutex(true), m_offset(0), m_size(size), m_length(0) -{ -} - -KSocketBuffer::KSocketBuffer(const KSocketBuffer& other) - : KIOBufferBase(other), m_mutex(true) -{ - *this = other; -} - -KSocketBuffer::~KSocketBuffer() -{ - // TQValueList takes care of deallocating memory -} - -KSocketBuffer& KSocketBuffer::operator=(const KSocketBuffer& other) -{ - TQMutexLocker locker1(&m_mutex); - TQMutexLocker locker2(&other.m_mutex); - - KIOBufferBase::operator=(other); - - m_list = other.m_list; // copy-on-write - m_offset = other.m_offset; - m_size = other.m_size; - m_length = other.m_length; - - return *this; -} - -bool KSocketBuffer::canReadLine() const -{ - TQMutexLocker locker(&m_mutex); - - TQValueListConstIterator<TQByteArray> it = m_list.constBegin(), - end = m_list.constEnd(); - TQIODevice::Offset offset = m_offset; - - // walk the buffer - for ( ; it != end; ++it) - { - if ((*it).find('\n', offset) != -1) - return true; - if ((*it).find('\r', offset) != -1) - return true; - offset = 0; - } - - return false; // not found -} - -TQCString KSocketBuffer::readLine() -{ - if (!canReadLine()) - return TQCString(); // empty - - TQMutexLocker locker(&m_mutex); - - // find the offset of the newline in the buffer - int newline = 0; - TQValueListConstIterator<TQByteArray> it = m_list.constBegin(), - end = m_list.constEnd(); - TQIODevice::Offset offset = m_offset; - - // walk the buffer - for ( ; it != end; ++it) - { - int posnl = (*it).find('\n', offset); - if (posnl == -1) - { - // not found in this one - newline += (*it).size(); - offset = 0; - continue; - } - - // we found it - newline += posnl; - break; - } - - TQCString result(newline + 2 - m_offset); - consumeBuffer(result.data(), newline + 1 - m_offset); - return result; -} - -TQ_LONG KSocketBuffer::length() const -{ - return m_length; -} - -TQ_LONG KSocketBuffer::size() const -{ - return m_size; -} - -bool KSocketBuffer::setSize(TQ_LONG size) -{ - m_size = size; - if (size == -1 || m_length < m_size) - return true; - - // size is now smaller than length - TQMutexLocker locker(&m_mutex); - - // repeat the test - if (m_length < m_size) - return true; - - // discard from the beginning - return (m_length - m_size) == consumeBuffer(0L, m_length - m_size, true); -} - -TQ_LONG KSocketBuffer::feedBuffer(const char *data, TQ_LONG len) -{ - if (data == 0L || len == 0) - return 0; // nothing to write - if (isFull()) - return -1; // can't write - - TQMutexLocker locker(&m_mutex); - - // verify if we can add len bytes - if (m_size != -1 && (m_size - m_length) < len) - len = m_size - m_length; - - TQByteArray a(len); - a.duplicate(data, len); - m_list.append(a); - - m_length += len; - return len; -} - -TQ_LONG KSocketBuffer::consumeBuffer(char *destbuffer, TQ_LONG maxlen, bool discard) -{ - if (maxlen == 0 || isEmpty()) - return 0; - - TQValueListIterator<TQByteArray> it = m_list.begin(), - end = m_list.end(); - TQIODevice::Offset offset = m_offset; - TQ_LONG copied = 0; - - // walk the buffer - while (it != end && maxlen) - { - // calculate how much we'll copy - size_t to_copy = (*it).size() - offset; - if (to_copy > maxlen) - to_copy = maxlen; - - // do the copying - if (destbuffer) - memcpy(destbuffer + copied, (*it).data() + offset, to_copy); - maxlen -= to_copy; - copied += to_copy; - - if ((*it).size() - offset > to_copy) - { - // we did not copy everything - offset += to_copy; - break; - } - else - { - // we copied everything - // discard this element; - offset = 0; - if (discard) - it = m_list.remove(it); - else - ++it; - } - } - - if (discard) - { - m_offset = offset; - m_length -= copied; - assert(m_length >= 0); - } - - return copied; -} - -void KSocketBuffer::clear() -{ - TQMutexLocker locker(&m_mutex); - m_list.clear(); - m_offset = 0; - m_length = 0; -} - -TQ_LONG KSocketBuffer::sendTo(KActiveSocketBase* dev, TQ_LONG len) -{ - if (len == 0 || isEmpty()) - return 0; - - TQMutexLocker locker(&m_mutex); - - TQValueListIterator<TQByteArray> it = m_list.begin(), - end = m_list.end(); - TQIODevice::Offset offset = m_offset; - TQ_LONG written = 0; - - // walk the buffer - while (it != end && (len || len == -1)) - { - // we have to write each element up to len bytes - // but since we can have several very small buffers, we can make things - // better by concatenating a few of them into a big buffer - // question is: how big should that buffer be? 2 kB should be enough - - TQ_ULONG bufsize = 1460; - if (len != -1 && len < bufsize) - bufsize = len; - TQByteArray buf(bufsize); - TQ_LONG count = 0; - - while (it != end && count + ((*it).size() - offset) <= bufsize) - { - memcpy(buf.data() + count, (*it).data() + offset, (*it).size() - offset); - count += (*it).size() - offset; - offset = 0; - ++it; - } - - // see if we can still fit more - if (count < bufsize && it != end) - { - // getting here means this buffer (*it) is larger than - // (bufsize - count) (even for count == 0). - memcpy(buf.data() + count, (*it).data() + offset, bufsize - count); - offset += bufsize - count; - count = bufsize; - } - - // now try to write those bytes - TQ_LONG wrote = dev->tqwriteBlock(buf, count); - - if (wrote == -1) - // error? - break; - - written += wrote; - if (wrote != count) - // can't fit more? - break; - } - - // discard data that has been written - // this updates m_length too - if (written) - consumeBuffer(0L, written); - - return written; -} - -TQ_LONG KSocketBuffer::receiveFrom(KActiveSocketBase* dev, TQ_LONG len) -{ - if (len == 0 || isFull()) - return 0; - - TQMutexLocker locker(&m_mutex); - - if (len == -1) - len = dev->bytesAvailable(); - if (len <= 0) - // error or closing socket - return len; - - // see if we can read that much - if (m_size != -1 && len > (m_size - m_length)) - len = m_size - m_length; - - // here, len contains just as many bytes as we're supposed to read - - // now do the reading - TQByteArray a(len); - len = dev->tqreadBlock(a.data(), len); - - if (len == -1) - // error? - return -1; - - // success - // resize the buffer and add it - a.truncate(len); - m_list.append(a); - m_length += len; - return len; -} diff --git a/kdecore/network/ksocketbuffer_p.h b/kdecore/network/ksocketbuffer_p.h deleted file mode 100644 index 0b8e96205..000000000 --- a/kdecore/network/ksocketbuffer_p.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KSOCKETBUFFER_P_H -#define KSOCKETBUFFER_P_H - -#include <tqmutex.h> -#include <tqcstring.h> -#include <tqvaluelist.h> -#include "kiobuffer.h" - -namespace KNetwork { - -class KActiveSocketBase; - - namespace Internal { - -/** - * @internal - * @class KSocketBuffer ksocketbuffer_p.h ksocketbuffer_p.h - * @brief generic socket buffering code - * - * This class implements generic buffering used by @ref KBufferedSocket. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KSocketBuffer: public KIOBufferBase -{ -public: - /** - * Default constructor. - * - * @param size the maximum size of the buffer - */ - KSocketBuffer(TQ_LONG size = -1); - - /** - * Copy constructor. - */ - KSocketBuffer(const KSocketBuffer& other); - - /** - * Virtual destructor. Frees the buffer and discards its contents. - */ - virtual ~KSocketBuffer(); - - /** - * Assignment operator. - */ - KSocketBuffer& operator=(const KSocketBuffer& other); - - /** - * Returns true if a line can be read from the buffer. - */ - virtual bool canReadLine() const; - - /** - * Reads a line from the buffer and discard it from the buffer. - */ - virtual TQCString readLine(); - - /** - * Returns the number of bytes in the buffer. Note that this is not - * the size of the buffer. - * - * @sa size - */ - virtual TQ_LONG length() const; - - /** - * Retrieves the buffer size. The value of -1 indicates that - * the buffer has no defined upper limit. - * - * @sa length for the length of the data stored - */ - virtual TQ_LONG size() const; - - /** - * Sets the size of the buffer, if allowed. - * - * @param size the maximum size, use -1 for unlimited. - * @returns true on success, false if an error occurred. - * @note if the new size is less than length(), the buffer will be truncated - */ - virtual bool setSize(TQ_LONG size); - - /** - * Adds data to the end of the buffer. - * - * @param data the data to be added - * @param len the data length, in bytes - * @returns the number of bytes added to the end of the buffer. - */ - virtual TQ_LONG feedBuffer(const char *data, TQ_LONG len); - - /** - * Clears the buffer. - */ - virtual void clear(); - - /** - * Consumes data from the beginning of the buffer. - * - * @param data where to copy the data to - * @param maxlen the maximum length to copy, in bytes - * @param discard if true, the bytes copied will be discarded - * @returns the number of bytes copied from the buffer - */ - virtual TQ_LONG consumeBuffer(char *data, TQ_LONG maxlen, bool discard = true); - - /** - * Sends at most @p len bytes of data to the I/O Device. - * - * @param device the device to which to send data - * @param len the amount of data to send; -1 to send everything - * @returns the number of bytes sent and discarded from the buffer, -1 - * indicates an error. - */ - virtual TQ_LONG sendTo(KActiveSocketBase* device, TQ_LONG len = -1); - - /** - * Tries to receive @p len bytes of data from the I/O device. - * - * @param device the device to receive from - * @param len the number of bytes to receive; -1 to read as much - * as possible - * @returns the number of bytes received and copied into the buffer, - * -1 indicates an error. - */ - virtual TQ_LONG receiveFrom(KActiveSocketBase* device, TQ_LONG len = -1); - -protected: - mutable TQMutex m_mutex; - TQValueList<TQByteArray> m_list; - TQIODevice::Offset m_offset; ///< offset of the start of data in the first element - - TQ_LONG m_size; ///< the maximum length of the buffer - mutable TQ_LONG m_length; -}; - -} } // namespace KNetwork::Internal - -#endif diff --git a/kdecore/network/ksocketdevice.cpp b/kdecore/network/ksocketdevice.cpp deleted file mode 100644 index 68651b8e2..000000000 --- a/kdecore/network/ksocketdevice.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003,2005 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <tqmap.h> - -#ifdef USE_SOLARIS -# include <sys/filio.h> -#endif -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <unistd.h> - -#ifdef HAVE_POLL -# include <sys/poll.h> -#else -# ifdef HAVE_SYS_SELECT -# include <sys/select.h> -# endif -#endif - -// Include syssocket before our local includes -#include "syssocket.h" - -#include <tqmutex.h> -#include <tqsocketnotifier.h> - -#include "kresolver.h" -#include "ksocketaddress.h" -#include "ksocketbase.h" -#include "ksocketdevice.h" -#include "ksockssocketdevice.h" - -using namespace KNetwork; - -class KNetwork::KSocketDevicePrivate -{ -public: - mutable TQSocketNotifier *input, *output, *exception; - KSocketAddress local, peer; - int af; - - inline KSocketDevicePrivate() - { - input = output = exception = 0L; - af = 0; - } -}; - - -KSocketDevice::KSocketDevice(const KSocketBase* parent) - : m_sockfd(-1), d(new KSocketDevicePrivate) -{ - setSocketDevice(this); - if (parent) - setSocketOptions(parent->socketOptions()); -} - -KSocketDevice::KSocketDevice(int fd) - : m_sockfd(fd), d(new KSocketDevicePrivate) -{ - setState(IO_Open); - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); - setSocketDevice(this); - d->af = localAddress().family(); -} - -KSocketDevice::KSocketDevice(bool, const KSocketBase* parent) - : m_sockfd(-1), d(new KSocketDevicePrivate) -{ - // do not set parent - if (parent) - setSocketOptions(parent->socketOptions()); -} - -KSocketDevice::~KSocketDevice() -{ - close(); // deletes the notifiers - unsetSocketDevice(); // prevent double deletion - delete d; -} - -bool KSocketDevice::setSocketOptions(int opts) -{ - // must call parent - TQMutexLocker locker(mutex()); - KSocketBase::setSocketOptions(opts); - - if (m_sockfd == -1) - return true; // flags are stored - - { - int fdflags = fcntl(m_sockfd, F_GETFL, 0); - if (fdflags == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; // error - } - - if (opts & Blocking) - fdflags &= ~O_NONBLOCK; - else - fdflags |= O_NONBLOCK; - - if (fcntl(m_sockfd, F_SETFL, fdflags) == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; // error - } - } - - { - int on = opts & AddressReuseable ? 1 : 0; - if (setsockopt(m_sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; // error - } - } - -#if defined(IPV6_V6ONLY) && defined(AF_INET6) - if (d->af == AF_INET6) - { - // don't try this on non-IPv6 sockets, or we'll get an error - - int on = opts & IPv6Only ? 1 : 0; - if (setsockopt(m_sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on, sizeof(on)) == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; // error - } - } -#endif - - { - int on = opts & Broadcast ? 1 : 0; - if (setsockopt(m_sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&on, sizeof(on)) == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; // error - } - } - - return true; // all went well -} - -bool KSocketDevice::open(TQ_OpenMode) -{ - resetError(); - return false; -} - -void KSocketDevice::close() -{ - resetError(); - if (m_sockfd != -1) - { - delete d->input; - delete d->output; - delete d->exception; - - d->input = d->output = d->exception = 0L; - - d->local.setFamily(AF_UNSPEC); - d->peer.setFamily(AF_UNSPEC); - - ::close(m_sockfd); - } - setState(0); - - m_sockfd = -1; -} - -bool KSocketDevice::create(int family, int type, int protocol) -{ - resetError(); - - if (m_sockfd != -1) - { - // it's already created! - setError(IO_SocketCreateError, AlreadyCreated); - return false; - } - - // no socket yet; we have to create it - m_sockfd = kde_socket(family, type, protocol); - - if (m_sockfd == -1) - { - setError(IO_SocketCreateError, NotSupported); - return false; - } - - d->af = family; - setSocketOptions(socketOptions()); - setState(IO_Open); - return true; // successfully created -} - -bool KSocketDevice::create(const KResolverEntry& address) -{ - return create(address.family(), address.socketType(), address.protocol()); -} - -bool KSocketDevice::bind(const KResolverEntry& address) -{ - resetError(); - - if (m_sockfd == -1 && !create(address)) - return false; // failed creating - - // we have a socket, so try and bind - if (kde_bind(m_sockfd, address.address(), address.length()) == -1) - { - if (errno == EADDRINUSE) - setError(IO_BindError, AddressInUse); - else if (errno == EINVAL) - setError(IO_BindError, AlreadyBound); - else - // assume the address is the cause - setError(IO_BindError, NotSupported); - return false; - } - - return true; -} - -bool KSocketDevice::listen(int backlog) -{ - if (m_sockfd != -1) - { - if (kde_listen(m_sockfd, backlog) == -1) - { - setError(IO_ListenError, NotSupported); - return false; - } - - resetError(); - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); - return true; - } - - // we don't have a socket - // can't listen - setError(IO_ListenError, NotCreated); - return false; -} - -bool KSocketDevice::connect(const KResolverEntry& address) -{ - resetError(); - - if (m_sockfd == -1 && !create(address)) - return false; // failed creating! - - if (kde_connect(m_sockfd, address.address(), address.length()) == -1) - { - if (errno == EISCONN) - return true; // we're already connected - else if (errno == EALREADY || errno == EINPROGRESS) - { - setError(IO_ConnectError, InProgress); - return true; - } - else if (errno == ECONNREFUSED) - setError(IO_ConnectError, ConnectionRefused); - else if (errno == ENETDOWN || errno == ENETUNREACH || - errno == ENETRESET || errno == ECONNABORTED || - errno == ECONNRESET || errno == EHOSTDOWN || - errno == EHOSTUNREACH) - setError(IO_ConnectError, NetFailure); - else - setError(IO_ConnectError, NotSupported); - - return false; - } - - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); - return true; // all is well -} - -KSocketDevice* KSocketDevice::accept() -{ - if (m_sockfd == -1) - { - // can't accept without a socket - setError(IO_AcceptError, NotCreated); - return 0L; - } - - struct sockaddr sa; - socklen_t len = sizeof(sa); - int newfd = kde_accept(m_sockfd, &sa, &len); - if (newfd == -1) - { - if (errno == EAGAIN || errno == EWOULDBLOCK) - setError(IO_AcceptError, WouldBlock); - else - setError(IO_AcceptError, UnknownError); - return NULL; - } - - return new KSocketDevice(newfd); -} - -bool KSocketDevice::disconnect() -{ - resetError(); - - if (m_sockfd == -1) - return false; // can't create - - KSocketAddress address; - address.setFamily(AF_UNSPEC); - if (kde_connect(m_sockfd, address.address(), address.length()) == -1) - { - if (errno == EALREADY || errno == EINPROGRESS) - { - setError(IO_ConnectError, InProgress); - return false; - } - else if (errno == ECONNREFUSED) - setError(IO_ConnectError, ConnectionRefused); - else if (errno == ENETDOWN || errno == ENETUNREACH || - errno == ENETRESET || errno == ECONNABORTED || - errno == ECONNRESET || errno == EHOSTDOWN || - errno == EHOSTUNREACH) - setError(IO_ConnectError, NetFailure); - else - setError(IO_ConnectError, NotSupported); - - return false; - } - - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); - setState(IO_Open); - return true; // all is well -} - -#ifdef USE_QT3 -TQ_LONG KSocketDevice::bytesAvailable() const -#endif -#ifdef USE_QT4 -qint64 KSocketDevice::bytesAvailable() const -#endif -{ - if (m_sockfd == -1) - return -1; // there's nothing to read in a closed socket - - int nchars; - if (ioctl(m_sockfd, FIONREAD, &nchars) == -1) - return -1; // error! - - return nchars; -} - -TQ_LONG KSocketDevice::waitForMore(int msecs, bool *timeout) -{ - if (m_sockfd == -1) - return -1; // there won't ever be anything to read... - - bool input; - if (!poll(&input, 0, 0, msecs, timeout)) - return -1; // failed polling - - return bytesAvailable(); -} - -static int do_read_common(int sockfd, char *data, TQ_ULONG maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false) -{ - socklen_t len; - if (from) - { - from->setLength(len = 128); // arbitrary length - retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len); - } - else - retval = ::recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL); - - if (retval == -1) - { - if (errno == EAGAIN || errno == EWOULDBLOCK) - return KSocketDevice::WouldBlock; - else - return KSocketDevice::UnknownError; - } - if (retval == 0) - return KSocketDevice::RemotelyDisconnected; - - if (from) - from->setLength(len); - return 0; -} - -TQT_TQIO_LONG KSocketDevice::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen) -{ - resetError(); - if (m_sockfd == -1) - return -1; - - if (maxlen == 0 || data == 0L) - return 0; // can't read - - ssize_t retval; - int err = do_read_common(m_sockfd, data, maxlen, 0L, retval); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQT_TQIO_LONG KSocketDevice::tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress &from) -{ - resetError(); - if (m_sockfd == -1) - return -1; // nothing to do here - - if (data == 0L || maxlen == 0) - return 0; // user doesn't want to read - - ssize_t retval; - int err = do_read_common(m_sockfd, data, maxlen, &from, retval); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQ_LONG KSocketDevice::peekBlock(char *data, TQ_ULONG maxlen) -{ - resetError(); - if (m_sockfd == -1) - return -1; - - if (maxlen == 0 || data == 0L) - return 0; // can't read - - ssize_t retval; - int err = do_read_common(m_sockfd, data, maxlen, 0L, retval, true); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQ_LONG KSocketDevice::peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from) -{ - resetError(); - if (m_sockfd == -1) - return -1; // nothing to do here - - if (data == 0L || maxlen == 0) - return 0; // user doesn't want to read - - ssize_t retval; - int err = do_read_common(m_sockfd, data, maxlen, &from, retval, true); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQT_TQIO_LONG KSocketDevice::tqwriteBlock(const char *data, TQT_TQIO_ULONG len) -{ - return tqwriteBlock(data, len, KSocketAddress()); -} - -TQT_TQIO_LONG KSocketDevice::tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to) -{ - resetError(); - if (m_sockfd == -1) - return -1; // can't write to unopen socket - - if (data == 0L || len == 0) - return 0; // nothing to be written - - ssize_t retval = ::sendto(m_sockfd, data, len, 0, to.address(), to.length()); - if (retval == -1) - { - if (errno == EAGAIN || errno == EWOULDBLOCK) - setError(IO_WriteError, WouldBlock); - else - setError(IO_WriteError, UnknownError); - return -1; // nothing written - } - else if (retval == 0) - setError(IO_WriteError, RemotelyDisconnected); - - return retval; -} - -KSocketAddress KSocketDevice::localAddress() const -{ - if (m_sockfd == -1) - return KSocketAddress(); // not open, empty value - - if (d->local.family() != AF_UNSPEC) - return d->local; - - socklen_t len; - KSocketAddress localAddress; - localAddress.setLength(len = 32); // arbitrary value - if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) - // error! - return d->local = KSocketAddress(); - -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - len = localAddress.address()->sa_len; -#endif - - if (len <= localAddress.length()) - { - // it has fit already - localAddress.setLength(len); - return d->local = localAddress; - } - - // no, the socket address is actually larger than we had anticipated - // call again - localAddress.setLength(len); - if (kde_getsockname(m_sockfd, localAddress.address(), &len) == -1) - // error! - return d->local = KSocketAddress(); - - return d->local = localAddress; -} - -KSocketAddress KSocketDevice::peerAddress() const -{ - if (m_sockfd == -1) - return KSocketAddress(); // not open, empty value - - if (d->peer.family() != AF_UNSPEC) - return d->peer; - - socklen_t len; - KSocketAddress peerAddress; - peerAddress.setLength(len = 32); // arbitrary value - if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) - // error! - return d->peer = KSocketAddress(); - -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - len = peerAddress.address()->sa_len; -#endif - - if (len <= peerAddress.length()) - { - // it has fit already - peerAddress.setLength(len); - return d->peer = peerAddress; - } - - // no, the socket address is actually larger than we had anticipated - // call again - peerAddress.setLength(len); - if (kde_getpeername(m_sockfd, peerAddress.address(), &len) == -1) - // error! - return d->peer = KSocketAddress(); - - return d->peer = peerAddress; -} - -KSocketAddress KSocketDevice::externalAddress() const -{ - // for normal sockets, the externally visible address is the same - // as the local address - return localAddress(); -} - -TQSocketNotifier* KSocketDevice::readNotifier() const -{ - if (d->input) - return d->input; - - TQMutexLocker locker(mutex()); - if (d->input) - return d->input; - - if (m_sockfd == -1) - { - // socket doesn't exist; can't create notifier - return 0L; - } - - return d->input = createNotifier(TQSocketNotifier::Read); -} - -TQSocketNotifier* KSocketDevice::writeNotifier() const -{ - if (d->output) - return d->output; - - TQMutexLocker locker(mutex()); - if (d->output) - return d->output; - - if (m_sockfd == -1) - { - // socket doesn't exist; can't create notifier - return 0L; - } - - return d->output = createNotifier(TQSocketNotifier::Write); -} - -TQSocketNotifier* KSocketDevice::exceptionNotifier() const -{ - if (d->exception) - return d->exception; - - TQMutexLocker locker(mutex()); - if (d->exception) - return d->exception; - - if (m_sockfd == -1) - { - // socket doesn't exist; can't create notifier - return 0L; - } - - return d->exception = createNotifier(TQSocketNotifier::Exception); -} - -bool KSocketDevice::poll(bool *input, bool *output, bool *exception, - int timeout, bool* timedout) -{ - if (m_sockfd == -1) - { - setError(IO_UnspecifiedError, NotCreated); - return false; - } - - resetError(); -#ifdef HAVE_POLL - struct pollfd fds; - fds.fd = m_sockfd; - fds.events = 0; - - if (input) - { - fds.events |= POLLIN; - *input = false; - } - if (output) - { - fds.events |= POLLOUT; - *output = false; - } - if (exception) - { - fds.events |= POLLPRI; - *exception = false; - } - - int retval = ::poll(&fds, 1, timeout); - if (retval == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; - } - if (retval == 0) - { - // timeout - if (timedout) - *timedout = true; - return true; - } - - if (input && fds.revents & POLLIN) - *input = true; - if (output && fds.revents & POLLOUT) - *output = true; - if (exception && fds.revents & POLLPRI) - *exception = true; - if (timedout) - *timedout = false; - - return true; -#else - /* - * We don't have poll(2). We'll have to make do with select(2). - */ - - fd_set readfds, writefds, exceptfds; - fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L; - - if (input) - { - preadfds = &readfds; - FD_ZERO(preadfds); - FD_SET(m_sockfd, preadfds); - *input = false; - } - if (output) - { - pwritefds = &writefds; - FD_ZERO(pwritefds); - FD_SET(m_sockfd, pwritefds); - *output = false; - } - if (exception) - { - pexceptfds = &exceptfds; - FD_ZERO(pexceptfds); - FD_SET(m_sockfd, pexceptfds); - *exception = false; - } - - int retval; - if (timeout < 0) - retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L); - else - { - // convert the milliseconds to timeval - struct timeval tv; - tv.tv_sec = timeout / 1000; - tv.tv_usec = timeout % 1000 * 1000; - - retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv); - } - - if (retval == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; - } - if (retval == 0) - { - // timeout - if (timedout) - *timedout = true; - return true; - } - - if (input && FD_ISSET(m_sockfd, preadfds)) - *input = true; - if (output && FD_ISSET(m_sockfd, pwritefds)) - *output = true; - if (exception && FD_ISSET(m_sockfd, pexceptfds)) - *exception = true; - - return true; -#endif -} - -bool KSocketDevice::poll(int timeout, bool *timedout) -{ - bool input, output, exception; - return poll(&input, &output, &exception, timeout, timedout); -} - -TQSocketNotifier* KSocketDevice::createNotifier(TQSocketNotifier::Type type) const -{ - if (m_sockfd == -1) - return 0L; - - return new TQSocketNotifier(m_sockfd, type); -} - -namespace -{ - // simple class to avoid pointer stuff - template<class T> class ptr - { - typedef T type; - type* obj; - public: - ptr() : obj(0) - { } - - ptr(const ptr<T>& other) : obj(other.obj) - { } - - ptr(type* _obj) : obj(_obj) - { } - - ~ptr() - { } - - ptr<T>& operator=(const ptr<T>& other) - { obj = other.obj; return *this; } - - ptr<T>& operator=(T* _obj) - { obj = _obj; return *this; } - - type* operator->() const { return obj; } - - operator T*() const { return obj; } - - bool isNull() const - { return obj == 0; } - }; -} - -static KSocketDeviceFactoryBase* defaultImplFactory; -static TQMutex defaultImplFactoryMutex; -typedef TQMap<int, KSocketDeviceFactoryBase* > factoryMap; -static factoryMap factories; - -KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent) -{ - KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent); - if (device != 0L) - return device; - - KSocksSocketDevice::initSocks(); - - if (defaultImplFactory) - return defaultImplFactory->create(parent); - - // the really default - return new KSocketDevice(parent); -} - -KSocketDevice* KSocketDevice::createDefault(KSocketBase* parent, int capabilities) -{ - KSocketDevice* device = dynamic_cast<KSocketDevice*>(parent); - if (device != 0L) - return device; - - TQMutexLocker locker(&defaultImplFactoryMutex); - factoryMap::ConstIterator it = factories.constBegin(); - for ( ; it != factories.constEnd(); ++it) - if ((it.key() & capabilities) == capabilities) - // found a match - return it.data()->create(parent); - - return 0L; // no default -} - -KSocketDeviceFactoryBase* -KSocketDevice::setDefaultImpl(KSocketDeviceFactoryBase* factory) -{ - TQMutexLocker locker(&defaultImplFactoryMutex); - KSocketDeviceFactoryBase* old = defaultImplFactory; - defaultImplFactory = factory; - return old; -} - -void KSocketDevice::addNewImpl(KSocketDeviceFactoryBase* factory, int capabilities) -{ - TQMutexLocker locker(&defaultImplFactoryMutex); - if (factories.contains(capabilities)) - delete factories[capabilities]; - factories.insert(capabilities, factory); -} - diff --git a/kdecore/network/ksocketdevice.h b/kdecore/network/ksocketdevice.h deleted file mode 100644 index 7c288b722..000000000 --- a/kdecore/network/ksocketdevice.h +++ /dev/null @@ -1,433 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KSOCKETDEVICE_H -#define KSOCKETDEVICE_H - -#include <tqsocketnotifier.h> -#include "ksocketbase.h" - -namespace KNetwork { - -class KSocketDevice; -class KSocketDeviceFactoryBase; - -class KSocketDevicePrivate; -/** @class KSocketDevice ksocketdevice.h ksocketdevice.h - * @brief Low-level socket functionality. - * - * This class provides low-level socket functionality. - * - * Most users will prefer "cooked" interfaces like those of @ref KStreamSocket or - * @ref KServerSocket. - * - * Descended classes from this one provide some other kinds of socket functionality, - * like proxying or specific socket types. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - */ -class KDECORE_EXPORT KSocketDevice: public KActiveSocketBase, public KPassiveSocketBase -{ -public: - /** - * Capabilities for the socket implementation. - * - * KSocketDevice-derived classes can implement certain capabilities that are not - * available in the default class. These capabilities are described by these flags. - * The default KSocketDevice class has none of these capabilities. - * - * For the negative capabilities (inabilities, the CanNot* forms), when a capability - * is not present, the implementation will default to the original behaviour. - */ - enum Capabilities - { - /** Can connect to hostnames. - * If this flag is present, the string form of @ref connect can be used. */ - CanConnectString = 0x01, - - /** Can bind to hostnames. - * If this flag is present, the string form of @ref bind can be used */ - CanBindString = 0x02, - - /** Can not bind. - * If this flag is present, this implementation cannot bind */ - CanNotBind = 0x04, - - /** Can not listen. - * If this flag is present, this implementation cannot listen */ - CanNotListen = 0x08, - - /** - * Can send multicast as well as join/leave multicast groups. - */ - CanMulticast = 0x10, - - /** - * Can not use datagrams. - * Note that this implies multicast capability not being available either. - */ - CanNotUseDatagrams = 0x20 - }; -protected: - /// The socket file descriptor. It is used throughout the implementation - /// and subclasses. - int m_sockfd; - -public: - /** - * Default constructor. - * - * The parameter is used to specify which socket this object is used as - * a device for. - */ - explicit KSocketDevice(const KSocketBase* = 0L); - - /** - * Constructs a new object around an already-open socket. - * - * Note: you should write programs that create sockets through - * the classes whenever possible. - */ - explicit KSocketDevice(int fd); - - /** - * Destructor. This closes the socket if it's open. - */ - virtual ~KSocketDevice(); - - /** - * Returns the file descriptor for this socket. - */ - inline int socket() const - { return m_sockfd; } - - /** - * Returns the set of capabilities this socket class implements. - * The set of capabilities is defined as an OR-ed mask of - * @ref Capabilities bits. - * - * The default implementation is guaranteed to always return 0. That - * is, derived implementations always return bits where they differ - * from the system standard sockets. - */ - virtual int capabilities() const - { return 0; } - - /** - * This implementation sets the options on the socket. - */ - virtual bool setSocketOptions(int opts); - - /** - * Reimplementation from TQIODevice. You should not call this function in sockets. - */ - virtual bool open(TQ_OpenMode mode); - - /** - * Closes the socket. Reimplemented from TQIODevice. - * - * Use this function to close the socket this object is holding open. - */ - virtual void close(); - - /** - * This call is not supported on sockets. Reimplemented from TQIODevice. - */ - virtual void flush() - { } - - /** - * Creates a socket but don't connect or bind anywhere. - * This function is the equivalent of the system call socket(2). - */ - virtual bool create(int family, int type, int protocol); - - /** - * @overload - * Creates a socket but don't connect or bind anywhere. - */ - bool create(const KResolverEntry& address); - - /** - * Binds this socket to the given address. - */ - virtual bool bind(const KResolverEntry& address); - - /** - * Puts this socket into listening mode. - */ - virtual bool listen(int backlog = 5); // 5 is arbitrary - - /** - * Connect to a remote host. - */ - virtual bool connect(const KResolverEntry& address); - - /** - * Accepts a new incoming connection. - * Note: this function returns a socket of type KSocketDevice. - */ - virtual KSocketDevice* accept(); - - /** - * Disconnects this socket. - */ - virtual bool disconnect(); - - /** - * Returns the number of bytes available for reading without blocking. - */ -#ifdef USE_QT3 - virtual TQ_LONG bytesAvailable() const; -#endif -#ifdef USE_QT4 - virtual qint64 bytesAvailable() const; -#endif - - /** - * Waits up to @p msecs for more data to be available on this socket. - * - * This function is a wrapper against @ref poll. This function will wait - * for any read events. - */ - virtual TQ_LONG waitForMore(int msecs, bool *timeout = 0L); - - /** - * Reads data from this socket. - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen); - - /** - * Reads data and the source address from this socket. - */ - virtual TQT_TQIO_LONG tqreadBlock(char *data, TQT_TQIO_ULONG maxlen, KSocketAddress& from); - - /** - * Peeks data in the socket. - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen); - - /** - * Peeks the data in the socket and the source address. - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from); - - /** - * Writes data to the socket. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len); - - /** - * Writes the given data to the given destination address. - */ - virtual TQT_TQIO_LONG tqwriteBlock(const char *data, TQT_TQIO_ULONG len, const KSocketAddress& to); - - /** - * Returns this socket's local address. - */ - virtual KSocketAddress localAddress() const; - - /** - * Returns this socket's peer address. If this implementation does proxying - * of some sort, this is the real external address, not the proxy's address. - */ - virtual KSocketAddress peerAddress() const; - - /** - * Returns this socket's externally visible local address. - * - * If this socket has a local address visible externally different - * from the normal local address (as returned by @ref localAddress), then - * return it. - * - * Certain implementations will use proxies and thus have externally visible - * addresses different from the local socket values. The default implementation - * returns the same value as @ref localAddress. - * - * @note This function may return an empty KSocketAddress. In that case, the - * externally visible address could/can not be determined. - */ - virtual KSocketAddress externalAddress() const; - - /** - * Returns a socket notifier for input on this socket. - * The notifier is created only when requested. Whether - * it is enabled or not depends on the implementation. - * - * This function might return NULL. - */ - TQSocketNotifier* readNotifier() const; - - /** - * Returns a socket notifier for output on this socket. - * The is created only when requested. - * - * This function might return NULL. - */ - TQSocketNotifier* writeNotifier() const; - - /** - * Returns a socket notifier for exceptional events on this socket. - * The is created only when requested. - * - * This function might return NULL. - */ - TQSocketNotifier* exceptionNotifier() const; - - /** - * Executes a poll in the socket, via select(2) or poll(2). - * The events polled are returned in the parameters pointers. - * Set any of them to NULL to disable polling of that event. - * - * On exit, @p input, @p output and @p exception will contain - * true if an event of that kind is waiting on the socket or false - * if not. If a timeout occurred, set @p timedout to true (all other - * parameters are necessarily set to false). - * - * @param input if set, turns on polling for input events - * @param output if set, turns on polling for output events - * @param exception if set, turns on polling for exceptional events - * @param timeout the time in milliseconds to wait for an event; - * 0 for no wait and any negative value to wait forever - * @param timedout on exit, will contain true if the polling timed out - * @return true if the poll call succeeded and false if an error occurred - */ - virtual bool poll(bool* input, bool* output, bool* exception = 0L, - int timeout = -1, bool* timedout = 0L); - - /** - * Shorter version to poll for any events in a socket. This call - * polls for input, output and exceptional events in a socket but - * does not return their states. This is useful if you need to wait for - * any event, but don't need to know which; or for timeouts. - * - * @param timeout the time in milliseconds to wait for an event; - * 0 for no wait and any negative value to wait forever - * @param timedout on exit, will contain true if the polling timed out - * @return true if the poll call succeeded and false if an error occurred - */ - bool poll(int timeout = -1, bool* timedout = 0L); - -protected: - /** - * Special constructor. This constructor will cause the internal - * socket device NOT to be set. Use this if your socket device class - * takes another underlying socket device. - * - * @param parent the parent, if any - */ - KSocketDevice(bool, const KSocketBase* parent = 0L); - - /** - * Creates a socket notifier of the given type. - * - * This function is called by @ref readNotifier, @ref writeNotifier and - * @ref exceptionNotifier when they need to create a socket notifier - * (i.e., the first call to those functions after the socket is open). - * After that call, those functions cache the socket notifier and will - * not need to call this function again. - * - * Reimplement this function in your derived class if your socket type - * requires a different kind of TQSocketNotifier. The return value should - * be deleteable with delete. (@ref close deletes them). - * - * @param type the socket notifier type - */ - virtual TQSocketNotifier* createNotifier(TQSocketNotifier::Type type) const; - -public: - /** - * Creates a new default KSocketDevice object given - * the parent object. - * - * The capabilities flag indicates the desired capabilities the object being - * created should possess. Those capabilities are not guaranteed: if no factory - * can provide such an object, a default object will be created. - * - * @param parent the KSocketBase parent - */ - static KSocketDevice* createDefault(KSocketBase* parent); - - /** - * @overload - * - * This will create an object only if the requested capabilities match. - * - * @param parent the parent - * @param capabilities the requested capabilities - */ - static KSocketDevice* createDefault(KSocketBase* parent, int capabilities); - - /** - * Sets the default KSocketDevice implementation to use and - * return the old factory. - * - * @param factory the factory object for the implementation - */ - static KSocketDeviceFactoryBase* setDefaultImpl(KSocketDeviceFactoryBase* factory); - - /** - * Adds a factory of KSocketDevice objects to the list, along with its - * capabilities flag. - */ - static void addNewImpl(KSocketDeviceFactoryBase* factory, int capabilities); - -private: - KSocketDevice(const KSocketDevice&); - KSocketDevice& operator=(const KSocketDevice&); - - KSocketDevicePrivate *d; -}; - -/** @internal - * This class provides functionality for creating and registering - * socket implementations. - */ -class KSocketDeviceFactoryBase -{ -public: - KSocketDeviceFactoryBase() {} - virtual ~KSocketDeviceFactoryBase() {} - - virtual KSocketDevice* create(KSocketBase*) const = 0; -}; - -/** - * This class provides functionality for creating and registering - * socket implementations. - */ -template<class Impl> -class KSocketDeviceFactory: public KSocketDeviceFactoryBase -{ -public: - KSocketDeviceFactory() {} - virtual ~KSocketDeviceFactory() {} - - virtual KSocketDevice* create(KSocketBase* parent) const - { return new Impl(parent); } -}; - -} // namespaces - -#endif diff --git a/kdecore/network/ksockssocketdevice.cpp b/kdecore/network/ksockssocketdevice.cpp deleted file mode 100644 index 3432ef84f..000000000 --- a/kdecore/network/ksockssocketdevice.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2004 Thiago Macieira <thiago.macieira@kdemail.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <config.h> - -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> - -#if defined(HAVE_UNISTD_H) -#include <unistd.h> -#endif - -#ifdef __CYGWIN__ -#undef kde_socklen_t -#define kde_socklen_t ksocklen_t -#endif - -#include "kapplication.h" - -#include "ksocks.h" -#include "ksocketaddress.h" -#include "kresolver.h" -#include "ksockssocketdevice.h" - -using namespace KNetwork; - -// constructor -// nothing to do -KSocksSocketDevice::KSocksSocketDevice(const KSocketBase* obj) - : KSocketDevice(obj) -{ -} - -// constructor with argument -// nothing to do -KSocksSocketDevice::KSocksSocketDevice(int fd) - : KSocketDevice(fd) -{ -} - -// destructor -// also nothing to do -KSocksSocketDevice::~KSocksSocketDevice() -{ -} - -// returns the capabilities -int KSocksSocketDevice::capabilities() const -{ - return 0; // can do everything! -} - -// From here on, the code is almost exactly a copy of KSocketDevice -// the differences are the use of KSocks where appropriate - -bool KSocksSocketDevice::bind(const KResolverEntry& address) -{ - resetError(); - - if (m_sockfd == -1 && !create(address)) - return false; // failed creating - - // we have a socket, so try and bind - if (KSocks::self()->bind(m_sockfd, address.address(), address.length()) == -1) - { - if (errno == EADDRINUSE) - setError(IO_BindError, AddressInUse); - else if (errno == EINVAL) - setError(IO_BindError, AlreadyBound); - else - // assume the address is the cause - setError(IO_BindError, NotSupported); - return false; - } - - return true; -} - - -bool KSocksSocketDevice::listen(int backlog) -{ - if (m_sockfd != -1) - { - if (KSocks::self()->listen(m_sockfd, backlog) == -1) - { - setError(IO_ListenError, NotSupported); - return false; - } - - resetError(); - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); - setState(IO_Open); - return true; - } - - // we don't have a socket - // can't listen - setError(IO_ListenError, NotCreated); - return false; -} - -bool KSocksSocketDevice::connect(const KResolverEntry& address) -{ - resetError(); - - if (m_sockfd == -1 && !create(address)) - return false; // failed creating! - - int retval; - if (KSocks::self()->hasWorkingAsyncConnect()) - retval = KSocks::self()->connect(m_sockfd, address.address(), - address.length()); - else - { - // work around some SOCKS implementation bugs - // we will do a *synchronous* connection here! - // FIXME: KDE4, write a proper SOCKS implementation - bool isBlocking = blocking(); - setBlocking(true); - retval = KSocks::self()->connect(m_sockfd, address.address(), - address.length()); - setBlocking(isBlocking); - } - - if (retval == -1) - { - if (errno == EISCONN) - return true; // we're already connected - else if (errno == EALREADY || errno == EINPROGRESS) - { - setError(IO_ConnectError, InProgress); - return true; - } - else if (errno == ECONNREFUSED) - setError(IO_ConnectError, ConnectionRefused); - else if (errno == ENETDOWN || errno == ENETUNREACH || - errno == ENETRESET || errno == ECONNABORTED || - errno == ECONNRESET || errno == EHOSTDOWN || - errno == EHOSTUNREACH) - setError(IO_ConnectError, NetFailure); - else - setError(IO_ConnectError, NotSupported); - - return false; - } - - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite); - setState(IO_Open); - return true; // all is well -} - -KSocksSocketDevice* KSocksSocketDevice::accept() -{ - if (m_sockfd == -1) - { - // can't accept without a socket - setError(IO_AcceptError, NotCreated); - return 0L; - } - - struct sockaddr sa; - kde_socklen_t len = sizeof(sa); - int newfd = KSocks::self()->accept(m_sockfd, &sa, &len); - if (newfd == -1) - { - if (errno == EAGAIN || errno == EWOULDBLOCK) - setError(IO_AcceptError, WouldBlock); - else - setError(IO_AcceptError, UnknownError); - return NULL; - } - - return new KSocksSocketDevice(newfd); -} - -static int socks_read_common(int sockfd, char *data, TQ_ULONG maxlen, KSocketAddress* from, ssize_t &retval, bool peek = false) -{ - kde_socklen_t len; - if (from) - { - from->setLength(len = 128); // arbitrary length - retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, from->address(), &len); - } - else - retval = KSocks::self()->recvfrom(sockfd, data, maxlen, peek ? MSG_PEEK : 0, NULL, NULL); - - if (retval == -1) - { - if (errno == EAGAIN || errno == EWOULDBLOCK) - return KSocketDevice::WouldBlock; - else - return KSocketDevice::UnknownError; - } - - if (from) - from->setLength(len); - return 0; -} - -TQ_LONG KSocksSocketDevice::tqreadBlock(char *data, TQ_ULONG maxlen) -{ - resetError(); - if (m_sockfd == -1) - return -1; - - if (maxlen == 0 || data == 0L) - return 0; // can't read - - ssize_t retval; - int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQ_LONG KSocksSocketDevice::tqreadBlock(char *data, TQ_ULONG maxlen, KSocketAddress &from) -{ - resetError(); - if (m_sockfd == -1) - return -1; // nothing to do here - - if (data == 0L || maxlen == 0) - return 0; // user doesn't want to read - - ssize_t retval; - int err = socks_read_common(m_sockfd, data, maxlen, &from, retval); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQ_LONG KSocksSocketDevice::peekBlock(char *data, TQ_ULONG maxlen) -{ - resetError(); - if (m_sockfd == -1) - return -1; - - if (maxlen == 0 || data == 0L) - return 0; // can't read - - ssize_t retval; - int err = socks_read_common(m_sockfd, data, maxlen, 0L, retval, true); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQ_LONG KSocksSocketDevice::peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from) -{ - resetError(); - if (m_sockfd == -1) - return -1; // nothing to do here - - if (data == 0L || maxlen == 0) - return 0; // user doesn't want to read - - ssize_t retval; - int err = socks_read_common(m_sockfd, data, maxlen, &from, retval, true); - - if (err) - { - setError(IO_ReadError, static_cast<SocketError>(err)); - return -1; - } - - return retval; -} - -TQ_LONG KSocksSocketDevice::tqwriteBlock(const char *data, TQ_ULONG len) -{ - return tqwriteBlock(data, len, KSocketAddress()); -} - -TQ_LONG KSocksSocketDevice::tqwriteBlock(const char *data, TQ_ULONG len, const KSocketAddress& to) -{ - resetError(); - if (m_sockfd == -1) - return -1; // can't write to unopen socket - - if (data == 0L || len == 0) - return 0; // nothing to be written - - ssize_t retval = KSocks::self()->sendto(m_sockfd, data, len, 0, to.address(), to.length()); - if (retval == -1) - { - if (errno == EAGAIN || errno == EWOULDBLOCK) - setError(IO_WriteError, WouldBlock); - else - setError(IO_WriteError, UnknownError); - return -1; // nothing written - } - - return retval; -} - -KSocketAddress KSocksSocketDevice::localAddress() const -{ - if (m_sockfd == -1) - return KSocketAddress(); // not open, empty value - - kde_socklen_t len; - KSocketAddress localAddress; - localAddress.setLength(len = 32); // arbitrary value - if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1) - // error! - return KSocketAddress(); - - if (len <= localAddress.length()) - { - // it has fit already - localAddress.setLength(len); - return localAddress; - } - - // no, the socket address is actually larger than we had anticipated - // call again - localAddress.setLength(len); - if (KSocks::self()->getsockname(m_sockfd, localAddress.address(), &len) == -1) - // error! - return KSocketAddress(); - - return localAddress; -} - -KSocketAddress KSocksSocketDevice::peerAddress() const -{ - if (m_sockfd == -1) - return KSocketAddress(); // not open, empty value - - kde_socklen_t len; - KSocketAddress peerAddress; - peerAddress.setLength(len = 32); // arbitrary value - if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1) - // error! - return KSocketAddress(); - - if (len <= peerAddress.length()) - { - // it has fit already - peerAddress.setLength(len); - return peerAddress; - } - - // no, the socket address is actually larger than we had anticipated - // call again - peerAddress.setLength(len); - if (KSocks::self()->getpeername(m_sockfd, peerAddress.address(), &len) == -1) - // error! - return KSocketAddress(); - - return peerAddress; -} - -KSocketAddress KSocksSocketDevice::externalAddress() const -{ - // return empty, indicating unknown external address - return KSocketAddress(); -} - -bool KSocksSocketDevice::poll(bool *input, bool *output, bool *exception, - int timeout, bool *timedout) -{ - if (m_sockfd == -1) - { - setError(IO_UnspecifiedError, NotCreated); - return false; - } - - resetError(); - fd_set readfds, writefds, exceptfds; - fd_set *preadfds = 0L, *pwritefds = 0L, *pexceptfds = 0L; - - if (input) - { - preadfds = &readfds; - FD_ZERO(preadfds); - FD_SET(m_sockfd, preadfds); - *input = false; - } - if (output) - { - pwritefds = &writefds; - FD_ZERO(pwritefds); - FD_SET(m_sockfd, pwritefds); - *output = false; - } - if (exception) - { - pexceptfds = &exceptfds; - FD_ZERO(pexceptfds); - FD_SET(m_sockfd, pexceptfds); - *exception = false; - } - - int retval; - if (timeout < 0) - retval = KSocks::self()->select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, 0L); - else - { - // convert the milliseconds to timeval - struct timeval tv; - tv.tv_sec = timeout / 1000; - tv.tv_usec = timeout % 1000 * 1000; - - retval = select(m_sockfd + 1, preadfds, pwritefds, pexceptfds, &tv); - } - - if (retval == -1) - { - setError(IO_UnspecifiedError, UnknownError); - return false; - } - if (retval == 0) - { - // timeout - if (timedout) - *timedout = true; - return true; - } - - if (input && FD_ISSET(m_sockfd, preadfds)) - *input = true; - if (output && FD_ISSET(m_sockfd, pwritefds)) - *output = true; - if (exception && FD_ISSET(m_sockfd, pexceptfds)) - *exception = true; - - return true; -} - -void KSocksSocketDevice::initSocks() -{ - static bool init = false; - - if (init) - return; - - if (kapp == 0L) - return; // no KApplication, so don't initialise - // this should, however, test for KInstance - - init = true; - - if (KSocks::self()->hasSocks()) - delete KSocketDevice::setDefaultImpl(new KSocketDeviceFactory<KSocksSocketDevice>); -} - -#if 0 -static bool register() -{ - KSocketDevice::addNewImpl(new KSocketDeviceFactory<KSocksSocketDevice>, 0); -} - -static bool register = registered(); -#endif diff --git a/kdecore/network/ksockssocketdevice.h b/kdecore/network/ksockssocketdevice.h deleted file mode 100644 index 4db5d1e01..000000000 --- a/kdecore/network/ksockssocketdevice.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2004 Thiago Macieira <thiago.macieira@kdemail.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KSOCKSSOCKETDEVICE_H -#define KSOCKSSOCKETDEVICE_H - -#include "ksocketdevice.h" - -namespace KNetwork { - -/** - * @class KSocksSocketDevice ksockssocketdevice.h ksockssocketdevice.h - * @brief The low-level class for SOCKS proxying. - * - * This class reimplements several functions from @ref KSocketDevice in order - * to implement SOCKS support. - * - * This works by using KSocks. - * - * @author Thiago Macieira <thiago.macieira@kdemail.net> - * - * @warning This code is untested! - */ -class KDECORE_EXPORT KSocksSocketDevice: public KSocketDevice -{ -public: - /** - * Constructor. - */ - KSocksSocketDevice(const KSocketBase* = 0L); - - /** - * Construct from a file descriptor. - */ - explicit KSocksSocketDevice(int fd); - - /** - * Destructor. - */ - virtual ~KSocksSocketDevice(); - - /** - * Sets our capabilities. - */ - virtual int capabilities() const; - - /** - * Overrides binding. - */ - virtual bool bind(const KResolverEntry& address); - - /** - * Overrides listening. - */ - virtual bool listen(int backlog); - - /** - * Overrides connection. - */ - virtual bool connect(const KResolverEntry& address); - - /** - * Overrides accepting. The return type is specialised. - */ - virtual KSocksSocketDevice* accept(); - - /** - * Overrides reading. - */ - virtual TQ_LONG tqreadBlock(char *data, TQ_ULONG maxlen); - virtual TQ_LONG tqreadBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from); - - /** - * Overrides peeking. - */ - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen); - virtual TQ_LONG peekBlock(char *data, TQ_ULONG maxlen, KSocketAddress& from); - - /** - * Overrides writing. - */ - virtual TQ_LONG tqwriteBlock(const char *data, TQ_ULONG len); - virtual TQ_LONG tqwriteBlock(const char *data, TQ_ULONG len, const KSocketAddress& to); - - /** - * Overrides getting socket address. - */ - virtual KSocketAddress localAddress() const; - - /** - * Overrides getting peer address. - */ - virtual KSocketAddress peerAddress() const; - - /** - * Overrides getting external address. - */ - virtual KSocketAddress externalAddress() const; - - /** - * Overrides polling. - */ - virtual bool poll(bool* input, bool* output, bool* exception = 0L, - int timeout = -1, bool* timedout = 0L); - -private: - static void initSocks(); - friend class KSocketDevice; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/ksrvresolverworker.cpp b/kdecore/network/ksrvresolverworker.cpp deleted file mode 100644 index 2ec5bb4bf..000000000 --- a/kdecore/network/ksrvresolverworker.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2005 Thiago Macieira <thiago@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <config.h> - -#include "ksrvresolverworker_p.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <stdlib.h> - -#include <tqapplication.h> -#include <tqevent.h> - -using namespace KNetwork; -using namespace KNetwork::Internal; - -namespace -{ - struct KSrvStartEvent: public TQCustomEvent - { - inline KSrvStartEvent() : TQCustomEvent(TQEvent::User) { } - }; -} - -static void sortPriorityClass(KSrvResolverWorker::PriorityClass&) -{ - // do nothing -} - -bool KSrvResolverWorker::preprocess() -{ - // check if the resolver flags mention SRV-based lookup - if ((flags() & (KResolver::NoSrv | KResolver::UseSrv)) != KResolver::UseSrv) - return false; - - TQString node = nodeName(); - if (node.find('%') != -1) - node.truncate(node.find('%')); - - if (node.isEmpty() || node == TQString::tqfromLatin1("*") || - node == TQString::tqfromLatin1("localhost")) - return false; // empty == localhost - - encodedName = KResolver::domainToAscii(node); - if (encodedName.isNull()) - return false; - - // we only work with Internet-based families - if ((familyMask() & KResolver::InternetFamily) == 0) - return false; - - // SRV-based resolution only works if the service isn't numeric - bool ok; - serviceName().toUInt(&ok); - if (ok) - return false; // it is numeric - - // check the protocol for something we know - TQCString protoname; - int sockettype = socketType(); - if (!protocolName().isEmpty()) - protoname = protocolName(); - else if (protocol() != 0) - { - TQStrList names = KResolver::protocolName(protocol()); - names.setAutoDelete(true); - if (names.isEmpty()) - return false; - - protoname = "_"; - protoname += names.tqat(0); - } - else if (sockettype == SOCK_STREAM || sockettype == 0) - protoname = "_tcp"; - else if (sockettype == SOCK_DGRAM) - protoname = "_udp"; - else - return false; // unknown protocol and socket type - - encodedName.prepend("."); - encodedName.prepend(protoname); - encodedName.prepend("."); - encodedName.prepend(serviceName().latin1()); - encodedName.prepend("_"); - - // looks like something we could process - return true; -} - -bool KSrvResolverWorker::run() -{ - sem = new TQSemaphore(1); - // zero out - sem->tryAccess(sem->available()); - - TQApplication::postEvent(this, new KSrvStartEvent); - - // block - (*sem)++; - delete sem; - sem = 0L; - - if (rawResults.isEmpty()) - { - // normal lookup - KResolver *r = new KResolver(nodeName(), serviceName()); - r->setFlags(flags() | KResolver::NoSrv); - r->setFamily(familyMask()); - r->setSocketType(socketType()); - r->setProtocol(protocol(), protocolName()); - - enqueue(r); - - Entry e; - PriorityClass cl; - e.resolver = r; - cl.entries.append(e); - myResults[0] = cl; - - return true; - } - else if (rawResults.count() == 1 && rawResults.first().name == ".") - { - // no name - setError(KResolver::NoName); - finished(); - return true; - } - else - { - // now process the results - TQValueList<TQDns::Server>::ConstIterator it = rawResults.begin(); - while (it != rawResults.end()) - { - const TQDns::Server& srv = *it; - PriorityClass& r = myResults[srv.priority]; - r.totalWeight += srv.weight; - - Entry e; - e.name = srv.name; - e.port = srv.port; - e.weight = srv.weight; - e.resolver = 0L; - r.entries.append(e); - - ++it; - } - rawResults.clear(); // free memory - - Results::Iterator mapit; - for (mapit = myResults.begin(); mapit != myResults.end(); ++mapit) - { - // sort the priority - sortPriorityClass(*mapit); - - TQValueList<Entry>& entries = (*mapit).entries; - - // start the resolvers - for (TQValueList<Entry>::Iterator it = entries.begin(); - it != entries.end(); ++it) - { - Entry &e = *it; - - KResolver* r = new KResolver(e.name, TQString::number(e.port)); - r->setFlags(flags() | KResolver::NoSrv); - r->setFamily(familyMask()); - r->setSocketType(socketType()); - r->setProtocol(protocol(), protocolName()); - - enqueue(r); - e.resolver = r; - } - } - - return true; - } -} - -bool KSrvResolverWorker::postprocess() -{ - setError(KResolver::NoName); - if (myResults.isEmpty()) - return false; - - Results::Iterator mapit, mapend; - for (mapit = myResults.begin(), mapend = myResults.end(); - mapit != mapend; ++mapit) - { - TQValueList<Entry>::Iterator it = (*mapit).entries.begin(), - end = (*mapit).entries.end(); - for ( ; it != end; ++it) - { - Entry &e = *it; - KResolverResults r = e.resolver->results(); - if (r.isEmpty() && results.isEmpty()) - setError(r.error(), r.systemError()); - else - { - setError(KResolver::NoError); - results += r; - } - } - } - - finished(); - return true; -} - -void KSrvResolverWorker::customEvent(TQCustomEvent*) -{ - dns = new TQDns(TQString::tqfromLatin1(encodedName), TQDns::Srv); - TQObject::connect(dns, TQT_SIGNAL(resultsReady()), this, TQT_SLOT(dnsResultsReady())); -} - -void KSrvResolverWorker::dnsResultsReady() -{ - (*sem)--; - rawResults = dns->servers(); - dns->deleteLater(); - dns = 0L; -} - -namespace KNetwork -{ - namespace Internal - { - - void initSrvWorker() KDE_NO_EXPORT; - void initSrvWorker() - { - if (getenv("KDE_NO_SRV") != NULL) - return; - - KResolverWorkerFactoryBase::registerNewWorker(new KResolverWorkerFactory<KSrvResolverWorker>); - } - - } -} - -#include "ksrvresolverworker_p.moc" diff --git a/kdecore/network/ksrvresolverworker_p.h b/kdecore/network/ksrvresolverworker_p.h deleted file mode 100644 index 293308544..000000000 --- a/kdecore/network/ksrvresolverworker_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2005 Thiago Macieira <thiago@kde.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef KSRVRESOLVERWORKER_P_H -#define KSRVRESOLVERWORKER_P_H - -#include <tqobject.h> -#include <tqdns.h> -#include <tqsemaphore.h> -#include <tqvaluelist.h> -#include <tqdict.h> -#include "kresolver.h" -#include "kresolverworkerbase.h" - -class TQCustomEvent; - -namespace KNetwork -{ - namespace Internal - { - /** - * @internal - * This class implements SRV-based resolution - */ - class KSrvResolverWorker: public TQObject, - public KNetwork::KResolverWorkerBase - { - Q_OBJECT - TQ_OBJECT - - public: - struct Entry - { - TQString name; - TQ_UINT16 port; - TQ_UINT16 weight; - KNetwork::KResolver* resolver; - }; - - struct PriorityClass - { - PriorityClass() : totalWeight(0) { } - - TQValueList<Entry> entries; - TQ_UINT16 totalWeight; - }; - - private: - TQDns *dns; - TQValueList<TQDns::Server> rawResults; - TQCString encodedName; - TQSemaphore *sem; - - typedef TQMap<TQ_UINT16, PriorityClass> Results; - Results myResults; - - public: - virtual bool preprocess(); - virtual bool run(); - virtual bool postprocess(); - - virtual void customEvent(TQCustomEvent*); - - public slots: - void dnsResultsReady(); - }; - } -} - -#endif diff --git a/kdecore/network/kstreamsocket.cpp b/kdecore/network/kstreamsocket.cpp deleted file mode 100644 index 3861a4e09..000000000 --- a/kdecore/network/kstreamsocket.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include <config.h> - -#include <tqsocketnotifier.h> -#include <tqdatetime.h> -#include <tqtimer.h> -#include <tqguardedptr.h> - -#include "ksocketaddress.h" -#include "kresolver.h" -#include "ksocketdevice.h" -#include "kstreamsocket.h" - -using namespace KNetwork; - -class KNetwork::KStreamSocketPrivate -{ -public: - KResolverResults::ConstIterator local, peer; - TQTime startTime; - TQTimer timer; - - int timeout; - - inline KStreamSocketPrivate() - : timeout(0) - { } -}; - -KStreamSocket::KStreamSocket(const TQString& node, const TQString& service, - TQObject* parent, const char *name) - : KClientSocketBase(parent, name), d(new KStreamSocketPrivate) -{ - peerResolver().setNodeName(node); - peerResolver().setServiceName(service); - peerResolver().setFamily(KResolver::KnownFamily); - localResolver().setFamily(KResolver::KnownFamily); - - setSocketOptions(socketOptions() & ~Blocking); - - TQObject::connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeoutSlot())); -} - -KStreamSocket::~KStreamSocket() -{ - delete d; - // KClientSocketBase's destructor closes the socket -} - -int KStreamSocket::timeout() const -{ - return d->timeout; -} - -int KStreamSocket::remainingTimeout() const -{ - if (state() != Connecting) - return timeout(); - if (timeout() <= 0) - return 0; - - return timeout() - d->startTime.elapsed(); -} - -void KStreamSocket::setTimeout(int msecs) -{ - d->timeout = msecs; - - if (state() == Connecting) - d->timer.changeInterval(msecs); -} - -bool KStreamSocket::bind(const TQString& node, const TQString& service) -{ - if (state() != Idle) - return false; - - if (!node.isNull()) - localResolver().setNodeName(node); - if (!service.isNull()) - localResolver().setServiceName(service); - return true; -} - -bool KStreamSocket::connect(const TQString& node, const TQString& service) -{ - if (state() == Connected) - return true; // already connected - - if (state() > Connected) - return false; // can't do much here - - if (!node.isNull()) - peerResolver().setNodeName(node); - if (!service.isNull()) - peerResolver().setServiceName(service); - - if (state() == Connecting && !blocking()) - { - setError(IO_ConnectError, InProgress); - emit gotError(InProgress); - return true; // we're already connecting - } - - if (state() < HostFound) - { - // connection hasn't started yet - if (!blocking()) - { - QObject::connect(this, TQT_SIGNAL(hostFound()), TQT_SLOT(hostFoundSlot())); - return lookup(); - } - - // blocking mode - if (!lookup()) - return false; // lookup failure - } - - /* - * lookup results are available here - */ - - if (timeout() > 0) - { - if (!blocking() && !d->timer.isActive()) - d->timer.start(timeout(), true); - else - { - // blocking connection with timeout - // this must be handled as a special case because it requires a - // non-blocking socket - - d->timer.stop(); // no need for a timer here - - socketDevice()->setBlocking(false); - while (true) - { - connectionEvent(); - if (state() < Connecting) - return false; // error connecting - if (state() == Connected) - return true; // connected! - - if (remainingTimeout() <= 0) - { - // we've timed out - timeoutSlot(); - return false; - } - - if (socketDevice()->error() == InProgress) - { - bool timedout; - socketDevice()->poll(remainingTimeout(), &timedout); - if (timedout) - { - timeoutSlot(); - return false; - } - } - } - } - } - - connectionEvent(); - return error() == NoError; -} - -bool KStreamSocket::connect(const KResolverEntry& entry) -{ - return KClientSocketBase::connect(entry); -} - -void KStreamSocket::hostFoundSlot() -{ - QObject::disconnect(this, TQT_SLOT(hostFoundSlot())); - if (timeout() > 0) - d->timer.start(timeout(), true); - TQTimer::singleShot(0, this, TQT_SLOT(connectionEvent())); -} - -void KStreamSocket::connectionEvent() -{ - if (state() != HostFound && state() != Connecting) - return; // nothing to do - - const KResolverResults& peer = peerResults(); - if (state() == HostFound) - { - d->startTime.start(); - - setState(Connecting); - emit stateChanged(Connecting); - d->peer = peer.begin(); - d->local = localResults().begin(); // just to be on the safe side - } - - while (d->peer != peer.end()) - { - const KResolverEntry &r = *d->peer; - - if (socketDevice()->socket() != -1) - { - // we have an existing file descriptor - // this means that we've got activity in it (connection result) - if (socketDevice()->connect(r) && socketDevice()->error() == NoError) - { - // yes, it did connect! - connectionSucceeded(r); - return; - } - else if (socketDevice()->error() == InProgress) - // nope, still in progress - return; - - // no, the socket failed to connect - copyError(); - socketDevice()->close(); - ++d->peer; - continue; - } - - // try to bind - if (!bindLocallyFor(r)) - { - // could not find a matching family - ++d->peer; - continue; - } - - { - bool skip = false; - emit aboutToConnect(r, skip); - if (skip) - { - ++d->peer; - continue; - } - } - - if (socketDevice()->connect(r) || socketDevice()->error() == InProgress) - { - // socket is attempting to connect - if (socketDevice()->error() == InProgress) - { - TQSocketNotifier *n = socketDevice()->readNotifier(); - TQObject::connect(n, TQT_SIGNAL(activated(int)), - this, TQT_SLOT(connectionEvent())); - n->setEnabled(true); - - n = socketDevice()->writeNotifier(); - TQObject::connect(n, TQT_SIGNAL(activated(int)), - this, TQT_SLOT(connectionEvent())); - n->setEnabled(true); - - return; // wait for activity - } - - // socket has connected - connectionSucceeded(r); - return; - } - - // connection failed - // try next - copyError(); - socketDevice()->close(); - ++d->peer; - } - - // that was the last item - socketDevice()->setSocketOptions(socketOptions()); - setState(Idle); - emit stateChanged(Idle); - emit gotError(error()); - return; -} - -void KStreamSocket::timeoutSlot() -{ - if (state() != Connecting) - return; - - // halt the connections - socketDevice()->close(); // this also kills the notifiers - - setError(IO_TimeOutError, Timeout); - setState(HostFound); - emit stateChanged(HostFound); - - TQGuardedPtr<KStreamSocket> that = this; - emit gotError(Timeout); - if (!that.isNull()) - emit timedOut(); -} - -bool KStreamSocket::bindLocallyFor(const KResolverEntry& peer) -{ - const KResolverResults& local = localResults(); - - if (local.isEmpty()) - // user doesn't want to bind to any specific local address - return true; - - bool foundone = false; - // scan the local resolution for a matching family - for (d->local = local.begin(); d->local != local.end(); ++d->local) - if ((*d->local).family() == peer.family()) - { - // found a suitable address! - foundone = true; - - if (socketDevice()->bind(*d->local)) - return true; - } - - if (!foundone) - { - // found nothing - setError(IO_BindError, NotSupported); - emit gotError(NotSupported); - } - else - copyError(); - return false; -} - -void KStreamSocket::connectionSucceeded(const KResolverEntry& peer) -{ - TQObject::disconnect(socketDevice()->readNotifier(), 0, this, TQT_SLOT(connectionEvent())); - TQObject::disconnect(socketDevice()->writeNotifier(), 0, this, TQT_SLOT(connectionEvent())); - - resetError(); - setFlags(IO_Sequential | IO_Raw | IO_ReadWrite | IO_Open | IO_Async); - setState(Connected); - socketDevice()->setSocketOptions(socketOptions()); - d->timer.stop(); - emit stateChanged(Connected); - - if (!localResults().isEmpty()) - emit bound(*d->local); - emit connected(peer); -} - -#include "kstreamsocket.moc" diff --git a/kdecore/network/kstreamsocket.h b/kdecore/network/kstreamsocket.h deleted file mode 100644 index 9b58bf23a..000000000 --- a/kdecore/network/kstreamsocket.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago@kde.org> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KSTREAMSOCKET_H -#define KSTREAMSOCKET_H - -#include <tqstring.h> - -#include "kclientsocketbase.h" - -/** A namespace to store all networking-related (socket) classes. */ -namespace KNetwork { - -class KResolverEntry; -class KResolverResults; -class KServerSocket; -class KBufferedSocket; - -class KStreamSocketPrivate; -/** @class KStreamSocket kstreamsocket.h kstreamsocket.h - * @brief Simple stream socket - * - * This class provides functionality to creating unbuffered, stream - * sockets. In the case of Internet (IP) sockets, this class creates and - * uses TCP/IP sockets. - * - * Objects of this class start, by default, on non-blocking mode. Call - * setBlocking if you wish to change that. - * - * KStreamSocket objects are thread-safe and can be used in auxiliary - * threads (i.e., not the thread in which the Qt event loop runs in). - * Note that KBufferedSocket cannot be used reliably in an auxiliary thread. - * - * Sample usage: - * \code - * TQByteArray httpGet(const TQString& hostname) - * { - * KStreamSocket socket(hostname, "http"); - * if (!socket.connect()) - * return TQByteArray(); - * TQByteArray data = socket.readAll(); - * return data; - * } - * \endcode - * - * Here's another sample, showing asynchronous operation: - * \code - * DataRetriever::DataRetriever(const TQString& hostname, const TQString& port) - * : socket(hostname, port) - * { - * // connect signals to our slots - * TQObject::connect(&socket, TQT_SIGNAL(connected(const KResolverEntry&)), - * this, TQT_SLOT(slotSocketConnected())); - * TQObject::connect(&socket, TQT_SIGNAL(gotError(int)), - * this, TQT_SLOT(slotSocketError(int))); - * TQObject::connect(&socket, TQT_SIGNAL(readyRead()), - * this, TQT_SLOT(slotSocketReadyToRead())); - * TQObject::connect(&socket, TQT_SIGNAL(readyWrite()), - * this, TQT_SLOT(slotSocketReadyToWrite())); - * - * // set non-blocking mode in order to work asynchronously - * socket.setBlocking(false); - * - * // turn on signal emission - * socket.enableRead(true); - * socket.enableWrite(true); - * - * // start connecting - * socket.connect(); - * } - * \endcode - * - * @see KNetwork::KBufferedSocket, KNetwork::KServerSocket - * @author Thiago Macieira <thiago@kde.org> - */ -class KDECORE_EXPORT KStreamSocket: public KClientSocketBase -{ - Q_OBJECT - TQ_OBJECT - -public: - /** - * Default constructor. - * - * @param node destination host - * @param service destination service to connect to - * @param parent the parent TQObject object - * @param name name for this object - */ - KStreamSocket(const TQString& node = TQString::null, const TQString& service = TQString::null, - TQObject* parent = 0L, const char *name = 0L); - - /** - * Destructor. This closes the socket. - */ - virtual ~KStreamSocket(); - - /** - * Retrieves the timeout value (in milliseconds). - */ - int timeout() const; - - /** - * Retrieves the remaining timeout time (in milliseconds). This value - * equals @ref timeout() if there's no connection in progress. - */ - int remainingTimeout() const; - - /** - * Sets the timeout value. Setting this value while a connection attempt - * is in progress will reset the timer. - * - * Please note that the timeout value is valid for the connection attempt - * only. No other operations are timed against this value -- including the - * name lookup associated. - * - * @param msecs the timeout value in milliseconds - */ - void setTimeout(int msecs); - - /** - * Binds this socket to the given nodename and service, - * or use the default ones if none are given. In order to bind to a service - * and allow the operating system to choose the interface, set @p node to - * TQString::null. - * - * Reimplemented from KClientSocketBase. - * - * Upon successful binding, the @ref bound signal will be - * emitted. If an error is found, the @ref gotError - * signal will be emitted. - * - * @note Due to the internals of the name lookup and binding - * mechanism, some (if not most) implementations of this function - * do not actually bind the socket until the connection - * is requested (see @ref connect). They only set the values - * for future reference. - * - * This function returns true on success. - * - * @param node the nodename - * @param service the service - */ - virtual bool bind(const TQString& node = TQString::null, - const TQString& service = TQString::null); - - /** - * Reimplemented from KClientSocketBase. Connect this socket to this - * specific address. - * - * Unlike @ref bind(const TQString&, const TQString&) above, this function - * really does bind the socket. No lookup is performed. The @ref bound - * signal will be emitted. - */ - virtual bool bind(const KResolverEntry& entry) - { return KClientSocketBase::bind(entry); } - - /** - * Reimplemented from KClientSocketBase. - * - * Attempts to connect to the these hostname and service, - * or use the default ones if none are given. If a connection attempt - * is already in progress, check on its state and set the error status - * (NoError, meaning the connection is completed, or InProgress). - * - * If the blocking mode for this object is on, this function will only - * return when all the resolved peer addresses have been tried or when - * a connection is established. - * - * Upon successfully connecting, the @ref connected signal - * will be emitted. If an error is found, the @ref gotError - * signal will be emitted. - * - * This function also implements timeout handling. - * - * @param node the remote node to connect to - * @param service the service on the remote node to connect to - */ - virtual bool connect(const TQString& node = TQString::null, - const TQString& service = TQString::null); - - /** - * Unshadowing from KClientSocketBase. - */ - virtual bool connect(const KResolverEntry& entry); - -signals: - /** - * This signal is emitted when a connection timeout occurs. - */ - void timedOut(); - -private slots: - void hostFoundSlot(); - void connectionEvent(); - void timeoutSlot(); - -private: - /** - * @internal - * If the user requested local bind before connection, bind the socket to one - * suitable address and return true. Also sets d->local to the address used. - * - * Return false in case of error. - */ - bool bindLocallyFor(const KResolverEntry& peer); - - /** - * @internal - * Finishes the connection process by setting internal values and - * emitting the proper signals. - * - * Note: assumes d->local iterator points to the address that we bound - * to. - */ - void connectionSucceeded(const KResolverEntry& peer); - - KStreamSocket(const KStreamSocket&); - KStreamSocket& operator=(const KStreamSocket&); - - KStreamSocketPrivate *d; - - friend class KServerSocket; - friend class KBufferedSocket; -}; - -} // namespace KNetwork - -#endif diff --git a/kdecore/network/syssocket.h b/kdecore/network/syssocket.h deleted file mode 100644 index e34db1bd1..000000000 --- a/kdecore/network/syssocket.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- C++ -*- - * Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net> - * - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef KDE_SYSSOCKET_H -#define KDE_SYSSOCKET_H - -#ifdef KSOCKETBASE_H -#error syssocket.h must be included before ksocketbase.h! -#endif - -#include <sys/types.h> -#include <sys/socket.h> - -namespace { - - /* - * These function here are just wrappers for the real system calls. - * - * Unfortunately, a number of systems out there work by redefining - * symbols through the preprocessor -- symbols that we need. - * - * So we write wrappers for all the low-level system calls. - * - * Qt has a very similar implementation. I got the idea from them, but - * I copied no code. - */ - - // socket - inline int kde_socket(int af, int style, int protocol) - { - return ::socket(af, style, protocol); - } - - // bind - inline int kde_bind(int fd, const struct sockaddr* sa, socklen_t len) - { - return ::bind(fd, sa, len); - } - - // listen - inline int kde_listen(int fd, int backlog) - { - return ::listen(fd, backlog); - } - - // connect - inline int kde_connect(int fd, const struct sockaddr* sa, socklen_t len) - { - return ::connect(fd, (struct sockaddr*)sa, len); - } - - // accept - inline int kde_accept(int fd, struct sockaddr* sa, socklen_t* len) - { - return ::accept(fd, sa, len); - } - - // getpeername - inline int kde_getpeername(int fd, struct sockaddr* sa, socklen_t* len) - { - return ::getpeername(fd, sa, len); - } - - // getsockname - inline int kde_getsockname(int fd, struct sockaddr* sa, socklen_t* len) - { - return ::getsockname(fd, sa, len); - } - -} // anonymous namespace - -#endif |