summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/network
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2019-04-21 23:22:20 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2019-04-21 23:22:20 +0900
commitdba036816b279bc1539a9f3894fbc414665d2bce (patch)
tree29e4bf00bafe515e7afdd02168d65a47a3f9fbc0 /tqtinterface/qt4/src/network
parent6f1b4f0c7505a049d992a33f6e409b7c75732d4b (diff)
downloadexperimental-dba036816b279bc1539a9f3894fbc414665d2bce.tar.gz
experimental-dba036816b279bc1539a9f3894fbc414665d2bce.zip
Removed unnecessary and/or TDE-unrelated code.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it> Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
Diffstat (limited to 'tqtinterface/qt4/src/network')
-rw-r--r--tqtinterface/qt4/src/network/qt_network.pri23
-rw-r--r--tqtinterface/qt4/src/network/tqdns.cpp5294
-rw-r--r--tqtinterface/qt4/src/network/tqdns.h382
-rw-r--r--tqtinterface/qt4/src/network/tqftp.cpp2421
-rw-r--r--tqtinterface/qt4/src/network/tqftp.h204
-rw-r--r--tqtinterface/qt4/src/network/tqhostaddress.cpp459
-rw-r--r--tqtinterface/qt4/src/network/tqhostaddress.h131
-rw-r--r--tqtinterface/qt4/src/network/tqhttp.cpp2384
-rw-r--r--tqtinterface/qt4/src/network/tqhttp.h278
-rw-r--r--tqtinterface/qt4/src/network/tqnetwork.cpp71
-rw-r--r--tqtinterface/qt4/src/network/tqnetwork.h60
-rw-r--r--tqtinterface/qt4/src/network/tqserversocket.cpp297
-rw-r--r--tqtinterface/qt4/src/network/tqserversocket.h95
-rw-r--r--tqtinterface/qt4/src/network/tqsocket.cpp1668
-rw-r--r--tqtinterface/qt4/src/network/tqsocket.h174
-rw-r--r--tqtinterface/qt4/src/network/tqsocketdevice.cpp584
-rw-r--r--tqtinterface/qt4/src/network/tqsocketdevice.h185
-rw-r--r--tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp1269
18 files changed, 0 insertions, 15979 deletions
diff --git a/tqtinterface/qt4/src/network/qt_network.pri b/tqtinterface/qt4/src/network/qt_network.pri
deleted file mode 100644
index 6b8986a..0000000
--- a/tqtinterface/qt4/src/network/qt_network.pri
+++ /dev/null
@@ -1,23 +0,0 @@
-# Qt network module
-
-network {
- HEADERS += $$NETWORK_H/tqdns.h \
- $$NETWORK_H/tqftp.h \
- $$NETWORK_H/tqhttp.h \
- $$NETWORK_H/tqhostaddress.h \
- $$NETWORK_H/tqnetwork.h \
- $$NETWORK_H/tqserversocket.h \
- $$NETWORK_H/tqsocket.h \
- $$NETWORK_H/tqsocketdevice.h
- NETWORK_SOURCES = $$NETWORK_CPP/tqdns.cpp \
- $$NETWORK_CPP/tqftp.cpp \
- $$NETWORK_CPP/tqhttp.cpp \
- $$NETWORK_CPP/tqhostaddress.cpp \
- $$NETWORK_CPP/tqnetwork.cpp \
- $$NETWORK_CPP/tqserversocket.cpp \
- $$NETWORK_CPP/tqsocket.cpp \
- $$NETWORK_CPP/tqsocketdevice.cpp
- unix:NETWORK_SOURCES += $$NETWORK_CPP/tqsocketdevice_unix.cpp
- win32:NETWORK_SOURCES += $$NETWORK_CPP/tqsocketdevice_win.cpp
- SOURCES += $$NETWORK_SOURCES
-}
diff --git a/tqtinterface/qt4/src/network/tqdns.cpp b/tqtinterface/qt4/src/network/tqdns.cpp
deleted file mode 100644
index 4ba3a85..0000000
--- a/tqtinterface/qt4/src/network/tqdns.cpp
+++ /dev/null
@@ -1,5294 +0,0 @@
-#include "tqtglobaldefines.h"
-
-#ifdef USE_QT4
-
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt3Support module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// #include "Qt/qplatformdefs.h"
-
-#include "Qt/qbytearray.h"
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_CYGWIN)
-# include "qt_windows.h"
-#else
-# include <sys/types.h>
-# include <netinet/in.h>
-# include <arpa/nameser.h>
-# include <resolv.h>
-extern "C" int res_init();
-#endif
-
-// POSIX Large File Support redefines open -> open64
-#if defined(open)
-# undef open
-#endif
-
-// POSIX Large File Support redefines truncate -> truncate64
-#if defined(truncate)
-# undef truncate
-#endif
-
-// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
-#if defined(connect)
-# undef connect
-#endif
-
-// UnixWare 7 redefines socket -> _socket
-#if defined(socket)
-# undef socket
-#endif
-
-#include "tqdns.h"
-
-#ifndef QT_NO_DNS
-
-#include "Qt/qdatetime.h"
-#include "tqdict.h"
-#include "tqptrlist.h"
-#include "Qt/qstring.h"
-#include "Qt/qtimer.h"
-#include "Qt/qapplication.h"
-#include "tqptrvector.h"
-#include "tqstrlist.h"
-#include "tqptrdict.h"
-#include "Qt/qfile.h"
-#include "Qt/qtextstream.h"
-#include "tqsocketdevice.h"
-#include "tqcleanuphandler.h"
-#include <limits.h>
-
-// #include "Qt/qhostaddress.h"
-// #include "Qt/qsocketnotifier.h"
-
-QT_BEGIN_NAMESPACE
-
-//#define TQDNS_DEBUG
-
-static Q_UINT16 theId; // ### seeded started by now()
-
-
-static QDateTime * originOfTime = 0;
-
-static TQCleanupHandler<QDateTime> q3dns_cleanup_time;
-
-static Q_UINT32 now()
-{
- if ( originOfTime )
- return originOfTime->secsTo( QDateTime::currentDateTime() );
-
- originOfTime = new QDateTime( QDateTime::currentDateTime() );
- theId = originOfTime->time().msec() * 60 + originOfTime->time().second();
- q3dns_cleanup_time.add( &originOfTime );
- return 0;
-}
-
-
-static TQPtrList<TQHostAddress> * theNs = 0;
-static TQStrList * theDomains = 0;
-static bool ipv6support = false;
-
-class TQDnsPrivate {
-public:
- TQDnsPrivate() : queryTimer( 0 ), noNames(false)
- {
-#if defined(Q_DNS_SYNCHRONOUS)
-#if defined(Q_OS_UNIX)
- noEventLoop = qApp==0 || qApp->loopLevel()==0;
-#else
- noEventLoop = false;
-#endif
-#endif
- }
- ~TQDnsPrivate()
- {
- delete queryTimer;
- }
-private:
- TQTimer * queryTimer;
- bool noNames;
-#if defined(Q_DNS_SYNCHRONOUS)
- bool noEventLoop;
-#endif
-
- friend class TQDns;
- friend class TQDnsAnswer;
-};
-
-
-class TQDnsRR;
-class TQDnsDomain;
-
-
-
-// TQDnsRR is the class used to store a single RR. TQDnsRR can store
-// all of the supported RR types. a TQDnsRR is always cached.
-
-// TQDnsRR is mostly constructed from the outside. a but hacky, but
-// permissible since the entire class is internal.
-
-class TQDnsRR {
-public:
- TQDnsRR( const TQString & label );
- ~TQDnsRR();
-
-public:
- TQDnsDomain * domain;
- TQDns::RecordType t;
- bool nxdomain;
- bool current;
- Q_UINT32 expireTime;
- Q_UINT32 deleteTime;
- // somewhat space-wasting per-type data
- // a / aaaa
- TQHostAddress address;
- // cname / mx / srv / ptr
- TQString target;
- // mx / srv
- Q_UINT16 priority;
- // srv
- Q_UINT16 weight;
- Q_UINT16 port;
- // txt
- TQString text; // could be overloaded into target...
-private:
-
-};
-
-
-class TQDnsDomain {
-public:
- TQDnsDomain( const TQString & label );
- ~TQDnsDomain();
-
- static void add( const TQString & label, TQDnsRR * );
- static TQPtrList<TQDnsRR> * cached( const TQDns * );
-
- void take( TQDnsRR * );
-
- void sweep( Q_UINT32 thisSweep );
-
- bool isEmpty() const { return rrs == 0 || rrs->isEmpty(); }
-
- TQString name() const { return l; }
-
-public:
- TQString l;
- TQPtrList<TQDnsRR> * rrs;
-};
-
-
-class TQDnsQuery: public TQTimer { // this inheritance is a very evil hack
-public:
- TQDnsQuery():
- id( 0 ), t( TQDns::None ), step(0), started(0),
- dns( new TQPtrDict<void>(17) ) {}
- ~TQDnsQuery() { delete dns; }
- Q_UINT16 id;
- TQDns::RecordType t;
- TQString l;
-
- uint step;
- Q_UINT32 started;
-
- TQPtrDict<void> * dns;
-};
-
-
-
-class TQDnsAnswer {
-public:
- TQDnsAnswer( TQDnsQuery * );
- TQDnsAnswer( const TQByteArray &, TQDnsQuery * );
- ~TQDnsAnswer();
-
- void parse();
- void notify();
-
- bool ok;
-
-private:
- TQDnsQuery * query;
-
- Q_UINT8 * answer;
- int size;
- int pp;
-
- TQPtrList<TQDnsRR> * rrs;
-
- // convenience
- int next;
- int ttl;
- TQString label;
- TQDnsRR * rr;
-
- TQString readString(bool multipleLabels = true);
- void parseA();
- void parseAaaa();
- void parseMx();
- void parseSrv();
- void parseCname();
- void parsePtr();
- void parseTxt();
- void parseNs();
-};
-
-
-TQDnsRR::TQDnsRR( const TQString & label )
- : domain( 0 ), t( TQDns::None ),
- nxdomain( false ), current( false ),
- expireTime( 0 ), deleteTime( 0 ),
- priority( 0 ), weight( 0 ), port( 0 )
-{
- TQDnsDomain::add( label, this );
-}
-
-
-// not supposed to be deleted except by TQDnsDomain
-TQDnsRR::~TQDnsRR()
-{
- // nothing is necessary
-}
-
-
-// this one just sticks in a NXDomain
-TQDnsAnswer::TQDnsAnswer( TQDnsQuery * query_ )
-{
- ok = true;
-
- answer = 0;
- size = 0;
- query = query_;
- pp = 0;
- rrs = new TQPtrList<TQDnsRR>;
- rrs->setAutoDelete( false );
- next = size;
- ttl = 0;
- label.clear();
- rr = 0;
-
- TQDnsRR * newrr = new TQDnsRR( query->l );
- newrr->t = query->t;
- newrr->deleteTime = query->started + 10;
- newrr->expireTime = query->started + 10;
- newrr->nxdomain = true;
- newrr->current = true;
- rrs->append( newrr );
-}
-
-
-TQDnsAnswer::TQDnsAnswer( const TQByteArray& answer_,
- TQDnsQuery * query_ )
-{
- ok = true;
-
- answer = (Q_UINT8 *)(answer_.data());
- size = (int)answer_.size();
- query = query_;
- pp = 0;
- rrs = new TQPtrList<TQDnsRR>;
- rrs->setAutoDelete( false );
- next = size;
- ttl = 0;
- label.clear();
- rr = 0;
-}
-
-
-TQDnsAnswer::~TQDnsAnswer()
-{
- if ( !ok && rrs ) {
- TQPtrListIterator<TQDnsRR> it( *rrs );
- TQDnsRR * tmprr;
- while( (tmprr=it.current()) != 0 ) {
- ++it;
- tmprr->t = TQDns::None; // will be deleted soonish
- }
- }
- delete rrs;
-}
-
-
-TQString TQDnsAnswer::readString(bool multipleLabels)
-{
- int p = pp;
- TQString r;
- Q_UINT8 b;
- for( ;; ) {
- b = 128;
- // Read one character
- if ( p >= 0 && p < size )
- b = answer[p];
-
- switch( b >> 6 ) {
- case 0:
- // b is less than 64
- p++;
-
- // Detect end of data
- if ( b == 0 ) {
- if ( p > pp )
- pp = p;
- return r.isNull() ? TQT_TQSTRING(TQLatin1String( "." )) : r;
- }
-
- // Read a label of size 'b' characters
- if ( !r.isNull() )
- r += QLatin1Char('.');
- while( b-- > 0 )
- r += QLatin1Char( answer[p++] );
-
- // Return immediately if we were only supposed to read one
- // label.
- if (!multipleLabels)
- return r;
-
- break;
- default:
- // Ignore unrecognized control character, or p was out of
- // range.
- goto not_ok;
- case 3:
- // Use the next character to determine the relative offset
- // to jump to before continuing the packet parsing.
- int q = ( (answer[p] & 0x3f) << 8 ) + answer[p+1];
-
- if ( q >= pp || q >= p )
- goto not_ok;
- if ( p >= pp )
- pp = p + 2;
- p = q;
- }
- }
-not_ok:
- ok = false;
- return TQString();
-}
-
-
-
-void TQDnsAnswer::parseA()
-{
- if ( next != pp + 4 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN A for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::A;
- rr->address = TQHostAddress( ( answer[pp+0] << 24 ) +
- ( answer[pp+1] << 16 ) +
- ( answer[pp+2] << 8 ) +
- ( answer[pp+3] ) );
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN A %s (ttl %d)", label.ascii(),
- rr->address.toString().ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseAaaa()
-{
- if ( next != pp + 16 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN Aaaa for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Aaaa;
- rr->address = TQHostAddress( answer+pp );
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN Aaaa %s (ttl %d)", label.ascii(),
- rr->address.toString().ascii(), ttl );
-#endif
-}
-
-
-
-void TQDnsAnswer::parseMx()
-{
- if ( next < pp + 2 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN MX for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->priority = (answer[pp] << 8) + answer[pp+1];
- pp += 2;
- rr->target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad string in MX for %s", label.ascii() );
-#endif
- return;
- }
- rr->t = TQDns::Mx;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN MX %d %s (ttl %d)", label.ascii(),
- rr->priority, rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseSrv()
-{
- if ( next < pp + 6 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN SRV for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->priority = (answer[pp] << 8) + answer[pp+1];
- rr->weight = (answer[pp+2] << 8) + answer[pp+3];
- rr->port = (answer[pp+4] << 8) + answer[pp+5];
- pp += 6;
- rr->target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad string in SRV for %s", label.ascii() );
-#endif
- return;
- }
- rr->t = TQDns::Srv;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN SRV %d %d %d %s (ttl %d)", label.ascii(),
- rr->priority, rr->weight, rr->port, rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseCname()
-{
- TQString target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Cname;
- rr->target = target;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN CNAME %s (ttl %d)", label.ascii(),
- rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseNs()
-{
- TQString target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
-#endif
- return;
- }
-
- // parse, but ignore
-
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN NS %s (ttl %d)", label.ascii(),
- target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parsePtr()
-{
- TQString target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad PTR for for %s", label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Ptr;
- rr->target = target;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN PTR %s (ttl %d)", label.ascii(),
- rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseTxt()
-{
- TQString text = readString(false);
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad TXT for for %s", label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Txt;
- rr->text = text;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN TXT \"%s\" (ttl %d)", label.ascii(),
- rr->text.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parse()
-{
- // okay, do the work...
- if ( (answer[2] & 0x78) != 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: answer to wrong query type (%d)", answer[1] );
-#endif
- ok = false;
- return;
- }
-
- // AA
- bool aa = (answer[2] & 4) != 0;
-
- // TC
- if ( (answer[2] & 2) != 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: truncated answer; pressing on" );
-#endif
- }
-
- // RD
- bool rd = (answer[2] & 1) != 0;
-
- // we don't test RA
- // we don't test the MBZ fields
-
- if ( (answer[3] & 0x0f) == 3 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: saw NXDomain for %s", query->l.ascii() );
-#endif
- // NXDomain. cache that for one minute.
- rr = new TQDnsRR( query->l );
- rr->t = query->t;
- rr->deleteTime = query->started + 60;
- rr->expireTime = query->started + 60;
- rr->nxdomain = true;
- rr->current = true;
- rrs->append( rr );
- return;
- }
-
- if ( (answer[3] & 0x0f) != 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: error code %d", answer[3] & 0x0f );
-#endif
- ok = false;
- return;
- }
-
- int qdcount = ( answer[4] << 8 ) + answer[5];
- int ancount = ( answer[6] << 8 ) + answer[7];
- int nscount = ( answer[8] << 8 ) + answer[9];
- int adcount = (answer[10] << 8 ) +answer[11];
-
- pp = 12;
-
- // read query
- while( qdcount > 0 && pp < size ) {
- // should I compare the string against query->l?
- (void)readString();
- if ( !ok )
- return;
- pp += 4;
- qdcount--;
- }
-
- // answers and stuff
- int rrno = 0;
- // if we parse the answer completely, but there are no answers,
- // ignore the entire thing.
- int answers = 0;
- while( ( rrno < ancount ||
- ( ok && answers >0 && rrno < ancount + nscount + adcount ) ) &&
- pp < size ) {
- label = readString().lower();
- if ( !ok )
- return;
- int rdlength = 0;
- if ( pp + 10 <= size )
- rdlength = ( answer[pp+8] << 8 ) + answer[pp+9];
- if ( pp + 10 + rdlength > size ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: ran out of stuff to parse (%d+%d>%d (%d)",
- pp, rdlength, size, rrno < ancount );
-#endif
- // if we're still in the AN section, we should go back and
- // at least down the TTLs. probably best to invalidate
- // the results.
- // the rrs list is good for this
- ok = ( rrno < ancount );
- return;
- }
- uint type, clas;
- type = ( answer[pp+0] << 8 ) + answer[pp+1];
- clas = ( answer[pp+2] << 8 ) + answer[pp+3];
- ttl = ( answer[pp+4] << 24 ) + ( answer[pp+5] << 16 ) +
- ( answer[pp+6] << 8 ) + answer[pp+7];
- pp = pp + 10;
- if ( clas != 1 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: class %d (not internet) for %s",
- clas, label.isNull() ? "." : label.ascii() );
-#endif
- } else {
- next = pp + rdlength;
- rr = 0;
- switch( type ) {
- case 1:
- parseA();
- break;
- case 28:
- parseAaaa();
- break;
- case 15:
- parseMx();
- break;
- case 33:
- parseSrv();
- break;
- case 5:
- parseCname();
- break;
- case 12:
- parsePtr();
- break;
- case 16:
- parseTxt();
- break;
- case 2:
- parseNs();
- break;
- default:
- // something we don't know
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: type %d for %s", type,
- label.isNull() ? "." : label.ascii() );
-#endif
- break;
- }
- if ( rr ) {
- rr->deleteTime = 0;
- if ( ttl > 0 )
- rr->expireTime = query->started + ttl;
- else
- rr->expireTime = query->started + 20;
- if ( rrno < ancount ) {
- answers++;
- rr->deleteTime = rr->expireTime;
- }
- rr->current = true;
- rrs->append( rr );
- }
- }
- if ( !ok )
- return;
- pp = next;
- next = size;
- rrno++;
- }
- if ( answers == 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: answer contained no answers" );
-#endif
- ok = ( aa && rd );
- }
-
- // now go through the list and mark all the As that are referenced
- // by something we care about. we want to cache such As.
- rrs->first();
- TQDict<void> used( 17 );
- used.setAutoDelete( false );
- while( (rr=rrs->current()) != 0 ) {
- rrs->next();
- if ( rr->target.length() && rr->deleteTime > 0 && rr->current )
- used.insert( rr->target, (void*)42 );
- if ( ( rr->t == TQDns::A || rr->t == TQDns::Aaaa ) &&
- used.find( rr->domain->name() ) != 0 )
- rr->deleteTime = rr->expireTime;
- }
-
- // next, for each RR, delete any older RRs that are equal to it
- rrs->first();
- while( (rr=rrs->current()) != 0 ) {
- rrs->next();
- if ( rr && rr->domain && rr->domain->rrs ) {
- TQPtrList<TQDnsRR> * drrs = rr->domain->rrs;
- drrs->first();
- TQDnsRR * older;
- while( (older=drrs->current()) != 0 ) {
- if ( older != rr &&
- older->t == rr->t &&
- older->nxdomain == rr->nxdomain &&
- older->address == rr->address &&
- older->target == rr->target &&
- older->priority == rr->priority &&
- older->weight == rr->weight &&
- older->port == rr->port &&
- older->text == rr->text ) {
- // well, it's equal, but it's not the same. so we kill it,
- // but use its expiry time.
-#if defined(TQDNS_DEBUG)
- qDebug( "killing off old %d for %s, expire was %d",
- older->t, older->domain->name().latin1(),
- rr->expireTime );
-#endif
- older->t = TQDns::None;
- rr->expireTime = QMAX( older->expireTime, rr->expireTime );
- rr->deleteTime = QMAX( older->deleteTime, rr->deleteTime );
- older->deleteTime = 0;
-#if defined(TQDNS_DEBUG)
- qDebug( " adjusted expire is %d", rr->expireTime );
-#endif
- }
- drrs->next();
- }
- }
- }
-
-#if defined(TQDNS_DEBUG)
- //qDebug( "DNS Manager: ()" );
-#endif
-}
-
-
-class TQDnsUgleHack: public TQDns {
-public:
- void ugle( bool emitAnyway=false );
-};
-
-
-void TQDnsAnswer::notify()
-{
- if ( !rrs || !ok || !query || !query->dns )
- return;
-
- TQPtrDict<void> notified;
- notified.setAutoDelete( false );
-
- TQPtrDictIterator<void> it( *query->dns );
- TQDns * dns;
- it.toFirst();
- while( (dns=(TQDns*)(it.current())) != 0 ) {
- ++it;
- if ( notified.find( (void*)dns ) == 0 ) {
- notified.insert( (void*)dns, (void*)42 );
- if ( rrs->count() == 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: found no answers!" );
-#endif
- dns->d->noNames = true;
- ((TQDnsUgleHack*)dns)->ugle( true );
- } else {
- TQStringList n = dns->qualifiedNames();
- if ( query && n.contains(query->l) )
- ((TQDnsUgleHack*)dns)->ugle();
-#if defined(TQDNS_DEBUG)
- else
- qDebug( "DNS Manager: DNS thing %s not notified for %s",
- dns->label().ascii(), query->l.ascii() );
-#endif
- }
- }
- }
-}
-
-
-//
-//
-// TQDnsManager
-//
-//
-
-
-class TQDnsManager: public TQDnsSocket {
-private:
-public: // just to silence the moronic g++.
- TQDnsManager();
- ~TQDnsManager();
-public:
- static TQDnsManager * manager();
-
- TQDnsDomain * domain( const TQString & );
-
- void transmitQuery( TQDnsQuery * );
- void transmitQuery( int );
-
- // reimplementation of the slots
- void cleanCache();
- void retransmit();
- void answer();
-
-public:
- TQPtrVector<TQDnsQuery> queries;
- TQDict<TQDnsDomain> cache;
- TQSocketDevice * ipv4Socket;
-#if !defined (QT_NO_IPV6)
- TQSocketDevice * ipv6Socket;
-#endif
-};
-
-
-
-static TQDnsManager * globalManager = 0;
-
-static void cleanupDns()
-{
- delete globalManager;
- globalManager = 0;
-}
-
-TQDnsManager * TQDnsManager::manager()
-{
- if ( !globalManager ) {
- qAddPostRoutine(cleanupDns);
- new TQDnsManager();
- }
- return globalManager;
-}
-
-
-void TQDnsUgleHack::ugle( bool emitAnyway)
-{
- if ( emitAnyway || !isWorking() ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: status change for %s (type %d)",
- label().ascii(), recordType() );
-#endif
- emit resultsReady();
- }
-}
-
-
-TQDnsManager::TQDnsManager()
- : TQDnsSocket( qApp, "Internal DNS manager" ),
- queries( TQPtrVector<TQDnsQuery>( 0 ) ),
- cache( TQDict<TQDnsDomain>( 83, false ) ),
- ipv4Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv4, 0 ) )
-#if !defined (QT_NO_IPV6)
- , ipv6Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv6, 0 ) )
-#endif
-{
- cache.setAutoDelete( true );
- globalManager = this;
-
- TQTimer * sweepTimer = new TQTimer( this );
- sweepTimer->start( 1000 * 60 * 3 );
- connect( sweepTimer, TQT_SIGNAL(timeout()),
- this, TQT_SLOT(cleanCache()) );
-
- TQSocketNotifier * rn4 = new TQSocketNotifier( ipv4Socket->socket(),
- TQSocketNotifier::Read,
- TQT_TQOBJECT(this), "dns IPv4 socket watcher" );
- ipv4Socket->setAddressReusable( false );
- ipv4Socket->setBlocking( false );
- connect( rn4, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
-
-#if !defined (QT_NO_IPV6)
- // Don't connect the IPv6 socket notifier if the host does not
- // support IPv6.
- if ( ipv6Socket->socket() != -1 ) {
- TQSocketNotifier * rn6 = new TQSocketNotifier( ipv6Socket->socket(),
- TQSocketNotifier::Read,
- TQT_TQOBJECT(this), "dns IPv6 socket watcher" );
-
- ipv6support = true;
- ipv6Socket->setAddressReusable( false );
- ipv6Socket->setBlocking( false );
- connect( rn6, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
- }
-#endif
-
- if ( !theNs )
- TQDns::doResInit();
-
- // O(n*n) stuff here. but for 3 and 6, O(n*n) with a low k should
- // be perfect. the point is to eliminate any duplicates that
- // might be hidden in the lists.
- TQPtrList<TQHostAddress> * ns = new TQPtrList<TQHostAddress>;
-
- theNs->first();
- TQHostAddress * h;
- while( (h=theNs->current()) != 0 ) {
- ns->first();
- while( ns->current() != 0 && !(*ns->current() == *h) )
- ns->next();
- if ( !ns->current() ) {
- ns->append( new TQHostAddress(*h) );
-#if defined(TQDNS_DEBUG)
- qDebug( "using name server %s", h->toString().latin1() );
- } else {
- qDebug( "skipping address %s", h->toString().latin1() );
-#endif
- }
- theNs->next();
- }
-
- delete theNs;
- theNs = ns;
- theNs->setAutoDelete( true );
-
- TQStrList * domains = new TQStrList( true );
-
- theDomains->first();
- const char * s;
- while( (s=theDomains->current()) != 0 ) {
- domains->first();
- while( domains->current() != 0 && qstrcmp( domains->current(), s ) )
- domains->next();
- if ( !domains->current() ) {
- domains->append( s );
-#if defined(TQDNS_DEBUG)
- qDebug( "searching domain %s", s );
- } else {
- qDebug( "skipping domain %s", s );
-#endif
- }
- theDomains->next();
- }
-
- delete theDomains;
- theDomains = domains;
- theDomains->setAutoDelete( true );
-}
-
-
-TQDnsManager::~TQDnsManager()
-{
- if ( globalManager )
- globalManager = 0;
- queries.setAutoDelete( true );
- cache.setAutoDelete( true );
- delete ipv4Socket;
-#if !defined (QT_NO_IPV6)
- delete ipv6Socket;
-#endif
-}
-
-static Q_UINT32 lastSweep = 0;
-
-void TQDnsManager::cleanCache()
-{
- bool again = false;
- TQDictIterator<TQDnsDomain> it( cache );
- TQDnsDomain * d;
- Q_UINT32 thisSweep = now();
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDnsManager::cleanCache(: Called, time is %u, last was %u",
- thisSweep, lastSweep );
-#endif
-
- while( (d=it.current()) != 0 ) {
- ++it;
- d->sweep( thisSweep ); // after this, d may be empty
- if ( !again )
- again = !d->isEmpty();
- }
- if ( !again )
- delete this;
- lastSweep = thisSweep;
-}
-
-
-void TQDnsManager::retransmit()
-{
- const TQT_BASE_OBJECT_NAME * o = sender();
- if ( o == 0 || globalManager == 0 || this != globalManager )
- return;
- uint q = 0;
- while( q < queries.size() && queries[q] != o )
- q++;
- if ( q < queries.size() )
- transmitQuery( q );
-}
-
-
-void TQDnsManager::answer()
-{
- TQByteArray a( 16383 ); // large enough for anything, one suspects
-
- int r;
-#if defined (QT_NO_IPV6)
- r = ipv4Socket->readBlock(a.data(), a.size());
-#else
- if (((TQSocketNotifier *)sender())->socket() == ipv4Socket->socket())
- r = ipv4Socket->readBlock(a.data(), a.size());
- else
- r = ipv6Socket->readBlock(a.data(), a.size());
-#endif
-#if defined(TQDNS_DEBUG)
-#if !defined (QT_NO_IPV6)
- qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
- useIpv4Socket ? ipv4Socket->peerAddress().toString().ascii()
- : ipv6Socket->peerAddress().toString().ascii(),
- useIpv4Socket ? ipv4Socket->peerPort() : ipv6Socket->peerPort() );
-#else
- qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
- ipv4Socket->peerAddress().toString().ascii(), ipv4Socket->peerPort());;
-#endif
-#endif
- if ( r < 12 )
- return;
- // maybe we should check that the answer comes from port 53 on one
- // of our name servers...
- a.resize( r );
-
- Q_UINT16 aid = (((Q_UINT8)a[0]) << 8) + ((Q_UINT8)a[1]);
- uint i = 0;
- while( i < queries.size() &&
- !( queries[i] && queries[i]->id == aid ) )
- i++;
- if ( i == queries.size() ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: bad id (0x%04x) %d", aid, i );
-#endif
- return;
- }
-
- // at this point queries[i] is whatever we asked for.
-
- if ( ( (Q_UINT8)(a[2]) & 0x80 ) == 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: received a query" );
-#endif
- return;
- }
-
- TQDnsQuery * q = queries[i];
- TQDnsAnswer answer( a, q );
- answer.parse();
- if ( answer.ok ) {
- queries.take( i );
- answer.notify();
- delete q;
- }
-}
-
-
-void TQDnsManager::transmitQuery( TQDnsQuery * query_ )
-{
- if ( !query_ )
- return;
-
- uint i = 0;
- while( i < queries.size() && queries[i] != 0 )
- i++;
- if ( i == queries.size() )
- queries.resize( i+1 );
- queries.insert( i, query_ );
- transmitQuery( i );
-}
-
-
-void TQDnsManager::transmitQuery( int i )
-{
- if ( i < 0 || i >= (int)queries.size() )
- return;
- TQDnsQuery * q = queries[i];
-
- if ( q && q->step > 8 ) {
- // okay, we've run out of retransmissions. we fake an NXDomain
- // with a very short life time...
- TQDnsAnswer answer( q );
- answer.notify();
- // and then get rid of the query
- queries.take( i );
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: giving up on query 0x%04x", q->id );
-#endif
- delete q;
- TQTimer::singleShot( 0, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
- // and don't process anything more
- return;
- }
-
- if ((q && !q->dns) || q->dns->isEmpty())
- // no one currently wants the answer, so there's no point in
- // retransmitting the query. we keep it, though. an answer may
- // arrive for an earlier query transmission, and if it does we
- // may benefit from caching the result.
- return;
-
- TQByteArray p( 12 + q->l.length() + 2 + 4 );
- if ( p.size() > 500 )
- return; // way over the limit, so don't even try
-
- // header
- // id
- p[0] = (q->id & 0xff00) >> 8;
- p[1] = q->id & 0x00ff;
- p[2] = 1; // recursion desired, rest is 0
- p[3] = 0; // all is 0
- // one query
- p[4] = 0;
- p[5] = 1;
- // no answers, name servers or additional data
- p[6] = p[7] = p[8] = p[9] = p[10] = p[11] = 0;
-
- // the name is composed of several components. each needs to be
- // written by itself... so we write...
- // oh, and we assume that there's no funky characters in there.
- int pp = 12;
- uint lp = 0;
- while( lp < (uint) q->l.length() ) {
- int le = q->l.find( QLatin1Char('.'), lp );
- if ( le < 0 )
- le = q->l.length();
- TQString component = q->l.mid( lp, le-lp );
- p[pp++] = component.length();
- int cp;
- for( cp=0; cp < (int)component.length(); cp++ )
- p[pp++] = component[cp].latin1();
- lp = le + 1;
- }
- // final null
- p[pp++] = 0;
- // query type
- p[pp++] = 0;
- switch( q->t ) {
- case TQDns::A:
- p[pp++] = 1;
- break;
- case TQDns::Aaaa:
- p[pp++] = 28;
- break;
- case TQDns::Mx:
- p[pp++] = 15;
- break;
- case TQDns::Srv:
- p[pp++] = 33;
- break;
- case TQDns::Cname:
- p[pp++] = 5;
- break;
- case TQDns::Ptr:
- p[pp++] = 12;
- break;
- case TQDns::Txt:
- p[pp++] = 16;
- break;
- default:
- p[pp++] = (char)255; // any
- break;
- }
- // query class (always internet)
- p[pp++] = 0;
- p[pp++] = 1;
-
- // if we have no name servers, we should regenerate ns in case
- // name servers have recently been defined (like on windows,
- // plugging/unplugging the network cable will change the name
- // server entries)
- if ( !theNs || theNs->isEmpty() )
- TQDns::doResInit();
-
- if ( !theNs || theNs->isEmpty() ) {
- // we don't find any name servers. We fake an NXDomain
- // with a very short life time...
- TQDnsAnswer answer( q );
- answer.notify();
- // and then get rid of the query
- queries.take( i );
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: no DNS server found on query 0x%04x", q->id );
-#endif
- delete q;
- TQTimer::singleShot( 1000*10, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
- // and don't process anything more
- return;
- }
-
- TQHostAddress receiver = *theNs->at( q->step % theNs->count() );
- if (receiver.isIPv4Address())
- ipv4Socket->writeBlock( p.data(), pp, receiver, 53 );
-#if !defined (QT_NO_IPV6)
- else
- ipv6Socket->writeBlock( p.data(), pp, receiver, 53 );
-#endif
-#if defined(TQDNS_DEBUG)
- qDebug( "issuing query 0x%04x (%d) about %s type %d to %s",
- q->id, q->step, q->l.ascii(), q->t,
- ns->at( q->step % ns->count() )->toString().ascii() );
-#endif
- if ( theNs->count() > 1 && q->step == 0 && queries.count() == 1 ) {
- // if it's the first time, and we don't have any other
- // outstanding queries, send nonrecursive queries to the other
- // name servers too.
- p[2] = 0;
- TQHostAddress * server;
- while( (server=theNs->next()) != 0 ) {
- if (server->isIPv4Address())
- ipv4Socket->writeBlock( p.data(), pp, *server, 53 );
-#if !defined (QT_NO_IPV6)
- else
- ipv6Socket->writeBlock( p.data(), pp, *server, 53 );
-#endif
-#if defined(TQDNS_DEBUG)
- qDebug( "copying query to %s", server->toString().ascii() );
-#endif
- }
- }
- q->step++;
- // some testing indicates that normal dns queries take up to 0.6
- // seconds. the graph becomes steep around that point, and the
- // number of errors rises... so it seems good to retry at that
- // point.
- q->start( q->step < theNs->count() ? 800 : 1500, true );
-}
-
-
-TQDnsDomain * TQDnsManager::domain( const TQString & label )
-{
- TQDnsDomain * d = cache.find( label );
- if ( !d ) {
- d = new TQDnsDomain( label );
- cache.insert( label, d );
- }
- return d;
-}
-
-
-//
-//
-// the TQDnsDomain class looks after and coordinates queries for TQDnsRRs for
-// each domain, and the cached TQDnsRRs. (A domain, in DNS terminology, is
-// a node in the DNS. "no", "trolltech.com" and "lupinella.troll.no" are
-// all domains.)
-//
-//
-
-
-TQDnsDomain::TQDnsDomain( const TQString & label )
-{
- l = label;
- rrs = 0;
-}
-
-
-TQDnsDomain::~TQDnsDomain()
-{
- delete rrs;
- rrs = 0;
-}
-
-
-void TQDnsDomain::add( const TQString & label, TQDnsRR * rr )
-{
- TQDnsDomain * d = TQDnsManager::manager()->domain( label );
- if ( !d->rrs ) {
- d->rrs = new TQPtrList<TQDnsRR>;
- d->rrs->setAutoDelete( true );
- }
- d->rrs->append( rr );
- rr->domain = d;
-}
-
-
-TQPtrList<TQDnsRR> * TQDnsDomain::cached( const TQDns * r )
-{
- TQPtrList<TQDnsRR> * l = new TQPtrList<TQDnsRR>;
-
- // test at first if you have to start a query at all
- if ( r->recordType() == TQDns::A ) {
- if ( r->label().lower() == TQLatin1String("localhost") ) {
- // undocumented hack. ipv4-specific. also, may be a memory
- // leak? not sure. would be better to do this in doResInit(),
- // anyway.
- TQDnsRR *rrTmp = new TQDnsRR( r->label() );
- rrTmp->t = TQDns::A;
- rrTmp->address = TQHostAddress( 0x7f000001 );
- rrTmp->current = true;
- l->append( rrTmp );
- return l;
- }
- TQHostAddress tmp;
- if ( tmp.setAddress( r->label() ) ) {
- TQDnsRR *rrTmp = new TQDnsRR( r->label() );
- if ( tmp.isIPv4Address() ) {
- rrTmp->t = TQDns::A;
- rrTmp->address = tmp;
- rrTmp->current = true;
- l->append( rrTmp );
- } else {
- rrTmp->nxdomain = true;
- }
- return l;
- }
- }
- if ( r->recordType() == TQDns::Aaaa ) {
- TQHostAddress tmp;
- if ( tmp.setAddress(r->label()) ) {
- TQDnsRR *rrTmp = new TQDnsRR( r->label() );
- if ( tmp.isIPv6Address() ) {
- rrTmp->t = TQDns::Aaaa;
- rrTmp->address = tmp;
- rrTmp->current = true;
- l->append( rrTmp );
- } else {
- rrTmp->nxdomain = true;
- }
- return l;
- }
- }
-
- // if you reach this point, you have to do the query
- TQDnsManager * m = TQDnsManager::manager();
- TQStringList n = r->qualifiedNames();
- bool nxdomain;
- int cnamecount = 0;
- int it = 0;
- while( it < n.count() ) {
- TQString s = *(n.at(it++));
- nxdomain = false;
-#if defined(TQDNS_DEBUG)
- qDebug( "looking at cache for %s (%s %d)",
- s.ascii(), r->label().ascii(), r->recordType() );
-#endif
- TQDnsDomain * d = m->domain( s );
-#if defined(TQDNS_DEBUG)
- qDebug( " - found %d RRs", d && d->rrs ? d->rrs->count() : 0 );
-#endif
- if ( d->rrs )
- d->rrs->first();
- TQDnsRR * rr;
- bool answer = false;
- while( d->rrs && (rr=d->rrs->current()) != 0 ) {
- if ( rr->t == TQDns::Cname && r->recordType() != TQDns::Cname &&
- !rr->nxdomain && cnamecount < 16 ) {
- // cname. if the code is ugly, that may just
- // possibly be because the concept is.
-#if defined(TQDNS_DEBUG)
- qDebug( "found cname from %s to %s",
- r->label().ascii(), rr->target.ascii() );
-#endif
- s = rr->target;
- d = m->domain( s );
- if ( d->rrs )
- d->rrs->first();
- it = n.count();
- // we've elegantly moved over to whatever the cname
- // pointed to. well, not elegantly. let's remember
- // that we've done something, anyway, so we can't be
- // fooled into an infinte loop as well.
- cnamecount++;
- } else {
- if ( rr->t == r->recordType() ) {
- if ( rr->nxdomain )
- nxdomain = true;
- else
- answer = true;
- l->append( rr );
- if ( rr->deleteTime <= lastSweep ) {
- // we're returning something that'll be
- // deleted soon. we assume that if the client
- // wanted it twice, it'll want it again, so we
- // ask the name server again right now.
- TQDnsQuery * query = new TQDnsQuery;
- query->started = now();
- query->id = ++theId;
- query->t = rr->t;
- query->l = rr->domain->name();
- // note that here, we don't bother about
- // notification. but we do bother about
- // timeouts: we make sure to use high timeouts
- // and few tramsissions.
- query->step = theNs->count();
- TQT_BASE_OBJECT_NAME::connect( query, TQT_SIGNAL(timeout()),
- TQDnsManager::manager(),
- TQT_SLOT(retransmit()) );
- TQDnsManager::manager()->transmitQuery( query );
- }
- }
- d->rrs->next();
- }
- }
- // if we found a positive result, return quickly
- if ( answer && l->count() ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "found %d records for %s",
- l->count(), r->label().ascii() );
- l->first();
- while( l->current() ) {
- qDebug( " type %d target %s address %s",
- l->current()->t,
- l->current()->target.latin1(),
- l->current()->address.toString().latin1() );
- l->next();
- }
-#endif
- l->first();
- return l;
- }
-
-#if defined(TQDNS_DEBUG)
- if ( nxdomain )
- qDebug( "found NXDomain %s", s.ascii() );
-#endif
-
- if ( !nxdomain ) {
- // if we didn't, and not a negative result either, perhaps
- // we need to transmit a query.
- uint q = 0;
- while ( q < m->queries.size() &&
- ( m->queries[q] == 0 ||
- m->queries[q]->t != r->recordType() ||
- m->queries[q]->l != s ) )
- q++;
- // we haven't done it before, so maybe we should. but
- // wait - if it's an unqualified name, only ask when all
- // the other alternatives are exhausted.
- if ( q == m->queries.size() && ( s.find( QLatin1Char('.') ) >= 0 ||
- int(l->count()) >= n.count()-1 ) ) {
- TQDnsQuery * query = new TQDnsQuery;
- query->started = now();
- query->id = ++theId;
- query->t = r->recordType();
- query->l = s;
- query->dns->replace( (void*)r, (void*)r );
- TQT_BASE_OBJECT_NAME::connect( query, TQT_SIGNAL(timeout()),
- TQDnsManager::manager(), TQT_SLOT(retransmit()) );
- TQDnsManager::manager()->transmitQuery( query );
- } else if ( q < m->queries.size() ) {
- // if we've found an earlier query for the same
- // domain/type, subscribe to its answer
- m->queries[q]->dns->replace( (void*)r, (void*)r );
- }
- }
- }
- l->first();
- return l;
-}
-
-
-void TQDnsDomain::sweep( Q_UINT32 thisSweep )
-{
- if ( !rrs )
- return;
-
- TQDnsRR * rr;
- rrs->first();
- while( (rr=rrs->current()) != 0 ) {
- if ( !rr->deleteTime )
- rr->deleteTime = thisSweep; // will hit next time around
-
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::sweep: %s type %d expires %u %u - %s / %s",
- rr->domain->name().latin1(), rr->t,
- rr->expireTime, rr->deleteTime,
- rr->target.latin1(), rr->address.toString().latin1());
-#endif
- if ( rr->current == false ||
- rr->t == TQDns::None ||
- rr->deleteTime <= thisSweep ||
- rr->expireTime <= thisSweep )
- rrs->remove();
- else
- rrs->next();
- }
-
- if ( rrs->isEmpty() ) {
- delete rrs;
- rrs = 0;
- }
-}
-
-
-
-
-// the itsy-bitsy little socket class I don't really need except for
-// so I can subclass and reimplement the slots.
-
-
-TQDnsSocket::TQDnsSocket( TQT_BASE_OBJECT_NAME * parent, const char * name )
- : TQObject( parent, name )
-{
- // nothing
-}
-
-
-TQDnsSocket::~TQDnsSocket()
-{
- // nothing
-}
-
-
-void TQDnsSocket::cleanCache()
-{
- // nothing
-}
-
-
-void TQDnsSocket::retransmit()
-{
- // nothing
-}
-
-
-void TQDnsSocket::answer()
-{
- // nothing
-}
-
-
-/*!
- \class TQDns
- \brief The TQDns class provides asynchronous DNS lookups.
-
- \compat
-
- Both Windows and Unix provide synchronous DNS lookups; Windows
- provides some asynchronous support too. At the time of writing
- neither operating system provides asynchronous support for
- anything other than hostname-to-address mapping.
-
- TQDns rectifies this shortcoming, by providing asynchronous caching
- lookups for the record types that we expect modern GUI
- applications to need in the near future.
-
- The class is \e not straightforward to use (although it is much
- simpler than the native APIs); TQSocket provides much easier to use
- TCP connection facilities. The aim of TQDns is to provide a correct
- and small API to the DNS and nothing more. (We use "correctness"
- to mean that the DNS information is correctly cached, and
- correctly timed out.)
-
- The API comprises a constructor, functions to set the DNS node
- (the domain in DNS terminology) and record type (setLabel() and
- setRecordType()), the corresponding get functions, an isWorking()
- function to determine whether TQDns is working or reading, a
- resultsReady() signal and query functions for the result.
-
- There is one query function for each RecordType, namely
- addresses(), mailServers(), servers(), hostNames() and texts().
- There are also two generic query functions: canonicalName()
- returns the name you'll presumably end up using (the exact meaning
- of this depends on the record type) and qualifiedNames() returns a
- list of the fully qualified names label() maps to.
-
- \sa TQSocket
-*/
-
-/*!
- Constructs a DNS query object with invalid settings for both the
- label and the search type.
-*/
-
-TQDns::TQDns()
-{
- d = new TQDnsPrivate;
- t = None;
-}
-
-
-
-
-/*!
- Constructs a DNS query object that will return record type \a rr
- information about \a label.
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-
- \a rr defaults to \c A, IPv4 addresses.
-*/
-
-TQDns::TQDns( const TQString & label, RecordType rr )
-{
- d = new TQDnsPrivate;
- t = rr;
- setLabel( label );
- setStartQueryTimer(); // start query the next time we enter event loop
-}
-
-
-
-/*!
- Constructs a DNS query object that will return record type \a rr
- information about host address \a address. The label is set to the
- IN-ADDR.ARPA domain name. This is useful in combination with the
- \c Ptr record type (e.g. if you want to look up a hostname for a
- given address).
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-
- \a rr defaults to \c Ptr, that maps addresses to hostnames.
-*/
-
-TQDns::TQDns( const TQHostAddress & address, RecordType rr )
-{
- d = new TQDnsPrivate;
- t = rr;
- setLabel( address );
- setStartQueryTimer(); // start query the next time we enter event loop
-}
-
-
-
-
-/*!
- Destroys the DNS query object and frees its allocated resources.
-*/
-
-TQDns::~TQDns()
-{
- if ( globalManager ) {
- uint q = 0;
- TQDnsManager * m = globalManager;
- while( q < m->queries.size() ) {
- TQDnsQuery * query=m->queries[q];
- if ( query && query->dns )
- (void)query->dns->take( (void*) this );
- q++;
- }
-
- }
-
- delete d;
- d = 0;
-}
-
-
-
-
-/*!
- Sets this DNS query object to query for information about \a
- label.
-
- This does not change the recordType(), but its isWorking() status
- will probably change as a result.
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-*/
-
-void TQDns::setLabel( const TQString & label )
-{
- l = label;
- d->noNames = false;
-
- // construct a list of qualified names
- n.clear();
- if ( l.length() > 1 && l[(int)l.length()-1] == QLatin1Char('.') ) {
- n.append( TQT_TQSTRING(l.left( l.length()-1 )).lower() );
- } else {
- int i = l.length();
- int dots = 0;
- const int maxDots = 2;
- while( i && dots < maxDots ) {
- if ( l[--i] == QLatin1Char('.') )
- dots++;
- }
- if ( dots < maxDots ) {
- (void)TQDnsManager::manager(); // create a TQDnsManager, if it is not already there
- TQStrListIterator it( *theDomains );
- const char * dom;
- while( (dom=it.current()) != 0 ) {
- ++it;
- n.append( l.lower() + QLatin1Char('.') + TQLatin1String(dom) );
- }
- }
- n.append( l.lower() );
- }
-
-#if defined(Q_DNS_SYNCHRONOUS)
- if ( d->noEventLoop ) {
- doSynchronousLookup();
- } else {
- setStartQueryTimer(); // start query the next time we enter event loop
- }
-#else
- setStartQueryTimer(); // start query the next time we enter event loop
-#endif
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::setLabel: %d address(es) for %s", n.count(), l.ascii() );
- int i = 0;
- for( i = 0; i < (int)n.count(); i++ )
- qDebug( "TQDns::setLabel: %d: %s", i, n[i].ascii() );
-#endif
-}
-
-
-/*!
- \overload
-
- Sets this DNS query object to query for information about the host
- address \a address. The label is set to the IN-ADDR.ARPA domain
- name. This is useful in combination with the \c Ptr record type
- (e.g. if you want to look up a hostname for a given address).
-*/
-
-void TQDns::setLabel( const TQHostAddress & address )
-{
- setLabel( toInAddrArpaDomain( address ) );
-}
-
-
-/*!
- \fn TQStringList TQDns::qualifiedNames() const
-
- Returns a list of the fully qualified names label() maps to.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 0
-
-*/
-
-
-/*!
- \fn TQString TQDns::label() const
-
- Returns the domain name for which this object returns information.
-
- \sa setLabel()
-*/
-
-/*!
- \enum TQDns::RecordType
-
- This enum type defines the record types TQDns can handle. The DNS
- provides many more; these are the ones we've judged to be in
- current use, useful for GUI programs and important enough to
- support right away:
-
- \value None No information. This exists only so that TQDns can
- have a default.
-
- \value A IPv4 addresses. By far the most common type.
-
- \value Aaaa IPv6 addresses. So far mostly unused.
-
- \value Mx Mail eXchanger names. Used for mail delivery.
-
- \value Srv SeRVer names. Generic record type for finding
- servers. So far mostly unused.
-
- \value Cname Canonical names. Maps from nicknames to the true
- name (the canonical name) for a host.
-
- \value Ptr name PoinTeRs. Maps from IPv4 or IPv6 addresses to hostnames.
-
- \value Txt arbitrary TeXT for domains.
-
- We expect that some support for the
- \l{http://www.rfc-editor.org/rfc/rfc2535.txt}{RFC 2535}
- extensions will be added in future versions.
-*/
-
-/*!
- Sets this object to query for record type \a rr records.
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-
- \sa RecordType
-*/
-
-void TQDns::setRecordType( RecordType rr )
-{
- t = rr;
- d->noNames = false;
- setStartQueryTimer(); // start query the next time we enter event loop
-}
-
-/*!
- \internal
-
- Private slot for starting the query.
-*/
-void TQDns::startQuery()
-{
- // isWorking() starts the query (if necessary)
- if ( !isWorking() )
- emit resultsReady();
-}
-
-/*!
- The three functions TQDns::TQDns(TQString, RecordType),
- TQDns::setLabel() and TQDns::setRecordType() may start a DNS lookup.
- This function handles setting up the single shot timer.
-*/
-void TQDns::setStartQueryTimer()
-{
-#if defined(Q_DNS_SYNCHRONOUS)
- if ( !d->queryTimer && !d->noEventLoop )
-#else
- if ( !d->queryTimer )
-#endif
- {
- // start the query the next time we enter event loop
- d->queryTimer = new TQTimer( this );
- connect( d->queryTimer, TQT_SIGNAL(timeout()),
- this, TQT_SLOT(startQuery()) );
- d->queryTimer->start( 0, true );
- }
-}
-
-/*
- Transforms the host address \a address to the IN-ADDR.ARPA domain
- name. Returns something indeterminate if you're sloppy or
- naughty. This function has an IPv4-specific name, but works for
- IPv6 too.
-*/
-TQString TQDns::toInAddrArpaDomain( const TQHostAddress &address )
-{
- TQString s;
- if ( address.isNull() ) {
- // if the address isn't valid, neither of the other two make
- // cases make sense. better to just return.
- } else if ( address.isIp4Addr() ) {
- Q_UINT32 i = address.ip4Addr();
- s.sprintf( "%d.%d.%d.%d.IN-ADDR.ARPA",
- i & 0xff, (i >> 8) & 0xff, (i>>16) & 0xff, (i>>24) & 0xff );
- } else {
- // RFC 3152. (1886 is deprecated, and clients no longer need to
- // support it, in practice).
- Q_IPV6ADDR i = address.toIPv6Address();
- s = TQLatin1String("ip6.arpa");
- uint b = 0;
- while( b < 16 ) {
- s = TQString::number( i.c[b]%16, 16 ) + QLatin1Char('.') +
- TQString::number( i.c[b]/16, 16 ) + QLatin1Char('.') + s;
- b++;
- }
- }
- return s;
-}
-
-
-/*!
- \fn TQDns::RecordType TQDns::recordType() const
-
- Returns the record type of this DNS query object.
-
- \sa setRecordType() RecordType
-*/
-
-/*!
- \fn void TQDns::resultsReady()
-
- This signal is emitted when results are available for one of the
- qualifiedNames().
-*/
-
-/*!
- Returns true if TQDns is doing a lookup for this object (i.e. if it
- does not already have the necessary information); otherwise
- returns false.
-
- TQDns emits the resultsReady() signal when the status changes to false.
-*/
-
-bool TQDns::isWorking() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::isWorking (%s, %d)", l.ascii(), t );
-#endif
- if ( t == None )
- return false;
-
-#if defined(Q_DNS_SYNCHRONOUS)
- if ( d->noEventLoop )
- return true;
-#endif
-
- TQPtrList<TQDnsRR> * ll = TQDnsDomain::cached( this );
- Q_LONG queries = n.count();
- while( ll->current() != 0 ) {
- if ( ll->current()->nxdomain ) {
- queries--;
- } else {
- delete ll;
- return false;
- }
- ll->next();
- }
- delete ll;
-
- if ( queries <= 0 )
- return false;
- if ( d->noNames )
- return false;
- return true;
-}
-
-
-/*!
- Returns a list of the addresses for this name if this TQDns object
- has a recordType() of TQDns::A or TQDns::Aaaa and the answer
- is available; otherwise returns an empty list.
-
- As a special case, if label() is a valid numeric IP address, this
- function returns that address.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 1
-
-*/
-
-TQValueList<TQHostAddress> TQDns::addresses() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::addresses (%s)", l.ascii() );
-#endif
- TQValueList<TQHostAddress> result;
- if ( t != A && t != Aaaa )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain )
- result.append( rr->address );
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- \class TQDns::MailServer
- \brief The TQDns::MailServer class is described in TQDns::mailServers().
-
- \internal
-*/
-
-/*!
- Returns a list of mail servers if the record type is \c Mx. The
- class TQDns::MailServer contains the following public variables:
- \list
- \i TQString TQDns::MailServer::name
- \i Q_UINT16 TQDns::MailServer::priority
- \endlist
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 2
-
-*/
-TQValueList<TQDns::MailServer> TQDns::mailServers() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::mailServers (%s)", l.ascii() );
-#endif
- TQValueList<TQDns::MailServer> result;
- if ( t != Mx )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- MailServer ms( rr->target, rr->priority );
- result.append( ms );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- \class TQDns::Server
- \brief The TQDns::Server class is described in TQDns::servers().
-
- \internal
-*/
-
-/*!
- Returns a list of servers if the record type is \c Srv. The class
- TQDns::Server contains the following public variables:
- \list
- \i TQString TQDns::Server::name
- \i Q_UINT16 TQDns::Server::priority
- \i Q_UINT16 TQDns::Server::weight
- \i Q_UINT16 TQDns::Server::port
- \endlist
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 3
-*/
-TQValueList<TQDns::Server> TQDns::servers() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::servers (%s)", l.ascii() );
-#endif
- TQValueList<TQDns::Server> result;
- if ( t != Srv )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- Server s( rr->target, rr->priority, rr->weight, rr->port );
- result.append( s );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- Returns a list of host names if the record type is \c Ptr.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 4
-
-*/
-TQStringList TQDns::hostNames() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::hostNames (%s)", l.ascii() );
-#endif
- TQStringList result;
- if ( t != Ptr )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- TQString str( rr->target );
- result.append( str );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- Returns a list of texts if the record type is \c Txt.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 5
-*/
-TQStringList TQDns::texts() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::texts (%s)", l.ascii() );
-#endif
- TQStringList result;
- if ( t != Txt )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- TQString str( rr->text );
- result.append( str );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- Returns the canonical name for this DNS node. (This works
- regardless of what recordType() is set to.)
-
- If the canonical name isn't known, this function returns a null
- string.
-
- The canonical name of a DNS node is its full name, or the full
- name of the target of its CNAME. For example, if l.trolltech.com
- is a CNAME to lillian.troll.no, and the search path for TQDns is
- "trolltech.com", then the canonical name for all of "lillian",
- "l", "lillian.troll.no." and "l.trolltech.com" is
- "lillian.troll.no.".
-*/
-
-TQString TQDns::canonicalName() const
-{
- // the cname should work regardless of the recordType(), so set the record
- // type temporarily to cname when you look at the cache
- TQDns *that = (TQDns*) this; // mutable function
- RecordType oldType = t;
- that->t = Cname;
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( that );
- that->t = oldType;
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain && rr->domain ) {
- delete cached;
- return rr->target;
- }
- cached->next();
- }
- delete cached;
- return TQString();
-}
-
-#if defined(Q_DNS_SYNCHRONOUS)
-/*! \reimp
-*/
-void TQDns::connectNotify( const char *signal )
-{
- if ( d->noEventLoop && qstrcmp(signal,TQT_SIGNAL(resultsReady()) )==0 ) {
- doSynchronousLookup();
- }
-}
-#endif
-
-#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
-
-#if defined(Q_DNS_SYNCHRONOUS)
-void TQDns::doSynchronousLookup()
-{
- // ### not implemented yet
-}
-#endif
-
-// the following typedefs are needed for GetNetworkParams() API call
-#ifndef IP_TYPES_INCLUDED
-#define MAX_HOSTNAME_LEN 128
-#define MAX_DOMAIN_NAME_LEN 128
-#define MAX_SCOPE_ID_LEN 256
-typedef struct {
- char String[4 * 4];
-} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
-typedef struct _IP_ADDR_STRING {
- struct _IP_ADDR_STRING* Next;
- IP_ADDRESS_STRING IpAddress;
- IP_MASK_STRING IpMask;
- DWORD Context;
-} IP_ADDR_STRING, *PIP_ADDR_STRING;
-typedef struct {
- char HostName[MAX_HOSTNAME_LEN + 4] ;
- char DomainName[MAX_DOMAIN_NAME_LEN + 4];
- PIP_ADDR_STRING CurrentDnsServer;
- IP_ADDR_STRING DnsServerList;
- UINT NodeType;
- char ScopeId[MAX_SCOPE_ID_LEN + 4];
- UINT EnableRouting;
- UINT EnableProxy;
- UINT EnableDns;
-} FIXED_INFO, *PFIXED_INFO;
-#endif
-typedef DWORD (WINAPI *GNP)( PFIXED_INFO, PULONG );
-
-// ### FIXME: this code is duplicated in qfiledialog.cpp
-static TQString getWindowsRegString(HKEY key, const TQString &subKey)
-{
- TQString s;
-
- wchar_t buf[1024];
- DWORD bsz = sizeof(buf) / sizeof(wchar_t);
- int r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)buf, &bsz);
- if (r == ERROR_SUCCESS) {
- s = TQString::fromWCharArray(buf);
- } else if (r == ERROR_MORE_DATA) {
- char *ptr = new char[bsz+1];
- r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)ptr, &bsz);
- if (r == ERROR_SUCCESS)
- s = TQLatin1String(ptr);
- delete [] ptr;
- }
-
- return s;
-}
-
-static bool getDnsParamsFromRegistry( const TQString &path,
- TQString *domainName, TQString *nameServer, TQString *searchList )
-{
- HKEY k;
- int r = RegOpenKeyEx( HKEY_LOCAL_MACHINE, (wchar_t*)path.utf16(), 0, KEY_READ, &k );
-
- if ( r == ERROR_SUCCESS ) {
- *domainName = getWindowsRegString( k, TQLatin1String("DhcpDomain") );
- if ( domainName->isEmpty() )
- *domainName = getWindowsRegString( k, TQLatin1String("Domain") );
-
- *nameServer = getWindowsRegString( k, TQLatin1String("DhcpNameServer") );
- if ( nameServer->isEmpty() )
- *nameServer = getWindowsRegString( k, TQLatin1String("NameServer") );
-
- *searchList = getWindowsRegString( k, TQLatin1String("SearchList") );
- }
- RegCloseKey( k );
- return r == ERROR_SUCCESS;
-}
-
-void TQDns::doResInit()
-{
- char separator = 0;
-
- if ( theNs )
- delete theNs;
- theNs = new TQPtrList<TQHostAddress>;
- theNs->setAutoDelete( true );
- theDomains = new TQStrList( true );
- theDomains->setAutoDelete( true );
-
- TQString domainName, nameServer, searchList;
-
- bool gotNetworkParams = false;
- // try the API call GetNetworkParams() first and use registry lookup only
- // as a fallback
- HINSTANCE hinstLib = LoadLibrary( L"iphlpapi" );
- if ( hinstLib != 0 ) {
-#ifdef Q_OS_WINCE
- GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, L"GetNetworkParams" );
-#else
- GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, "GetNetworkParams" );
-#endif
- if ( getNetworkParams != 0 ) {
- ULONG l = 0;
- DWORD res;
- res = getNetworkParams( 0, &l );
- if ( res == ERROR_BUFFER_OVERFLOW ) {
- FIXED_INFO *finfo = (FIXED_INFO*)new char[l];
- res = getNetworkParams( finfo, &l );
- if ( res == ERROR_SUCCESS ) {
- domainName = TQLatin1String(finfo->DomainName);
- nameServer = TQLatin1String("");
- IP_ADDR_STRING *dnsServer = &finfo->DnsServerList;
- while ( dnsServer != 0 ) {
- nameServer += TQLatin1String(dnsServer->IpAddress.String);
- dnsServer = dnsServer->Next;
- if ( dnsServer != 0 )
- nameServer += QLatin1Char(' ');
- }
- searchList = TQLatin1String("");
- separator = ' ';
- gotNetworkParams = true;
- }
- delete[] finfo;
- }
- }
- FreeLibrary( hinstLib );
- }
- if ( !gotNetworkParams ) {
- if ( getDnsParamsFromRegistry(
- TQLatin1String("System\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
- &domainName, &nameServer, &searchList )) {
- separator = ' ';
- } else {
- // Could not access the TCP/IP parameters
- domainName = TQLatin1String("");
- nameServer = TQLatin1String("127.0.0.1");
- searchList = TQLatin1String("");
- separator = ' ';
- }
- }
-
- nameServer = nameServer.simplifyWhiteSpace();
- int first, last;
- if ( !nameServer.isEmpty() ) {
- first = 0;
- do {
- last = nameServer.find( QLatin1Char(separator), first );
- if ( last < 0 )
- last = nameServer.length();
- TQDns tmp( nameServer.mid( first, last-first ), TQDns::A );
- TQValueList<TQHostAddress> address = tmp.addresses();
- Q_LONG i = address.count();
- while( i )
- theNs->append( new TQHostAddress(address[--i]) );
- first = last+1;
- } while( first < (int)nameServer.length() );
- }
-
- searchList += QLatin1Char(' ') + domainName;
- searchList = searchList.simplifyWhiteSpace().lower();
- first = 0;
- do {
- last = searchList.find( QLatin1Char(separator), first );
- if ( last < 0 )
- last = searchList.length();
- theDomains->append( qstrdup( searchList.mid( first, last-first ).latin1() ) );
- first = last+1;
- } while( first < (int)searchList.length() );
-}
-
-#elif defined(Q_OS_UNIX)
-
-#if defined(Q_DNS_SYNCHRONOUS)
-void TQDns::doSynchronousLookup()
-{
- if ( t!=None && !l.isEmpty() ) {
- TQValueListIterator<TQString> it = n.begin();
- TQValueListIterator<TQString> end = n.end();
- int type;
- switch( t ) {
- case TQDns::A:
- type = 1;
- break;
- case TQDns::Aaaa:
- type = 28;
- break;
- case TQDns::Mx:
- type = 15;
- break;
- case TQDns::Srv:
- type = 33;
- break;
- case TQDns::Cname:
- type = 5;
- break;
- case TQDns::Ptr:
- type = 12;
- break;
- case TQDns::Txt:
- type = 16;
- break;
- default:
- type = (char)255; // any
- break;
- }
- while( it != end ) {
- TQString s = *it;
- it++;
- TQByteArray ba( 512 );
- int len = res_search( s.latin1(), 1, type, (uchar*)ba.data(), ba.size() );
- if ( len > 0 ) {
- ba.resize( len );
-
- TQDnsQuery * query = new TQDnsQuery;
- query->started = now();
- query->id = ++theId;
- query->t = t;
- query->l = s;
- TQDnsAnswer a( ba, query );
- a.parse();
- } else if ( len == -1 ) {
- // res_search error
- }
- }
- emit resultsReady();
- }
-}
-#endif
-
-#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
-#define Q_MODERN_RES_API
-#endif
-
-void TQDns::doResInit()
-{
- if ( theNs )
- return;
- theNs = new TQPtrList<TQHostAddress>;
- theNs->setAutoDelete( true );
- theDomains = new TQStrList( true );
- theDomains->setAutoDelete( true );
-
- // read resolv.conf manually.
- QFile resolvConf(TQLatin1String("/etc/resolv.conf"));
- if (resolvConf.open(QIODevice::ReadOnly)) {
- QTextStream stream( &resolvConf );
- TQString line;
-
- while ( !stream.atEnd() ) {
- line = stream.readLine();
- TQStringList list = TQStringList::split( TQLatin1String(" "), line );
- if( line.startsWith( QLatin1Char('#') ) || list.size() < 2 )
- continue;
- const TQString type = list[0].lower();
-
- if ( type == TQLatin1String("nameserver") ) {
- TQHostAddress *address = new TQHostAddress();
- if ( address->setAddress( TQString(list[1]) ) ) {
- // only add ipv6 addresses from resolv.conf if
- // this host supports ipv6.
- if ( address->isIPv4Address() || ipv6support )
- theNs->append( address );
- else
- delete address;
- } else {
- delete address;
- }
- } else if ( type == TQLatin1String("search") ) {
- TQStringList srch = TQStringList::split( TQLatin1String(" "), list[1] );
- for ( TQStringList::Iterator i = srch.begin(); i != srch.end(); ++i )
- theDomains->append( (*i).lower().local8Bit() );
-
- } else if ( type == TQLatin1String("domain") ) {
- theDomains->append( list[1].lower().local8Bit() );
- }
- }
- }
-
- if (theNs->isEmpty()) {
-#if defined(Q_MODERN_RES_API)
- struct __res_state res;
- res_ninit( &res );
- int i;
- // find the name servers to use
- for( i=0; i < MAXNS && i < res.nscount; i++ )
- theNs->append( new TQHostAddress( ntohl( res.nsaddr_list[i].sin_addr.s_addr ) ) );
-# if defined(MAXDFLSRCH)
- for( i=0; i < MAXDFLSRCH; i++ ) {
- if ( res.dnsrch[i] && *(res.dnsrch[i]) )
- theDomains->append( TQT_TQSTRING(TQString::fromLatin1( res.dnsrch[i] )).lower().local8Bit() );
- else
- break;
- }
-# endif
- if ( *res.defdname )
- theDomains->append( TQT_TQSTRING(TQString::fromLatin1( res.defdname )).lower().local8Bit() );
-#else
- res_init();
- int i;
- // find the name servers to use
- for( i=0; i < MAXNS && i < _res.nscount; i++ )
- theNs->append( new TQHostAddress( ntohl( _res.nsaddr_list[i].sin_addr.s_addr ) ) );
-# if defined(MAXDFLSRCH)
- for( i=0; i < MAXDFLSRCH; i++ ) {
- if ( _res.dnsrch[i] && *(_res.dnsrch[i]) )
- theDomains->append( TQString::fromLatin1( _res.dnsrch[i] ).lower().local8Bit() );
- else
- break;
- }
-# endif
- if ( *_res.defdname )
- theDomains->append( TQString::fromLatin1( _res.defdname ).lower().local8Bit() );
-#endif
-
- // the code above adds "0.0.0.0" as a name server at the slightest
- // hint of trouble. so remove those again.
- theNs->first();
- while( theNs->current() ) {
- if ( theNs->current()->isNull() )
- delete theNs->take();
- else
- theNs->next();
- }
- }
-
- QFile hosts( TQString::fromLatin1( "/etc/hosts" ) );
- if ( hosts.open( QIODevice::ReadOnly ) ) {
- // read the /etc/hosts file, creating long-life A and PTR RRs
- // for the things we find.
- QTextStream i( &hosts );
- TQString line;
- while( !i.atEnd() ) {
- line = TQT_TQSTRING(i.readLine()).simplifyWhiteSpace().lower();
- uint n = 0;
- while( (int) n < line.length() && line[(int)n] != QLatin1Char('#') )
- n++;
- line.truncate( n );
- n = 0;
- while( (int) n < line.length() && !line[(int)n].isSpace() )
- n++;
- TQString ip = line.left( n );
- TQHostAddress a;
- a.setAddress( ip );
- if ( ( a.isIPv4Address() || a.isIPv6Address() ) && !a.isNull() ) {
- bool first = true;
- line = line.mid( n+1 );
- n = 0;
- while( (int) n < line.length() && !line[(int)n].isSpace() )
- n++;
- TQString hostname = line.left( n );
- // ### in case of bad syntax, hostname is invalid. do we care?
- if ( n ) {
- TQDnsRR * rr = new TQDnsRR( hostname );
- if ( a.isIPv4Address() )
- rr->t = TQDns::A;
- else
- rr->t = TQDns::Aaaa;
- rr->address = a;
- rr->deleteTime = UINT_MAX;
- rr->expireTime = UINT_MAX;
- rr->current = true;
- if ( first ) {
- first = false;
- TQDnsRR * ptr = new TQDnsRR( TQDns::toInAddrArpaDomain( a ) );
- ptr->t = TQDns::Ptr;
- ptr->target = hostname;
- ptr->deleteTime = UINT_MAX;
- ptr->expireTime = UINT_MAX;
- ptr->current = true;
- }
- }
- }
- }
- }
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_DNS
-
-
-#else // USE_QT4
-
-/****************************************************************************
-**
-** Implementation of TQDns class.
-**
-** Created : 991122
-**
-** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqplatformdefs.h"
-
-// POSIX Large File Support redefines open -> open64
-#if defined(open)
-# undef open
-#endif
-
-// POSIX Large File Support redefines truncate -> truncate64
-#if defined(truncate)
-# undef truncate
-#endif
-
-// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
-#if defined(connect)
-# undef connect
-#endif
-
-// UnixWare 7 redefines socket -> _socket
-#if defined(socket)
-# undef socket
-#endif
-
-#include "tqdns.h"
-
-#ifndef TQT_NO_DNS
-
-#include "tqdatetime.h"
-#include "tqdict.h"
-#include "tqptrlist.h"
-#include "tqstring.h"
-#include "tqtimer.h"
-#include "tqapplication.h"
-#include "tqptrvector.h"
-#include "tqstrlist.h"
-#include "tqptrdict.h"
-#include "tqfile.h"
-#include "tqtextstream.h"
-#include "tqsocketdevice.h"
-#include "tqcleanuphandler.h"
-#include <limits.h>
-#ifdef TQ_OS_MAC
-#include "../3rdparty/dlcompat/dlfcn.h"
-#endif
-
-//#define TQDNS_DEBUG
-
-static TQ_UINT16 id; // ### seeded started by now()
-
-
-static TQDateTime * originOfTime = 0;
-
-static TQCleanupHandler<TQDateTime> qdns_cleanup_time;
-
-static TQ_UINT32 now()
-{
- if ( originOfTime )
- return originOfTime->secsTo( TQDateTime::tqcurrentDateTime() );
-
- originOfTime = new TQDateTime( TQDateTime::tqcurrentDateTime() );
- ::id = originOfTime->time().msec() * 60 + originOfTime->time().second();
- qdns_cleanup_time.add( &originOfTime );
- return 0;
-}
-
-
-static TQPtrList<TQHostAddress> * ns = 0;
-static TQStrList * domains = 0;
-static bool ipv6support = FALSE;
-
-static int qdns_res_init()
-{
-#ifdef TQ_OS_MAC
- typedef int (*PtrRes_init)();
- static PtrRes_init ptrRes_init = 0;
- if (!ptrRes_init)
- ptrRes_init = (PtrRes_init)DL_PREFIX(dlsym)(RTLD_NEXT, "res_init");
- if (ptrRes_init)
- return (*ptrRes_init)();
- else
- return -1;
-#elif defined(TQ_OS_UNIX)
- return res_init();
-#else
- return 0; // not called at all on Windows.
-#endif
-}
-
-
-class TQDnsPrivate {
-public:
- TQDnsPrivate() : queryTimer( 0 ), noNames(FALSE)
- {
-#if defined(TQ_DNS_SYNCHRONOUS)
-#if defined(TQ_OS_UNIX)
- noEventLoop = tqApp==0 || tqApp->loopLevel()==0;
-#else
- noEventLoop = FALSE;
-#endif
-#endif
- }
- ~TQDnsPrivate()
- {
- delete queryTimer;
- }
-private:
- TQTimer * queryTimer;
- bool noNames;
-#if defined(TQ_DNS_SYNCHRONOUS)
- bool noEventLoop;
-#endif
-
- friend class TQDns;
- friend class TQDnsAnswer;
-};
-
-
-class TQDnsRR;
-class TQDnsDomain;
-
-
-
-// TQDnsRR is the class used to store a single RR. TQDnsRR can store
-// all of the supported RR types. a TQDnsRR is always cached.
-
-// TQDnsRR is mostly constructed from the outside. a but hacky, but
-// permissible since the entire class is internal.
-
-class TQDnsRR {
-public:
- TQDnsRR( const TQString & label );
- ~TQDnsRR();
-
-public:
- TQDnsDomain * domain;
- TQDns::RecordType t;
- bool nxdomain;
- bool current;
- TQ_UINT32 expireTime;
- TQ_UINT32 deleteTime;
- // somewhat space-wasting per-type data
- // a / aaaa
- TQHostAddress address;
- // cname / mx / srv / ptr
- TQString target;
- // mx / srv
- TQ_UINT16 priority;
- // srv
- TQ_UINT16 weight;
- TQ_UINT16 port;
- // txt
- TQString text; // could be overloaded into target...
-private:
-
-};
-
-
-class TQDnsDomain {
-public:
- TQDnsDomain( const TQString & label );
- ~TQDnsDomain();
-
- static void add( const TQString & label, TQDnsRR * );
- static TQPtrList<TQDnsRR> * cached( const TQDns * );
-
- void take( TQDnsRR * );
-
- void sweep( TQ_UINT32 thisSweep );
-
- bool isEmpty() const { return rrs == 0 || rrs->isEmpty(); }
-
- TQString name() const { return l; }
-
-public:
- TQString l;
- TQPtrList<TQDnsRR> * rrs;
-};
-
-
-class TQDnsQuery: public TQTimer { // this inheritance is a very evil hack
-public:
- TQDnsQuery():
- id( 0 ), t( TQDns::None ), step(0), started(0),
- dns( new TQPtrDict<void>(17) ) {}
- ~TQDnsQuery() { delete dns; }
- TQ_UINT16 id;
- TQDns::RecordType t;
- TQString l;
-
- uint step;
- TQ_UINT32 started;
-
- TQPtrDict<void> * dns;
-};
-
-
-
-class TQDnsAnswer {
-public:
- TQDnsAnswer( TQDnsQuery * );
- TQDnsAnswer( const TQByteArray &, TQDnsQuery * );
- ~TQDnsAnswer();
-
- void parse();
- void notify();
-
- bool ok;
-
-private:
- TQDnsQuery * query;
-
- TQ_UINT8 * answer;
- int size;
- int pp;
-
- TQPtrList<TQDnsRR> * rrs;
-
- // convenience
- int next;
- int ttl;
- TQString label;
- TQDnsRR * rr;
-
- TQString readString(bool multipleLabels = TRUE);
- void parseA();
- void parseAaaa();
- void parseMx();
- void parseSrv();
- void parseCname();
- void parsePtr();
- void parseTxt();
- void parseNs();
-};
-
-
-TQDnsRR::TQDnsRR( const TQString & label )
- : domain( 0 ), t( TQDns::None ),
- nxdomain( FALSE ), current( FALSE ),
- expireTime( 0 ), deleteTime( 0 ),
- priority( 0 ), weight( 0 ), port( 0 )
-{
- TQDnsDomain::add( label, this );
-}
-
-
-// not supposed to be deleted except by TQDnsDomain
-TQDnsRR::~TQDnsRR()
-{
- // nothing is necessary
-}
-
-
-// this one just sticks in a NXDomain
-TQDnsAnswer::TQDnsAnswer( TQDnsQuery * query_ )
-{
- ok = TRUE;
-
- answer = 0;
- size = 0;
- query = query_;
- pp = 0;
- rrs = new TQPtrList<TQDnsRR>;
- rrs->setAutoDelete( FALSE );
- next = size;
- ttl = 0;
- label = TQString::null;
- rr = 0;
-
- TQDnsRR * newrr = new TQDnsRR( query->l );
- newrr->t = query->t;
- newrr->deleteTime = query->started + 10;
- newrr->expireTime = query->started + 10;
- newrr->nxdomain = TRUE;
- newrr->current = TRUE;
- rrs->append( newrr );
-}
-
-
-TQDnsAnswer::TQDnsAnswer( const TQByteArray& answer_,
- TQDnsQuery * query_ )
-{
- ok = TRUE;
-
- answer = (TQ_UINT8 *)(answer_.data());
- size = (int)answer_.size();
- query = query_;
- pp = 0;
- rrs = new TQPtrList<TQDnsRR>;
- rrs->setAutoDelete( FALSE );
- next = size;
- ttl = 0;
- label = TQString::null;
- rr = 0;
-}
-
-
-TQDnsAnswer::~TQDnsAnswer()
-{
- if ( !ok && rrs ) {
- TQPtrListIterator<TQDnsRR> it( *rrs );
- TQDnsRR * tmprr;
- while( (tmprr=it.current()) != 0 ) {
- ++it;
- tmprr->t = TQDns::None; // will be deleted soonish
- }
- }
- delete rrs;
-}
-
-
-TQString TQDnsAnswer::readString(bool multipleLabels)
-{
- int p = pp;
- TQString r = TQString::null;
- TQ_UINT8 b;
- for( ;; ) {
- b = 128;
- // Read one character
- if ( p >= 0 && p < size )
- b = answer[p];
-
- switch( b >> 6 ) {
- case 0:
- // b is less than 64
- p++;
-
- // Detect end of data
- if ( b == 0 ) {
- if ( p > pp )
- pp = p;
- return r.isNull() ? TQString( "." ) : r;
- }
-
- // Read a label of size 'b' characters
- if ( !r.isNull() )
- r += '.';
- while( b-- > 0 ) {
- r += TQChar( answer[p] );
- p++;
- }
-
- // Return immediately if we were only supposed to read one
- // label.
- if (!multipleLabels)
- return r;
-
- break;
- default:
- // Ignore unrecognized control character, or p was out of
- // range.
- goto not_ok;
- case 3:
- // Use the next character to determine the relative offset
- // to jump to before continuing the packet parsing.
- int q = ( (answer[p] & 0x3f) << 8 ) + answer[p+1];
-
- if ( q >= pp || q >= p )
- goto not_ok;
- if ( p >= pp )
- pp = p + 2;
- p = q;
- }
- }
-not_ok:
- ok = FALSE;
- return TQString::null;
-}
-
-
-
-void TQDnsAnswer::parseA()
-{
- if ( next != pp + 4 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN A for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::A;
- rr->address = TQHostAddress( ( answer[pp+0] << 24 ) +
- ( answer[pp+1] << 16 ) +
- ( answer[pp+2] << 8 ) +
- ( answer[pp+3] ) );
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN A %s (ttl %d)", label.ascii(),
- rr->address.toString().ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseAaaa()
-{
- if ( next != pp + 16 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN Aaaa for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Aaaa;
- rr->address = TQHostAddress( answer+pp );
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN Aaaa %s (ttl %d)", label.ascii(),
- rr->address.toString().ascii(), ttl );
-#endif
-}
-
-
-
-void TQDnsAnswer::parseMx()
-{
- if ( next < pp + 2 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN MX for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->priority = (answer[pp] << 8) + answer[pp+1];
- pp += 2;
- rr->target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad string in MX for %s", label.ascii() );
-#endif
- return;
- }
- rr->t = TQDns::Mx;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN MX %d %s (ttl %d)", label.ascii(),
- rr->priority, rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseSrv()
-{
- if ( next < pp + 6 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %d bytes long IN SRV for %s",
- next - pp, label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->priority = (answer[pp] << 8) + answer[pp+1];
- rr->weight = (answer[pp+2] << 8) + answer[pp+3];
- rr->port = (answer[pp+4] << 8) + answer[pp+5];
- pp += 6;
- rr->target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad string in SRV for %s", label.ascii() );
-#endif
- return;
- }
- rr->t = TQDns::Srv;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN SRV %d %d %d %s (ttl %d)", label.ascii(),
- rr->priority, rr->weight, rr->port, rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseCname()
-{
- TQString target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Cname;
- rr->target = target;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN CNAME %s (ttl %d)", label.ascii(),
- rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseNs()
-{
- TQString target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
-#endif
- return;
- }
-
- // parse, but ignore
-
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN NS %s (ttl %d)", label.ascii(),
- target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parsePtr()
-{
- TQString target = readString().lower();
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad PTR for for %s", label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Ptr;
- rr->target = target;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN PTR %s (ttl %d)", label.ascii(),
- rr->target.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parseTxt()
-{
- TQString text = readString(FALSE);
- if ( !ok ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw bad TXT for for %s", label.ascii() );
-#endif
- return;
- }
-
- rr = new TQDnsRR( label );
- rr->t = TQDns::Txt;
- rr->text = text;
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns: saw %s IN TXT \"%s\" (ttl %d)", label.ascii(),
- rr->text.ascii(), ttl );
-#endif
-}
-
-
-void TQDnsAnswer::parse()
-{
- // okay, do the work...
- if ( (answer[2] & 0x78) != 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: answer to wrong query type (%d)", answer[1] );
-#endif
- ok = FALSE;
- return;
- }
-
- // AA
- bool aa = (answer[2] & 4) != 0;
-
- // TC
- if ( (answer[2] & 2) != 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: truncated answer; pressing on" );
-#endif
- }
-
- // RD
- bool rd = (answer[2] & 1) != 0;
-
- // we don't test RA
- // we don't test the MBZ fields
-
- if ( (answer[3] & 0x0f) == 3 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: saw NXDomain for %s", query->l.ascii() );
-#endif
- // NXDomain. cache that for one minute.
- rr = new TQDnsRR( query->l );
- rr->t = query->t;
- rr->deleteTime = query->started + 60;
- rr->expireTime = query->started + 60;
- rr->nxdomain = TRUE;
- rr->current = TRUE;
- rrs->append( rr );
- return;
- }
-
- if ( (answer[3] & 0x0f) != 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: error code %d", answer[3] & 0x0f );
-#endif
- ok = FALSE;
- return;
- }
-
- int qdcount = ( answer[4] << 8 ) + answer[5];
- int ancount = ( answer[6] << 8 ) + answer[7];
- int nscount = ( answer[8] << 8 ) + answer[9];
- int adcount = (answer[10] << 8 ) +answer[11];
-
- pp = 12;
-
- // read query
- while( qdcount > 0 && pp < size ) {
- // should I compare the string against query->l?
- (void)readString();
- if ( !ok )
- return;
- pp += 4;
- qdcount--;
- }
-
- // answers and stuff
- int rrno = 0;
- // if we parse the answer completely, but there are no answers,
- // ignore the entire thing.
- int answers = 0;
- while( ( rrno < ancount ||
- ( ok && answers >0 && rrno < ancount + nscount + adcount ) ) &&
- pp < size ) {
- label = readString().lower();
- if ( !ok )
- return;
- int rdlength = 0;
- if ( pp + 10 <= size )
- rdlength = ( answer[pp+8] << 8 ) + answer[pp+9];
- if ( pp + 10 + rdlength > size ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: ran out of stuff to parse (%d+%d>%d (%d)",
- pp, rdlength, size, rrno < ancount );
-#endif
- // if we're still in the AN section, we should go back and
- // at least down the TTLs. probably best to tqinvalidate
- // the results.
- // the rrs list is good for this
- ok = ( rrno < ancount );
- return;
- }
- uint type, clas;
- type = ( answer[pp+0] << 8 ) + answer[pp+1];
- clas = ( answer[pp+2] << 8 ) + answer[pp+3];
- ttl = ( answer[pp+4] << 24 ) + ( answer[pp+5] << 16 ) +
- ( answer[pp+6] << 8 ) + answer[pp+7];
- pp = pp + 10;
- if ( clas != 1 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: class %d (not internet) for %s",
- clas, label.isNull() ? "." : label.ascii() );
-#endif
- } else {
- next = pp + rdlength;
- rr = 0;
- switch( type ) {
- case 1:
- parseA();
- break;
- case 28:
- parseAaaa();
- break;
- case 15:
- parseMx();
- break;
- case 33:
- parseSrv();
- break;
- case 5:
- parseCname();
- break;
- case 12:
- parsePtr();
- break;
- case 16:
- parseTxt();
- break;
- case 2:
- parseNs();
- break;
- default:
- // something we don't know
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: type %d for %s", type,
- label.isNull() ? "." : label.ascii() );
-#endif
- break;
- }
- if ( rr ) {
- rr->deleteTime = 0;
- if ( ttl > 0 )
- rr->expireTime = query->started + ttl;
- else
- rr->expireTime = query->started + 20;
- if ( rrno < ancount ) {
- answers++;
- rr->deleteTime = rr->expireTime;
- }
- rr->current = TRUE;
- rrs->append( rr );
- }
- }
- if ( !ok )
- return;
- pp = next;
- next = size;
- rrno++;
- }
- if ( answers == 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: answer contained no answers" );
-#endif
- ok = ( aa && rd );
- }
-
- // now go through the list and mark all the As that are referenced
- // by something we care about. we want to cache such As.
- rrs->first();
- TQDict<void> used( 17 );
- used.setAutoDelete( FALSE );
- while( (rr=rrs->current()) != 0 ) {
- rrs->next();
- if ( rr->target.length() && rr->deleteTime > 0 && rr->current )
- used.insert( rr->target, (void*)42 );
- if ( ( rr->t == TQDns::A || rr->t == TQDns::Aaaa ) &&
- used.find( rr->domain->name() ) != 0 )
- rr->deleteTime = rr->expireTime;
- }
-
- // next, for each RR, delete any older RRs that are equal to it
- rrs->first();
- while( (rr=rrs->current()) != 0 ) {
- rrs->next();
- if ( rr && rr->domain && rr->domain->rrs ) {
- TQPtrList<TQDnsRR> * drrs = rr->domain->rrs;
- drrs->first();
- TQDnsRR * older;
- while( (older=drrs->current()) != 0 ) {
- if ( older != rr &&
- older->t == rr->t &&
- older->nxdomain == rr->nxdomain &&
- older->address == rr->address &&
- older->target == rr->target &&
- older->priority == rr->priority &&
- older->weight == rr->weight &&
- older->port == rr->port &&
- older->text == rr->text ) {
- // well, it's equal, but it's not the same. so we kill it,
- // but use its expiry time.
-#if defined(TQDNS_DEBUG)
- qDebug( "killing off old %d for %s, expire was %d",
- older->t, older->domain->name().latin1(),
- rr->expireTime );
-#endif
- older->t = TQDns::None;
- rr->expireTime = TQMAX( older->expireTime, rr->expireTime );
- rr->deleteTime = TQMAX( older->deleteTime, rr->deleteTime );
- older->deleteTime = 0;
-#if defined(TQDNS_DEBUG)
- qDebug( " adjusted expire is %d", rr->expireTime );
-#endif
- }
- drrs->next();
- }
- }
- }
-
-#if defined(TQDNS_DEBUG)
- //qDebug( "DNS Manager: ()" );
-#endif
-}
-
-
-class TQDnsUgleHack: public TQDns {
-public:
- void ugle( bool emitAnyway=FALSE );
-};
-
-
-void TQDnsAnswer::notify()
-{
- if ( !rrs || !ok || !query || !query->dns )
- return;
-
- TQPtrDict<void> notified;
- notified.setAutoDelete( FALSE );
-
- TQPtrDictIterator<void> it( *query->dns );
- TQDns * dns;
- it.toFirst();
- while( (dns=(TQDns*)(it.current())) != 0 ) {
- ++it;
- if ( notified.find( (void*)dns ) == 0 ) {
- notified.insert( (void*)dns, (void*)42 );
- if ( rrs->count() == 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: found no answers!" );
-#endif
- dns->d->noNames = TRUE;
- ((TQDnsUgleHack*)dns)->ugle( TRUE );
- } else {
- TQStringList n = dns->qualifiedNames();
- if ( query && n.contains(query->l) )
- ((TQDnsUgleHack*)dns)->ugle();
-#if defined(TQDNS_DEBUG)
- else
- qDebug( "DNS Manager: DNS thing %s not notified for %s",
- dns->label().ascii(), query->l.ascii() );
-#endif
- }
- }
- }
-}
-
-
-//
-//
-// TQDnsManager
-//
-//
-
-
-class TQDnsManager: public TQDnsSocket {
-private:
-public: // just to silence the moronic g++.
- TQDnsManager();
- ~TQDnsManager();
-public:
- static TQDnsManager * manager();
-
- TQDnsDomain * domain( const TQString & );
-
- void transmitQuery( TQDnsQuery * );
- void transmitQuery( int );
-
- // reimplementation of the Q_SLOTS
- void cleanCache();
- void retransmit();
- void answer();
-
-public:
- TQPtrVector<TQDnsQuery> queries;
- TQDict<TQDnsDomain> cache;
- TQSocketDevice * ipv4Socket;
-#if !defined (TQT_NO_IPV6)
- TQSocketDevice * ipv6Socket;
-#endif
-};
-
-
-
-static TQDnsManager * globalManager = 0;
-
-static void cleanupDns()
-{
- delete globalManager;
- globalManager = 0;
-}
-
-TQDnsManager * TQDnsManager::manager()
-{
- if ( !globalManager ) {
- qAddPostRoutine(cleanupDns);
- new TQDnsManager();
- }
- return globalManager;
-}
-
-
-void TQDnsUgleHack::ugle( bool emitAnyway)
-{
- if ( emitAnyway || !isWorking() ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: status change for %s (type %d)",
- label().ascii(), recordType() );
-#endif
- emit resultsReady();
- }
-}
-
-
-TQDnsManager::TQDnsManager()
- : TQDnsSocket( tqApp, "Internal DNS manager" ),
- queries( TQPtrVector<TQDnsQuery>( 0 ) ),
- cache( TQDict<TQDnsDomain>( 83, FALSE ) ),
- ipv4Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv4, 0 ) )
-#if !defined (TQT_NO_IPV6)
- , ipv6Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv6, 0 ) )
-#endif
-{
- cache.setAutoDelete( TRUE );
- globalManager = this;
-
- TQTimer * sweepTimer = new TQTimer( this );
- sweepTimer->start( 1000 * 60 * 3 );
- connect( sweepTimer, TQT_SIGNAL(timeout()),
- this, TQT_SLOT(cleanCache()) );
-
- TQSocketNotifier * rn4 = new TQSocketNotifier( ipv4Socket->socket(),
- TQSocketNotifier::Read,
- TQT_TQOBJECT(this), "dns IPv4 socket watcher" );
- ipv4Socket->setAddressReusable( FALSE );
- ipv4Socket->setBlocking( FALSE );
- connect( rn4, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
-
-#if !defined (TQT_NO_IPV6)
- // Don't connect the IPv6 socket notifier if the host does not
- // support IPv6.
- if ( ipv6Socket->socket() != -1 ) {
- TQSocketNotifier * rn6 = new TQSocketNotifier( ipv6Socket->socket(),
- TQSocketNotifier::Read,
- TQT_TQOBJECT(this), "dns IPv6 socket watcher" );
-
- ipv6support = TRUE;
- ipv6Socket->setAddressReusable( FALSE );
- ipv6Socket->setBlocking( FALSE );
- connect( rn6, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
- }
-#endif
-
- if ( !ns )
- TQDns::doResInit();
-
- // O(n*n) stuff here. but for 3 and 6, O(n*n) with a low k should
- // be perfect. the point is to eliminate any duplicates that
- // might be hidden in the lists.
- TQPtrList<TQHostAddress> * ns = new TQPtrList<TQHostAddress>;
-
- ::ns->first();
- TQHostAddress * h;
- while( (h=::ns->current()) != 0 ) {
- ns->first();
- while( ns->current() != 0 && !(*ns->current() == *h) )
- ns->next();
- if ( !ns->current() ) {
- ns->append( new TQHostAddress(*h) );
-#if defined(TQDNS_DEBUG)
- qDebug( "using name server %s", h->toString().latin1() );
- } else {
- qDebug( "skipping address %s", h->toString().latin1() );
-#endif
- }
- ::ns->next();
- }
-
- delete ::ns;
- ::ns = ns;
- ::ns->setAutoDelete( TRUE );
-
- TQStrList * domains = new TQStrList( TRUE );
-
- ::domains->first();
- const char * s;
- while( (s=::domains->current()) != 0 ) {
- domains->first();
- while( domains->current() != 0 && qstrcmp( domains->current(), s ) )
- domains->next();
- if ( !domains->current() ) {
- domains->append( s );
-#if defined(TQDNS_DEBUG)
- qDebug( "searching domain %s", s );
- } else {
- qDebug( "skipping domain %s", s );
-#endif
- }
- ::domains->next();
- }
-
- delete ::domains;
- ::domains = domains;
- ::domains->setAutoDelete( TRUE );
-}
-
-
-TQDnsManager::~TQDnsManager()
-{
- if ( globalManager )
- globalManager = 0;
- queries.setAutoDelete( TRUE );
- cache.setAutoDelete( TRUE );
- delete ipv4Socket;
-#if !defined (TQT_NO_IPV6)
- delete ipv6Socket;
-#endif
-}
-
-static TQ_UINT32 lastSweep = 0;
-
-void TQDnsManager::cleanCache()
-{
- bool again = FALSE;
- TQDictIterator<TQDnsDomain> it( cache );
- TQDnsDomain * d;
- TQ_UINT32 thisSweep = now();
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDnsManager::cleanCache(: Called, time is %u, last was %u",
- thisSweep, lastSweep );
-#endif
-
- while( (d=it.current()) != 0 ) {
- ++it;
- d->sweep( thisSweep ); // after this, d may be empty
- if ( !again )
- again = !d->isEmpty();
- }
- if ( !again )
- delete this;
- lastSweep = thisSweep;
-}
-
-
-void TQDnsManager::retransmit()
-{
- const TQObject * o = sender();
- if ( o == 0 || globalManager == 0 || this != globalManager )
- return;
- uint q = 0;
- while( q < queries.size() && queries[q] != o )
- q++;
- if ( q < queries.size() )
- transmitQuery( q );
-}
-
-
-void TQDnsManager::answer()
-{
- TQByteArray a( 16383 ); // large enough for anything, one suspects
-
- int r;
-#if defined (TQT_NO_IPV6)
- r = ipv4Socket->readBlock(a.data(), a.size());
-#else
- if (((TQSocketNotifier *)sender())->socket() == ipv4Socket->socket())
- r = ipv4Socket->readBlock(a.data(), a.size());
- else
- r = ipv6Socket->readBlock(a.data(), a.size());
-#endif
-#if defined(TQDNS_DEBUG)
-#if !defined (TQT_NO_IPV6)
- qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
- useIpv4Socket ? ipv4Socket->peerAddress().toString().ascii()
- : ipv6Socket->peerAddress().toString().ascii(),
- useIpv4Socket ? ipv4Socket->peerPort() : ipv6Socket->peerPort() );
-#else
- qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
- ipv4Socket->peerAddress().toString().ascii(), ipv4Socket->peerPort());;
-#endif
-#endif
- if ( r < 12 )
- return;
- // maybe we should check that the answer comes from port 53 on one
- // of our name servers...
- a.resize( r );
-
- TQ_UINT16 aid = (((TQ_UINT8)a[0]) << 8) + ((TQ_UINT8)a[1]);
- uint i = 0;
- while( i < queries.size() &&
- !( queries[i] && queries[i]->id == aid ) )
- i++;
- if ( i == queries.size() ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: bad id (0x%04x) %d", aid, i );
-#endif
- return;
- }
-
- // at this point queries[i] is whatever we asked for.
-
- if ( ( (TQ_UINT8)(a[2]) & 0x80 ) == 0 ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: received a query" );
-#endif
- return;
- }
-
- TQDnsQuery * q = queries[i];
- TQDnsAnswer answer( a, q );
- answer.parse();
- if ( answer.ok ) {
- queries.take( i );
- answer.notify();
- delete q;
- }
-}
-
-
-void TQDnsManager::transmitQuery( TQDnsQuery * query_ )
-{
- if ( !query_ )
- return;
-
- uint i = 0;
- while( i < queries.size() && queries[i] != 0 )
- i++;
- if ( i == queries.size() )
- queries.resize( i+1 );
- queries.insert( i, query_ );
- transmitQuery( i );
-}
-
-
-void TQDnsManager::transmitQuery( int i )
-{
- if ( i < 0 || i >= (int)queries.size() )
- return;
- TQDnsQuery * q = queries[i];
-
- if ( q && q->step > 8 ) {
- // okay, we've run out of retransmissions. we fake an NXDomain
- // with a very short life time...
- TQDnsAnswer answer( q );
- answer.notify();
-
- if (globalManager == 0)
- return;
-
- // and then get rid of the query
- queries.take( i );
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: giving up on query 0x%04x", q->id );
-#endif
- delete q;
- TQTimer::singleShot( 0, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
- // and don't process anything more
- return;
- }
-
- if ( q && !q->dns || q->dns->isEmpty() )
- // noone currently wants the answer, so there's no point in
- // retransmitting the query. we keep it, though. an answer may
- // arrive for an earlier query transmission, and if it does we
- // may benefit from caching the result.
- return;
-
- TQByteArray p( 12 + q->l.length() + 2 + 4 );
- if ( p.size() > 500 )
- return; // way over the limit, so don't even try
-
- // header
- // id
- p[0] = (q->id & 0xff00) >> 8;
- p[1] = q->id & 0x00ff;
- p[2] = 1; // recursion desired, rest is 0
- p[3] = 0; // all is 0
- // one query
- p[4] = 0;
- p[5] = 1;
- // no answers, name servers or additional data
- p[6] = p[7] = p[8] = p[9] = p[10] = p[11] = 0;
-
- // the name is composed of several components. each needs to be
- // written by itself... so we write...
- // oh, and we assume that there's no funky characters in there.
- int pp = 12;
- uint lp = 0;
- while( lp < q->l.length() ) {
- int le = q->l.find( '.', lp );
- if ( le < 0 )
- le = q->l.length();
- TQString component = q->l.mid( lp, le-lp );
- p[pp++] = component.length();
- int cp;
- for( cp=0; cp < (int)component.length(); cp++ )
- p[pp++] = component[cp].latin1();
- lp = le + 1;
- }
- // final null
- p[pp++] = 0;
- // query type
- p[pp++] = 0;
- switch( q->t ) {
- case TQDns::A:
- p[pp++] = 1;
- break;
- case TQDns::Aaaa:
- p[pp++] = 28;
- break;
- case TQDns::Mx:
- p[pp++] = 15;
- break;
- case TQDns::Srv:
- p[pp++] = 33;
- break;
- case TQDns::Cname:
- p[pp++] = 5;
- break;
- case TQDns::Ptr:
- p[pp++] = 12;
- break;
- case TQDns::Txt:
- p[pp++] = 16;
- break;
- default:
- p[pp++] = (char)255; // any
- break;
- }
- // query class (always internet)
- p[pp++] = 0;
- p[pp++] = 1;
-
- // if we have no name servers, we should regenerate ns in case
- // name servers have recently been defined (like on windows,
- // plugging/unplugging the network cable will change the name
- // server entries)
- if ( !ns || ns->isEmpty() )
- TQDns::doResInit();
-
- if ( !ns || ns->isEmpty() ) {
- // we don't find any name servers. We fake an NXDomain
- // with a very short life time...
- TQDnsAnswer answer( q );
- answer.notify();
- // and then get rid of the query
- queries.take( i );
-#if defined(TQDNS_DEBUG)
- qDebug( "DNS Manager: no DNS server found on query 0x%04x", q->id );
-#endif
- delete q;
- TQTimer::singleShot( 1000*10, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
- // and don't process anything more
- return;
- }
-
- TQHostAddress receiver = *ns->at( q->step % ns->count() );
- if (receiver.isIPv4Address())
- ipv4Socket->writeBlock( p.data(), pp, receiver, 53 );
-#if !defined (TQT_NO_IPV6)
- else
- ipv6Socket->writeBlock( p.data(), pp, receiver, 53 );
-#endif
-#if defined(TQDNS_DEBUG)
- qDebug( "issuing query 0x%04x (%d) about %s type %d to %s",
- q->id, q->step, q->l.ascii(), q->t,
- ns->at( q->step % ns->count() )->toString().ascii() );
-#endif
- if ( ns->count() > 1 && q->step == 0 && queries.count() == 1 ) {
- // if it's the first time, and we don't have any other
- // outstanding queries, send nonrecursive queries to the other
- // name servers too.
- p[2] = 0;
- TQHostAddress * server;
- while( (server=ns->next()) != 0 ) {
- if (server->isIPv4Address())
- ipv4Socket->writeBlock( p.data(), pp, *server, 53 );
-#if !defined (TQT_NO_IPV6)
- else
- ipv6Socket->writeBlock( p.data(), pp, *server, 53 );
-#endif
-#if defined(TQDNS_DEBUG)
- qDebug( "copying query to %s", server->toString().ascii() );
-#endif
- }
- }
- q->step++;
- // some testing indicates that normal dns queries take up to 0.6
- // seconds. the graph becomes steep around that point, and the
- // number of errors rises... so it seems good to retry at that
- // point.
- q->start( q->step < ns->count() ? 800 : 1500, TRUE );
-}
-
-
-TQDnsDomain * TQDnsManager::domain( const TQString & label )
-{
- TQDnsDomain * d = cache.find( label );
- if ( !d ) {
- d = new TQDnsDomain( label );
- cache.insert( label, d );
- }
- return d;
-}
-
-
-//
-//
-// the TQDnsDomain class looks after and coordinates queries for TQDnsRRs for
-// each domain, and the cached TQDnsRRs. (A domain, in DNS terminology, is
-// a node in the DNS. "no", "trolltech.com" and "lupinella.troll.no" are
-// all domains.)
-//
-//
-
-
-// this is ONLY to be called by TQDnsManager::domain(). noone else.
-TQDnsDomain::TQDnsDomain( const TQString & label )
-{
- l = label;
- rrs = 0;
-}
-
-
-TQDnsDomain::~TQDnsDomain()
-{
- delete rrs;
- rrs = 0;
-}
-
-
-void TQDnsDomain::add( const TQString & label, TQDnsRR * rr )
-{
- TQDnsDomain * d = TQDnsManager::manager()->domain( label );
- if ( !d->rrs ) {
- d->rrs = new TQPtrList<TQDnsRR>;
- d->rrs->setAutoDelete( TRUE );
- }
- d->rrs->append( rr );
- rr->domain = d;
-}
-
-
-TQPtrList<TQDnsRR> * TQDnsDomain::cached( const TQDns * r )
-{
- TQPtrList<TQDnsRR> * l = new TQPtrList<TQDnsRR>;
-
- // test at first if you have to start a query at all
- if ( r->recordType() == TQDns::A ) {
- if ( r->label().lower() == "localhost" ) {
- // undocumented hack. ipv4-specific. also, may be a memory
- // leak? not sure. would be better to do this in doResInit(),
- // anyway.
- TQDnsRR *rrTmp = new TQDnsRR( r->label() );
- rrTmp->t = TQDns::A;
- rrTmp->address = TQHostAddress( 0x7f000001 );
- rrTmp->current = TRUE;
- l->append( rrTmp );
- return l;
- }
- TQHostAddress tmp;
- if ( tmp.setAddress( r->label() ) ) {
- TQDnsRR *rrTmp = new TQDnsRR( r->label() );
- if ( tmp.isIPv4Address() ) {
- rrTmp->t = TQDns::A;
- rrTmp->address = tmp;
- rrTmp->current = TRUE;
- l->append( rrTmp );
- } else {
- rrTmp->nxdomain = TRUE;
- }
- return l;
- }
- }
- if ( r->recordType() == TQDns::Aaaa ) {
- TQHostAddress tmp;
- if ( tmp.setAddress(r->label()) ) {
- TQDnsRR *rrTmp = new TQDnsRR( r->label() );
- if ( tmp.isIPv6Address() ) {
- rrTmp->t = TQDns::Aaaa;
- rrTmp->address = tmp;
- rrTmp->current = TRUE;
- l->append( rrTmp );
- } else {
- rrTmp->nxdomain = TRUE;
- }
- return l;
- }
- }
-
- // if you reach this point, you have to do the query
- TQDnsManager * m = TQDnsManager::manager();
- TQStringList n = r->qualifiedNames();
- TQValueListIterator<TQString> it = n.begin();
- TQValueListIterator<TQString> end = n.end();
- bool nxdomain;
- int cnamecount = 0;
- while( it != end ) {
- TQString s = *it++;
- nxdomain = FALSE;
-#if defined(TQDNS_DEBUG)
- qDebug( "looking at cache for %s (%s %d)",
- s.ascii(), r->label().ascii(), r->recordType() );
-#endif
- TQDnsDomain * d = m->domain( s );
-#if defined(TQDNS_DEBUG)
- qDebug( " - found %d RRs", d && d->rrs ? d->rrs->count() : 0 );
-#endif
- if ( d->rrs )
- d->rrs->first();
- TQDnsRR * rr;
- bool answer = FALSE;
- while( d->rrs && (rr=d->rrs->current()) != 0 ) {
- if ( rr->t == TQDns::Cname && r->recordType() != TQDns::Cname &&
- !rr->nxdomain && cnamecount < 16 ) {
- // cname. if the code is ugly, that may just
- // possibly be because the concept is.
-#if defined(TQDNS_DEBUG)
- qDebug( "found cname from %s to %s",
- r->label().ascii(), rr->target.ascii() );
-#endif
- s = rr->target;
- d = m->domain( s );
- if ( d->rrs )
- d->rrs->first();
- it = end;
- // we've elegantly moved over to whatever the cname
- // pointed to. well, not elegantly. let's remember
- // that we've done something, anyway, so we can't be
- // fooled into an infinte loop as well.
- cnamecount++;
- } else {
- if ( rr->t == r->recordType() ) {
- if ( rr->nxdomain )
- nxdomain = TRUE;
- else
- answer = TRUE;
- l->append( rr );
- if ( rr->deleteTime <= lastSweep ) {
- // we're returning something that'll be
- // deleted soon. we assume that if the client
- // wanted it twice, it'll want it again, so we
- // ask the name server again right now.
- TQDnsQuery * query = new TQDnsQuery;
- query->started = now();
- query->id = ++::id;
- query->t = rr->t;
- query->l = rr->domain->name();
- // note that here, we don't bother about
- // notification. but we do bother about
- // timeouts: we make sure to use high timeouts
- // and few tramsissions.
- query->step = ns->count();
- TQObject::connect( query, TQT_SIGNAL(timeout()),
- TQDnsManager::manager(),
- TQT_SLOT(retransmit()) );
- TQDnsManager::manager()->transmitQuery( query );
- }
- }
- d->rrs->next();
- }
- }
- // if we found a positive result, return quickly
- if ( answer && l->count() ) {
-#if defined(TQDNS_DEBUG)
- qDebug( "found %d records for %s",
- l->count(), r->label().ascii() );
- l->first();
- while( l->current() ) {
- qDebug( " type %d target %s address %s",
- l->current()->t,
- l->current()->target.latin1(),
- l->current()->address.toString().latin1() );
- l->next();
- }
-#endif
- l->first();
- return l;
- }
-
-#if defined(TQDNS_DEBUG)
- if ( nxdomain )
- qDebug( "found NXDomain %s", s.ascii() );
-#endif
-
- if ( !nxdomain ) {
- // if we didn't, and not a negative result either, perhaps
- // we need to transmit a query.
- uint q = 0;
- while ( q < m->queries.size() &&
- ( m->queries[q] == 0 ||
- m->queries[q]->t != r->recordType() ||
- m->queries[q]->l != s ) )
- q++;
- // we haven't done it before, so maybe we should. but
- // wait - if it's an unqualified name, only ask when all
- // the other alternatives are exhausted.
- if ( q == m->queries.size() && ( s.find( '.' ) >= 0 ||
- l->count() >= n.count()-1 ) ) {
- TQDnsQuery * query = new TQDnsQuery;
- query->started = now();
- query->id = ++::id;
- query->t = r->recordType();
- query->l = s;
- query->dns->replace( (void*)r, (void*)r );
- TQObject::connect( query, TQT_SIGNAL(timeout()),
- TQDnsManager::manager(), TQT_SLOT(retransmit()) );
- TQDnsManager::manager()->transmitQuery( query );
- } else if ( q < m->queries.size() ) {
- // if we've found an earlier query for the same
- // domain/type, subscribe to its answer
- m->queries[q]->dns->replace( (void*)r, (void*)r );
- }
- }
- }
- l->first();
- return l;
-}
-
-
-void TQDnsDomain::sweep( TQ_UINT32 thisSweep )
-{
- if ( !rrs )
- return;
-
- TQDnsRR * rr;
- rrs->first();
- while( (rr=rrs->current()) != 0 ) {
- if ( !rr->deleteTime )
- rr->deleteTime = thisSweep; // will hit next time around
-
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::sweep: %s type %d expires %u %u - %s / %s",
- rr->domain->name().latin1(), rr->t,
- rr->expireTime, rr->deleteTime,
- rr->target.latin1(), rr->address.toString().latin1());
-#endif
- if ( rr->current == FALSE ||
- rr->t == TQDns::None ||
- rr->deleteTime <= thisSweep ||
- rr->expireTime <= thisSweep )
- rrs->remove();
- else
- rrs->next();
- }
-
- if ( rrs->isEmpty() ) {
- delete rrs;
- rrs = 0;
- }
-}
-
-
-
-
-// the itsy-bitsy little socket class I don't really need except for
-// so I can subclass and reimplement the Q_SLOTS.
-
-
-TQDnsSocket::TQDnsSocket( TQObject * parent, const char * name )
- : TQObject( parent, name )
-{
- // nothing
-}
-
-
-TQDnsSocket::~TQDnsSocket()
-{
- // nothing
-}
-
-
-void TQDnsSocket::cleanCache()
-{
- // nothing
-}
-
-
-void TQDnsSocket::retransmit()
-{
- // nothing
-}
-
-
-void TQDnsSocket::answer()
-{
- // nothing
-}
-
-
-/*!
- \class TQDns tqdns.h
- \brief The TQDns class provides asynchronous DNS lookups.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \module network
- \ingroup io
-
- Both Windows and Unix provide synchronous DNS lookups; Windows
- provides some asynchronous support too. At the time of writing
- neither operating system provides asynchronous support for
- anything other than hostname-to-address mapping.
-
- TQDns rectifies this shortcoming, by providing asynchronous caching
- lookups for the record types that we expect modern GUI
- applications to need in the near future.
-
- The class is \e not straightforward to use (although it is much
- simpler than the native APIs); TQSocket provides much easier to use
- TCP connection facilities. The aim of TQDns is to provide a correct
- and small API to the DNS and nothing more. (We use "correctness"
- to mean that the DNS information is correctly cached, and
- correctly timed out.)
-
- The API comprises a constructor, functions to set the DNS node
- (the domain in DNS terminology) and record type (setLabel() and
- setRecordType()), the corresponding get functions, an isWorking()
- function to determine whether TQDns is working or reading, a
- resultsReady() signal and query functions for the result.
-
- There is one query function for each RecordType, namely
- addresses(), mailServers(), servers(), hostNames() and texts().
- There are also two generic query functions: canonicalName()
- returns the name you'll presumably end up using (the exact meaning
- of this depends on the record type) and qualifiedNames() returns a
- list of the fully qualified names label() maps to.
-
- \sa TQSocket
-*/
-
-/*!
- Constructs a DNS query object with invalid settings for both the
- label and the search type.
-*/
-
-TQDns::TQDns()
-{
- d = new TQDnsPrivate;
- t = None;
-}
-
-
-
-
-/*!
- Constructs a DNS query object that will return record type \a rr
- information about \a label.
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-
- \a rr defaults to \c A, IPv4 addresses.
-*/
-
-TQDns::TQDns( const TQString & label, RecordType rr )
-{
- d = new TQDnsPrivate;
- t = rr;
- setLabel( label );
- setStartQueryTimer(); // start query the next time we enter event loop
-}
-
-
-
-/*!
- Constructs a DNS query object that will return record type \a rr
- information about host address \a address. The label is set to the
- IN-ADDR.ARPA domain name. This is useful in combination with the
- \c Ptr record type (e.g. if you want to look up a hostname for a
- given address).
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-
- \a rr defaults to \c Ptr, that maps addresses to hostnames.
-*/
-
-TQDns::TQDns( const TQHostAddress & address, RecordType rr )
-{
- d = new TQDnsPrivate;
- t = rr;
- setLabel( address );
- setStartQueryTimer(); // start query the next time we enter event loop
-}
-
-
-
-
-/*!
- Destroys the DNS query object and frees its allocated resources.
-*/
-
-TQDns::~TQDns()
-{
- if ( globalManager ) {
- uint q = 0;
- TQDnsManager * m = globalManager;
- while( q < m->queries.size() ) {
- TQDnsQuery * query=m->queries[q];
- if ( query && query->dns )
- (void)query->dns->take( (void*) this );
- q++;
- }
-
- }
-
- delete d;
- d = 0;
-}
-
-
-
-
-/*!
- Sets this DNS query object to query for information about \a
- label.
-
- This does not change the recordType(), but its isWorking() status
- will probably change as a result.
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-*/
-
-void TQDns::setLabel( const TQString & label )
-{
- l = label;
- d->noNames = FALSE;
-
- // construct a list of qualified names
- n.clear();
- if ( l.length() > 1 && l[(int)l.length()-1] == '.' ) {
- n.append( l.left( l.length()-1 ).lower() );
- } else {
- int i = l.length();
- int dots = 0;
- const int maxDots = 2;
- while( i && dots < maxDots ) {
- if ( l[--i] == '.' )
- dots++;
- }
- if ( dots < maxDots ) {
- (void)TQDnsManager::manager(); // create a TQDnsManager, if it is not already there
- TQStrListIterator it( *domains );
- const char * dom;
- while( (dom=it.current()) != 0 ) {
- ++it;
- n.append( l.lower() + "." + dom );
- }
- }
- n.append( l.lower() );
- }
-
-#if defined(TQ_DNS_SYNCHRONOUS)
- if ( d->noEventLoop ) {
- doSynchronousLookup();
- } else {
- setStartQueryTimer(); // start query the next time we enter event loop
- }
-#else
- setStartQueryTimer(); // start query the next time we enter event loop
-#endif
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::setLabel: %d address(es) for %s", n.count(), l.ascii() );
- int i = 0;
- for( i = 0; i < (int)n.count(); i++ )
- qDebug( "TQDns::setLabel: %d: %s", i, n[i].ascii() );
-#endif
-}
-
-
-/*!
- \overload
-
- Sets this DNS query object to query for information about the host
- address \a address. The label is set to the IN-ADDR.ARPA domain
- name. This is useful in combination with the \c Ptr record type
- (e.g. if you want to look up a hostname for a given address).
-*/
-
-void TQDns::setLabel( const TQHostAddress & address )
-{
- setLabel( toInAddrArpaDomain( address ) );
-}
-
-
-/*!
- \fn TQStringList TQDns::qualifiedNames() const
-
- Returns a list of the fully qualified names label() maps to.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \code
- TQStringList list = myDns.qualifiedNames();
- TQStringList::Iterator it = list.begin();
- while( it != list.end() ) {
- myProcessing( *it );
- ++it;
- }
- \endcode
-
-*/
-
-
-/*!
- \fn TQString TQDns::label() const
-
- Returns the domain name for which this object returns information.
-
- \sa setLabel()
-*/
-
-/*!
- \enum TQDns::RecordType
-
- This enum type defines the record types TQDns can handle. The DNS
- provides many more; these are the ones we've judged to be in
- current use, useful for GUI programs and important enough to
- support right away:
-
- \value None No information. This exists only so that TQDns can
- have a default.
-
- \value A IPv4 addresses. By far the most common type.
-
- \value Aaaa IPv6 addresses. So far mostly unused.
-
- \value Mx Mail eXchanger names. Used for mail delivery.
-
- \value Srv SeRVer names. Generic record type for finding
- servers. So far mostly unused.
-
- \value Cname Canonical names. Maps from nicknames to the true
- name (the canonical name) for a host.
-
- \value Ptr name PoinTeRs. Maps from IPv4 or IPv6 addresses to hostnames.
-
- \value Txt arbitrary TeXT for domains.
-
- We expect that some support for the
- \link http://www.dns.net/dnsrd/rfc/rfc2535.html RFC-2535 \endlink
- extensions will be added in future versions.
-*/
-
-/*!
- Sets this object to query for record type \a rr records.
-
- The DNS lookup is started the next time the application enters the
- event loop. When the result is found the signal resultsReady() is
- emitted.
-
- \sa RecordType
-*/
-
-void TQDns::setRecordType( RecordType rr )
-{
- t = rr;
- d->noNames = FALSE;
- setStartQueryTimer(); // start query the next time we enter event loop
-}
-
-/*!
- \internal
-
- Private slot for starting the query.
-*/
-void TQDns::startQuery()
-{
- // isWorking() starts the query (if necessary)
- if ( !isWorking() )
- emit resultsReady();
-}
-
-/*!
- The three functions TQDns::TQDns(TQString, RecordType),
- TQDns::setLabel() and TQDns::setRecordType() may start a DNS lookup.
- This function handles setting up the single shot timer.
-*/
-void TQDns::setStartQueryTimer()
-{
-#if defined(TQ_DNS_SYNCHRONOUS)
- if ( !d->queryTimer && !d->noEventLoop )
-#else
- if ( !d->queryTimer )
-#endif
- {
- // start the query the next time we enter event loop
- d->queryTimer = new TQTimer( this );
- connect( d->queryTimer, TQT_SIGNAL(timeout()),
- this, TQT_SLOT(startQuery()) );
- d->queryTimer->start( 0, TRUE );
- }
-}
-
-/*
- Transforms the host address \a address to the IN-ADDR.ARPA domain
- name. Returns something indeterminate if you're sloppy or
- naughty. This function has an IPv4-specific name, but works for
- IPv6 too.
-*/
-TQString TQDns::toInAddrArpaDomain( const TQHostAddress &address )
-{
- TQString s;
- if ( address.isNull() ) {
- // if the address isn't valid, neither of the other two make
- // cases make sense. better to just return.
- } else if ( address.isIp4Addr() ) {
- TQ_UINT32 i = address.ip4Addr();
- s.sprintf( "%d.%d.%d.%d.IN-ADDR.ARPA",
- i & 0xff, (i >> 8) & 0xff, (i>>16) & 0xff, (i>>24) & 0xff );
- } else {
- // RFC 3152. (1886 is deprecated, and clients no longer need to
- // support it, in practice).
- TQ_IPV6ADDR i = address.toIPv6Address();
- s = "ip6.arpa";
- uint b = 0;
- while( b < 16 ) {
- s = TQString::number( i.c[b]%16, 16 ) + "." +
- TQString::number( i.c[b]/16, 16 ) + "." + s;
- b++;
- }
- }
- return s;
-}
-
-
-/*!
- \fn TQDns::RecordType TQDns::recordType() const
-
- Returns the record type of this DNS query object.
-
- \sa setRecordType() RecordType
-*/
-
-/*!
- \fn void TQDns::resultsReady()
-
- This signal is emitted when results are available for one of the
- qualifiedNames().
-*/
-
-/*!
- Returns TRUE if TQDns is doing a lookup for this object (i.e. if it
- does not already have the necessary information); otherwise
- returns FALSE.
-
- TQDns emits the resultsReady() signal when the status changes to FALSE.
-*/
-
-bool TQDns::isWorking() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::isWorking (%s, %d)", l.ascii(), t );
-#endif
- if ( t == None )
- return FALSE;
-
-#if defined(TQ_DNS_SYNCHRONOUS)
- if ( d->noEventLoop )
- return TRUE;
-#endif
-
- TQPtrList<TQDnsRR> * ll = TQDnsDomain::cached( this );
- TQ_LONG queries = n.count();
- while( ll->current() != 0 ) {
- if ( ll->current()->nxdomain ) {
- queries--;
- } else {
- delete ll;
- return FALSE;
- }
- ll->next();
- }
- delete ll;
-
- if ( queries <= 0 )
- return FALSE;
- if ( d->noNames )
- return FALSE;
- return TRUE;
-}
-
-
-/*!
- Returns a list of the addresses for this name if this TQDns object
- has a recordType() of \c TQDns::A or \c TQDns::Aaaa and the answer
- is available; otherwise returns an empty list.
-
- As a special case, if label() is a valid numeric IP address, this
- function returns that address.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \code
- TQValueList<TQHostAddress> list = myDns.addresses();
- TQValueList<TQHostAddress>::Iterator it = list.begin();
- while( it != list.end() ) {
- myProcessing( *it );
- ++it;
- }
- \endcode
-
-*/
-
-TQValueList<TQHostAddress> TQDns::addresses() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::addresses (%s)", l.ascii() );
-#endif
- TQValueList<TQHostAddress> result;
- if ( t != A && t != Aaaa )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain )
- result.append( rr->address );
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- \class TQDns::MailServer
- \brief The TQDns::MailServer class is described in TQDns::mailServers().
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
-
- \internal
-*/
-
-/*!
- Returns a list of mail servers if the record type is \c Mx. The
- class \c TQDns::MailServer contains the following public variables:
- \list
- \i TQString TQDns::MailServer::name
- \i TQ_UINT16 TQDns::MailServer::priority
- \endlist
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \code
- TQValueList<TQDns::MailServer> list = myDns.mailServers();
- TQValueList<TQDns::MailServer>::Iterator it = list.begin();
- while( it != list.end() ) {
- myProcessing( *it );
- ++it;
- }
- \endcode
-
-*/
-TQValueList<TQDns::MailServer> TQDns::mailServers() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::mailServers (%s)", l.ascii() );
-#endif
- TQValueList<TQDns::MailServer> result;
- if ( t != Mx )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- MailServer ms( rr->target, rr->priority );
- result.append( ms );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- \class TQDns::Server
- \brief The TQDns::Server class is described in TQDns::servers().
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
-
- \internal
-*/
-
-/*!
- Returns a list of servers if the record type is \c Srv. The class
- \c TQDns::Server contains the following public variables:
- \list
- \i TQString TQDns::Server::name
- \i TQ_UINT16 TQDns::Server::priority
- \i TQ_UINT16 TQDns::Server::weight
- \i TQ_UINT16 TQDns::Server::port
- \endlist
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \code
- TQValueList<TQDns::Server> list = myDns.servers();
- TQValueList<TQDns::Server>::Iterator it = list.begin();
- while( it != list.end() ) {
- myProcessing( *it );
- ++it;
- }
- \endcode
-*/
-TQValueList<TQDns::Server> TQDns::servers() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::servers (%s)", l.ascii() );
-#endif
- TQValueList<TQDns::Server> result;
- if ( t != Srv )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- Server s( rr->target, rr->priority, rr->weight, rr->port );
- result.append( s );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- Returns a list of host names if the record type is \c Ptr.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \code
- TQStringList list = myDns.hostNames();
- TQStringList::Iterator it = list.begin();
- while( it != list.end() ) {
- myProcessing( *it );
- ++it;
- }
- \endcode
-
-*/
-TQStringList TQDns::hostNames() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::hostNames (%s)", l.ascii() );
-#endif
- TQStringList result;
- if ( t != Ptr )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- TQString str( rr->target );
- result.append( str );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- Returns a list of texts if the record type is \c Txt.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \code
- TQStringList list = myDns.texts();
- TQStringList::Iterator it = list.begin();
- while( it != list.end() ) {
- myProcessing( *it );
- ++it;
- }
- \endcode
-*/
-TQStringList TQDns::texts() const
-{
-#if defined(TQDNS_DEBUG)
- qDebug( "TQDns::texts (%s)", l.ascii() );
-#endif
- TQStringList result;
- if ( t != Txt )
- return result;
-
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain ) {
- TQString str( rr->text );
- result.append( str );
- }
- cached->next();
- }
- delete cached;
- return result;
-}
-
-
-/*!
- Returns the canonical name for this DNS node. (This works
- regardless of what recordType() is set to.)
-
- If the canonical name isn't known, this function returns a null
- string.
-
- The canonical name of a DNS node is its full name, or the full
- name of the target of its CNAME. For example, if l.trolltech.com
- is a CNAME to lillian.troll.no, and the search path for TQDns is
- "trolltech.com", then the canonical name for all of "lillian",
- "l", "lillian.troll.no." and "l.trolltech.com" is
- "lillian.troll.no.".
-*/
-
-TQString TQDns::canonicalName() const
-{
- // the cname should work regardless of the recordType(), so set the record
- // type temporarily to cname when you look at the cache
- TQDns *that = (TQDns*) this; // mutable function
- RecordType oldType = t;
- that->t = Cname;
- TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( that );
- that->t = oldType;
-
- TQDnsRR * rr;
- while( (rr=cached->current()) != 0 ) {
- if ( rr->current && !rr->nxdomain && rr->domain ) {
- delete cached;
- return rr->target;
- }
- cached->next();
- }
- delete cached;
- return TQString::null;
-}
-
-#if defined(TQ_DNS_SYNCHRONOUS)
-/*! \reimp
-*/
-void TQDns::connectNotify( const char *signal )
-{
- if ( d->noEventLoop && qstrcmp(signal,TQT_SIGNAL(resultsReady()) )==0 ) {
- doSynchronousLookup();
- }
-}
-#endif
-
-#if defined(TQ_OS_WIN32) || defined(TQ_OS_CYGWIN)
-
-#if defined(TQ_DNS_SYNCHRONOUS)
-void TQDns::doSynchronousLookup()
-{
- // ### not implemented yet
-}
-#endif
-
-// the following typedefs are needed for GetNetworkParams() API call
-#ifndef IP_TYPES_INCLUDED
-#define MAX_HOSTNAME_LEN 128
-#define MAX_DOMAIN_NAME_LEN 128
-#define MAX_SCOPE_ID_LEN 256
-typedef struct {
- char String[4 * 4];
-} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
-typedef struct _IP_ADDR_STRING {
- struct _IP_ADDR_STRING* Next;
- IP_ADDRESS_STRING IpAddress;
- IP_MASK_STRING IpMask;
- DWORD Context;
-} IP_ADDR_STRING, *PIP_ADDR_STRING;
-typedef struct {
- char HostName[MAX_HOSTNAME_LEN + 4] ;
- char DomainName[MAX_DOMAIN_NAME_LEN + 4];
- PIP_ADDR_STRING CurrentDnsServer;
- IP_ADDR_STRING DnsServerList;
- UINT NodeType;
- char ScopeId[MAX_SCOPE_ID_LEN + 4];
- UINT EnableRouting;
- UINT EnableProxy;
- UINT EnableDns;
-} FIXED_INFO, *PFIXED_INFO;
-#endif
-typedef DWORD (WINAPI *GNP)( PFIXED_INFO, PULONG );
-
-// ### FIXME: this code is duplicated in qfiledialog.cpp
-static TQString getWindowsRegString( HKEY key, const TQString &subKey )
-{
- TQString s;
- TQT_WA( {
- char buf[1024];
- DWORD bsz = sizeof(buf);
- int r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)buf, &bsz );
- if ( r == ERROR_SUCCESS ) {
- s = TQString::fromUcs2( (unsigned short *)buf );
- } else if ( r == ERROR_MORE_DATA ) {
- char *ptr = new char[bsz+1];
- r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)ptr, &bsz );
- if ( r == ERROR_SUCCESS )
- s = ptr;
- delete [] ptr;
- }
- } , {
- char buf[512];
- DWORD bsz = sizeof(buf);
- int r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)buf, &bsz );
- if ( r == ERROR_SUCCESS ) {
- s = buf;
- } else if ( r == ERROR_MORE_DATA ) {
- char *ptr = new char[bsz+1];
- r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)ptr, &bsz );
- if ( r == ERROR_SUCCESS )
- s = ptr;
- delete [] ptr;
- }
- } );
- return s;
-}
-
-static bool getDnsParamsFromRegistry( const TQString &path,
- TQString *domainName, TQString *nameServer, TQString *searchList )
-{
- HKEY k;
- int r;
- TQT_WA( {
- r = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- (TCHAR*)path.ucs2(),
- 0, KEY_READ, &k );
- } , {
- r = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
- path,
- 0, KEY_READ, &k );
- } );
-
- if ( r == ERROR_SUCCESS ) {
- *domainName = getWindowsRegString( k, "DhcpDomain" );
- if ( domainName->isEmpty() )
- *domainName = getWindowsRegString( k, "Domain" );
-
- *nameServer = getWindowsRegString( k, "DhcpNameServer" );
- if ( nameServer->isEmpty() )
- *nameServer = getWindowsRegString( k, "NameServer" );
-
- *searchList = getWindowsRegString( k, "SearchList" );
- }
- RegCloseKey( k );
- return r == ERROR_SUCCESS;
-}
-
-void TQDns::doResInit()
-{
- char separator = 0;
-
- if ( ns )
- delete ns;
- ns = new TQPtrList<TQHostAddress>;
- ns->setAutoDelete( TRUE );
- domains = new TQStrList( TRUE );
- domains->setAutoDelete( TRUE );
-
- TQString domainName, nameServer, searchList;
-
- bool gotNetworkParams = FALSE;
- // try the API call GetNetworkParams() first and use registry lookup only
- // as a fallback
-#ifdef TQ_OS_TEMP
- HINSTANCE hinstLib = LoadLibraryW( L"iphlpapi" );
-#else
- HINSTANCE hinstLib = LoadLibraryA( "iphlpapi" );
-#endif
- if ( hinstLib != 0 ) {
-#ifdef TQ_OS_TEMP
- GNP getNetworkParams = (GNP) GetProcAddressW( hinstLib, L"GetNetworkParams" );
-#else
- GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, "GetNetworkParams" );
-#endif
- if ( getNetworkParams != 0 ) {
- ULONG l = 0;
- DWORD res;
- res = getNetworkParams( 0, &l );
- if ( res == ERROR_BUFFER_OVERFLOW ) {
- FIXED_INFO *finfo = (FIXED_INFO*)new char[l];
- res = getNetworkParams( finfo, &l );
- if ( res == ERROR_SUCCESS ) {
- domainName = finfo->DomainName;
- nameServer = "";
- IP_ADDR_STRING *dnsServer = &finfo->DnsServerList;
- while ( dnsServer != 0 ) {
- nameServer += dnsServer->IpAddress.String;
- dnsServer = dnsServer->Next;
- if ( dnsServer != 0 )
- nameServer += " ";
- }
- searchList = "";
- separator = ' ';
- gotNetworkParams = TRUE;
- }
- delete[] finfo;
- }
- }
- FreeLibrary( hinstLib );
- }
- if ( !gotNetworkParams ) {
- if ( getDnsParamsFromRegistry(
- TQString( "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" ),
- &domainName, &nameServer, &searchList )) {
- // for NT
- separator = ' ';
- } else if ( getDnsParamsFromRegistry(
- TQString( "System\\CurrentControlSet\\Services\\VxD\\MSTCP" ),
- &domainName, &nameServer, &searchList )) {
- // for 95/98
- separator = ',';
- } else {
- // Could not access the TCP/IP parameters
- domainName = "";
- nameServer = "127.0.0.1";
- searchList = "";
- separator = ' ';
- }
- }
-
- nameServer = nameServer.simplifyWhiteSpace();
- int first, last;
- if ( !nameServer.isEmpty() ) {
- first = 0;
- do {
- last = nameServer.find( separator, first );
- if ( last < 0 )
- last = nameServer.length();
- TQDns tmp( nameServer.mid( first, last-first ), TQDns::A );
- TQValueList<TQHostAddress> address = tmp.addresses();
- TQ_LONG i = address.count();
- while( i )
- ns->append( new TQHostAddress(address[--i]) );
- first = last+1;
- } while( first < (int)nameServer.length() );
- }
-
- searchList = searchList + " " + domainName;
- searchList = searchList.simplifyWhiteSpace().lower();
- first = 0;
- do {
- last = searchList.find( separator, first );
- if ( last < 0 )
- last = searchList.length();
- domains->append( qstrdup( searchList.mid( first, last-first ) ) );
- first = last+1;
- } while( first < (int)searchList.length() );
-}
-
-#elif defined(TQ_OS_UNIX)
-
-#if defined(TQ_DNS_SYNCHRONOUS)
-void TQDns::doSynchronousLookup()
-{
- if ( t!=None && !l.isEmpty() ) {
- TQValueListIterator<TQString> it = n.begin();
- TQValueListIterator<TQString> end = n.end();
- int type;
- switch( t ) {
- case TQDns::A:
- type = 1;
- break;
- case TQDns::Aaaa:
- type = 28;
- break;
- case TQDns::Mx:
- type = 15;
- break;
- case TQDns::Srv:
- type = 33;
- break;
- case TQDns::Cname:
- type = 5;
- break;
- case TQDns::Ptr:
- type = 12;
- break;
- case TQDns::Txt:
- type = 16;
- break;
- default:
- type = (char)255; // any
- break;
- }
- while( it != end ) {
- TQString s = *it;
- it++;
- TQByteArray ba( 512 );
- int len = res_search( s.latin1(), 1, type, (uchar*)ba.data(), ba.size() );
- if ( len > 0 ) {
- ba.resize( len );
-
- TQDnsQuery * query = new TQDnsQuery;
- query->started = now();
- query->id = ++::id;
- query->t = t;
- query->l = s;
- TQDnsAnswer a( ba, query );
- a.parse();
- } else if ( len == -1 ) {
- // res_search error
- }
- }
- emit resultsReady();
- }
-}
-#endif
-
-#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
-#define TQ_MODERN_RES_API
-#else
-#endif
-
-void TQDns::doResInit()
-{
- if ( ns )
- return;
- ns = new TQPtrList<TQHostAddress>;
- ns->setAutoDelete( TRUE );
- domains = new TQStrList( TRUE );
- domains->setAutoDelete( TRUE );
-
- // read resolv.conf manually.
- TQFile resolvConf("/etc/resolv.conf");
- if (resolvConf.open(IO_ReadOnly)) {
- TQTextStream stream( &resolvConf );
- TQString line;
-
- while ( !stream.atEnd() ) {
- line = stream.readLine();
- TQStringList list = TQStringList::split( " ", line );
- if ( line.startsWith( "#" ) || list.count() < 2 )
- continue;
- const TQString type = list[0].lower();
-
- if ( type == "nameserver" ) {
- TQHostAddress *address = new TQHostAddress();
- if ( address->setAddress( TQString(list[1]) ) ) {
- // only add ipv6 addresses from resolv.conf if
- // this host supports ipv6.
- if ( address->isIPv4Address() || ipv6support )
- ns->append( address );
- else
- delete address;
- } else {
- delete address;
- }
- } else if ( type == "search" ) {
- TQStringList srch = TQStringList::split( " ", list[1] );
- for ( TQStringList::Iterator i = srch.begin(); i != srch.end(); ++i )
- domains->append( (*i).lower() );
-
- } else if ( type == "domain" ) {
- domains->append( list[1].lower() );
- }
- }
- }
-
- if (ns->isEmpty()) {
-#if defined(TQ_MODERN_RES_API)
- struct __res_state res;
- res_ninit( &res );
- int i;
- // find the name servers to use
- for( i=0; i < MAXNS && i < res.nscount; i++ )
- ns->append( new TQHostAddress( ntohl( res.nsaddr_list[i].sin_addr.s_addr ) ) );
-# if defined(MAXDFLSRCH)
- for( i=0; i < MAXDFLSRCH; i++ ) {
- if ( res.dnsrch[i] && *(res.dnsrch[i]) )
- domains->append( TQString::tqfromLatin1( res.dnsrch[i] ).lower() );
- else
- break;
- }
-# endif
- if ( *res.defdname )
- domains->append( TQString::tqfromLatin1( res.defdname ).lower() );
-#else
- qdns_res_init();
- int i;
- // find the name servers to use
- for( i=0; i < MAXNS && i < _res.nscount; i++ )
- ns->append( new TQHostAddress( ntohl( _res.nsaddr_list[i].sin_addr.s_addr ) ) );
-# if defined(MAXDFLSRCH)
- for( i=0; i < MAXDFLSRCH; i++ ) {
- if ( _res.dnsrch[i] && *(_res.dnsrch[i]) )
- domains->append( TQString::tqfromLatin1( _res.dnsrch[i] ).lower() );
- else
- break;
- }
-# endif
- if ( *_res.defdname )
- domains->append( TQString::tqfromLatin1( _res.defdname ).lower() );
-#endif
-
- // the code above adds "0.0.0.0" as a name server at the slightest
- // hint of trouble. so remove those again.
- ns->first();
- while( ns->current() ) {
- if ( ns->current()->isNull() )
- delete ns->take();
- else
- ns->next();
- }
- }
-
- TQFile hosts( TQString::tqfromLatin1( "/etc/hosts" ) );
- if ( hosts.open( IO_ReadOnly ) ) {
- // read the /etc/hosts file, creating long-life A and PTR RRs
- // for the things we find.
- TQTextStream i( &hosts );
- TQString line;
- while( !i.atEnd() ) {
- line = i.readLine().simplifyWhiteSpace().lower();
- uint n = 0;
- while( n < line.length() && line[(int)n] != '#' )
- n++;
- line.truncate( n );
- n = 0;
- while( n < line.length() && !line[(int)n].isSpace() )
- n++;
- TQString ip = line.left( n );
- TQHostAddress a;
- a.setAddress( ip );
- if ( ( a.isIPv4Address() || a.isIPv6Address() ) && !a.isNull() ) {
- bool first = TRUE;
- line = line.mid( n+1 );
- n = 0;
- while( n < line.length() && !line[(int)n].isSpace() )
- n++;
- TQString hostname = line.left( n );
- // ### in case of bad syntax, hostname is invalid. do we care?
- if ( n ) {
- TQDnsRR * rr = new TQDnsRR( hostname );
- if ( a.isIPv4Address() )
- rr->t = TQDns::A;
- else
- rr->t = TQDns::Aaaa;
- rr->address = a;
- rr->deleteTime = UINT_MAX;
- rr->expireTime = UINT_MAX;
- rr->current = TRUE;
- if ( first ) {
- first = FALSE;
- TQDnsRR * ptr = new TQDnsRR( TQDns::toInAddrArpaDomain( a ) );
- ptr->t = TQDns::Ptr;
- ptr->target = hostname;
- ptr->deleteTime = UINT_MAX;
- ptr->expireTime = UINT_MAX;
- ptr->current = TRUE;
- }
- }
- }
- }
- }
-}
-
-#endif
-
-#endif // TQT_NO_DNS
-
-#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/network/tqdns.h b/tqtinterface/qt4/src/network/tqdns.h
deleted file mode 100644
index 23c84ee..0000000
--- a/tqtinterface/qt4/src/network/tqdns.h
+++ /dev/null
@@ -1,382 +0,0 @@
-#include "tqtglobaldefines.h"
-
-#ifdef USE_QT4
-
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt3Support module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial Usage
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Nokia.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef TQDNS_H
-#define TQDNS_H
-
-#include <Qt/qobject.h>
-#include <Qt/qhostaddress.h>
-#include <Qt/qsocketnotifier.h>
-#include <tqstringlist.h>
-#include <tqvaluelist.h>
-
-#include "tqtimer.h"
-#include "tqobject.h"
-#include "tqhostaddress.h"
-#include "tqsocketnotifier.h"
-
-#define TQLatin1String TQString
-#define TQLatin1Char TQChar
-
-typedef qint8 Q_INT8;
-typedef quint8 Q_UINT8;
-typedef qint16 Q_INT16;
-typedef quint16 Q_UINT16;
-typedef qint32 Q_INT32;
-typedef quint32 Q_UINT32;
-typedef qint64 Q_INT64;
-typedef quint64 Q_UINT64;
-typedef qint64 Q_LLONG;
-typedef quint64 Q_ULLONG;
-#if defined(Q_OS_WIN64)
-typedef __int64 Q_LONG; /* word up to 64 bit signed */
-typedef unsigned __int64 Q_ULONG; /* word up to 64 bit unsigned */
-#else
-typedef long Q_LONG; /* word up to 64 bit signed */
-typedef unsigned long Q_ULONG; /* word up to 64 bit unsigned */
-#endif
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Qt3Support)
-
-#ifndef QT_NO_DNS
-
-//#define Q_DNS_SYNCHRONOUS
-
-class TQDnsPrivate;
-
-class Q_COMPAT_EXPORT TQDns: public TQObject {
- Q_OBJECT
- TQ_OBJECT
-public:
- enum RecordType {
- None,
- A, Aaaa,
- Mx, Srv,
- Cname,
- Ptr,
- Txt
- };
-
- TQDns();
- TQDns( const TQString & label, RecordType rr = A );
- TQDns( const TQHostAddress & address, RecordType rr = Ptr );
- virtual ~TQDns();
-
- // to set/change the query
- virtual void setLabel( const TQString & label );
- virtual void setLabel( const TQHostAddress & address );
- TQString label() const { return l; }
-
- virtual void setRecordType( RecordType rr = A );
- RecordType recordType() const { return t; }
-
- // whether something is happening behind the scenes
- bool isWorking() const;
-
- // to query for replies
- TQValueList<TQHostAddress> addresses() const;
-
- class Q_COMPAT_EXPORT MailServer {
- public:
- MailServer( const TQString & n=TQString(), Q_UINT16 p=0 )
- :name(n), priority(p) {}
- TQString name;
- Q_UINT16 priority;
- Q_DUMMY_COMPARISON_OPERATOR(MailServer)
- };
- TQValueList<MailServer> mailServers() const;
-
- class Q_COMPAT_EXPORT Server {
- public:
- Server(const TQString & n=TQString(), Q_UINT16 p=0, Q_UINT16 w=0, Q_UINT16 po=0 )
- : name(n), priority(p), weight(w), port(po) {}
- TQString name;
- Q_UINT16 priority;
- Q_UINT16 weight;
- Q_UINT16 port;
- Q_DUMMY_COMPARISON_OPERATOR(Server)
- };
- TQValueList<Server> servers() const;
-
- TQStringList hostNames() const;
-
- TQStringList texts() const;
-
- TQString canonicalName() const; // ### real-world but uncommon: TQStringList
-
- TQStringList qualifiedNames() const { return n; }
-
-#if defined(Q_DNS_SYNCHRONOUS)
-protected:
- void connectNotify( const char *signal );
-#endif
-
-Q_SIGNALS:
- void resultsReady();
-
-private Q_SLOTS:
- void startQuery();
-
-private:
- static void doResInit();
- void setStartQueryTimer();
- static TQString toInAddrArpaDomain( const TQHostAddress &address );
-#if defined(Q_DNS_SYNCHRONOUS)
- void doSynchronousLookup();
-#endif
-
- TQString l;
- TQStringList n;
- RecordType t;
- TQDnsPrivate * d;
-
- friend class TQDnsAnswer;
- friend class TQDnsManager;
-};
-
-
-// TQDnsSocket are sockets that are used for DNS lookup
-
-class TQDnsSocket: public TQObject {
- Q_OBJECT
- // note: Private not public. This class contains NO public API.
-protected:
- TQDnsSocket( TQT_BASE_OBJECT_NAME *, const char * );
- virtual ~TQDnsSocket();
-
-private Q_SLOTS:
- virtual void cleanCache();
- virtual void retransmit();
- virtual void answer();
-};
-
-#endif // QT_NO_DNS
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // TQDNS_H
-
-#else // USE_QT4
-
-/****************************************************************************
-**
-** Definition of TQDns class.
-**
-** Created : 991122
-**
-** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQDNS_H
-#define TQDNS_H
-
-#ifndef TQT_H
-#include "tqobject.h"
-#include "tqhostaddress.h"
-#include "tqsocketnotifier.h"
-#include "tqstringlist.h"
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_DNS
-#else
-#define TQM_EXPORT_DNS TQ_EXPORT
-#endif
-
-#ifndef TQT_NO_DNS
-
-//#define TQ_DNS_SYNCHRONOUS
-
-class TQDnsPrivate;
-
-class TQM_EXPORT_DNS TQDns: public TQObject {
- Q_OBJECT
- TQ_OBJECT
-public:
- enum RecordType {
- None,
- A, Aaaa,
- Mx, Srv,
- Cname,
- Ptr,
- Txt
- };
-
- TQDns();
- TQDns( const TQString & label, RecordType rr = A );
- TQDns( const TQHostAddress & address, RecordType rr = Ptr );
- virtual ~TQDns();
-
- // to set/change the query
- virtual void setLabel( const TQString & label );
- virtual void setLabel( const TQHostAddress & address );
- TQString label() const { return l; }
-
- virtual void setRecordType( RecordType rr = A );
- RecordType recordType() const { return t; }
-
- // whether something is happening behind the scenes
- bool isWorking() const;
-
- // to query for replies
- TQValueList<TQHostAddress> addresses() const;
-
- class TQM_EXPORT_DNS MailServer {
- public:
- MailServer( const TQString & n=TQString::null, TQ_UINT16 p=0 )
- :name(n), priority(p) {}
- TQString name;
- TQ_UINT16 priority;
- TQ_DUMMY_COMPARISON_OPERATOR(MailServer)
- };
- TQValueList<MailServer> mailServers() const;
-
- class TQM_EXPORT_DNS Server {
- public:
- Server(const TQString & n=TQString::null, TQ_UINT16 p=0, TQ_UINT16 w=0, TQ_UINT16 po=0 )
- : name(n), priority(p), weight(w), port(po) {}
- TQString name;
- TQ_UINT16 priority;
- TQ_UINT16 weight;
- TQ_UINT16 port;
- TQ_DUMMY_COMPARISON_OPERATOR(Server)
- };
- TQValueList<Server> servers() const;
-
- TQStringList hostNames() const;
-
- TQStringList texts() const;
-
- TQString canonicalName() const; // ### real-world but uncommon: TQStringList
-
- TQStringList qualifiedNames() const { return n; }
-
-#if defined(TQ_DNS_SYNCHRONOUS)
-protected:
- void connectNotify( const char *signal );
-#endif
-
-Q_SIGNALS:
- void resultsReady();
-
-private Q_SLOTS:
- void startQuery();
-
-private:
- static void doResInit();
- void setStartQueryTimer();
- static TQString toInAddrArpaDomain( const TQHostAddress &address );
-#if defined(TQ_DNS_SYNCHRONOUS)
- void doSynchronousLookup();
-#endif
-
- TQString l;
- TQStringList n;
- RecordType t;
- TQDnsPrivate * d;
-
- friend class TQDnsAnswer;
- friend class TQDnsManager;
-};
-
-
-// TQDnsSocket are sockets that are used for DNS lookup
-
-class TQDnsSocket: public TQObject {
- Q_OBJECT
- TQ_OBJECT
- // note: Private not public. This class contains NO public API.
-protected:
- TQDnsSocket( TQObject *, const char * );
- virtual ~TQDnsSocket();
-
-private Q_SLOTS:
- virtual void cleanCache();
- virtual void retransmit();
- virtual void answer();
-};
-
-#endif // TQT_NO_DNS
-
-#endif // TQDNS_H
-
-#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/network/tqftp.cpp b/tqtinterface/qt4/src/network/tqftp.cpp
deleted file mode 100644
index 78f1ce8..0000000
--- a/tqtinterface/qt4/src/network/tqftp.cpp
+++ /dev/null
@@ -1,2421 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQFtp class.
-**
-** Created : 970521
-**
-** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqftp.h"
-
-#ifndef TQT_NO_NETWORKPROTOCOL_FTP
-
-#include "tqsocket.h"
-#include "tqsocketdevice.h"
-#include "tqurlinfo.h"
-#include "tqurloperator.h"
-#include "tqstringlist.h"
-#include "tqregexp.h"
-#include "tqtimer.h"
-#include "tqfileinfo.h"
-#include "tqptrdict.h" // binary compatibility
-
-#ifndef TQT_NO_TEXTCODEC
-#include "tqtextcodec.h"
-#endif
-
-//#define TQFTPPI_DEBUG
-//#define TQFTPDTP_DEBUG
-
-
-class TQFtpPI;
-
-class TQFtpDTP : public TQObject
-{
- Q_OBJECT
- TQ_OBJECT
-
-public:
- enum ConnectState {
- CsHostFound,
- CsConnected,
- CsClosed,
- CsHostNotFound,
- CsConnectionRefused
- };
-
- TQFtpDTP( TQFtpPI *p, TQObject *parent=0, const char *name=0 );
-
- void setData( TQByteArray * );
- void setDevice( TQIODevice * );
- void writeData();
-
- void setBytesTotal( int bytes )
- {
- bytesTotal = bytes;
- bytesDone = 0;
- emit dataTransferProgress( bytesDone, bytesTotal );
- }
-
- bool hasError() const;
- TQString errorMessage() const;
- void clearError();
-
- void connectToHost( const TQString & host, TQ_UINT16 port )
- { socket.connectToHost( host, port ); }
-
- TQSocket::State socketState() const
- { return socket.state(); }
-
- TQ_ULONG bytesAvailable() const
- { return socket.bytesAvailable(); }
-
- TQ_LONG readBlock( char *data, TQ_ULONG maxlen )
- {
- TQ_LONG read = socket.readBlock( data, maxlen );
- bytesDone += read;
- return read;
- }
-
- TQByteArray readAll()
- {
- TQByteArray tmp = TQT_TQBYTEARRAY_OBJECT(socket.readAll());
- bytesDone += tmp.size();
- return tmp;
- }
-
- void abortConnection();
-
- static bool parseDir( const TQString &buffer, const TQString &userName, TQUrlInfo *info );
-
-Q_SIGNALS:
- void listInfo( const TQUrlInfo& );
- void readyRead();
- void dataTransferProgress( int, int );
-
- void connectState( int );
-
-private Q_SLOTS:
- void socketConnected();
- void socketReadyRead();
- void socketError( int );
- void socketConnectionClosed();
- void socketBytesWritten( int );
-
-private:
- void clearData()
- {
- is_ba = FALSE;
- data.dev = 0;
- }
-
- TQSocket socket;
- TQFtpPI *pi;
- TQString err;
- int bytesDone;
- int bytesTotal;
- bool callWriteData;
-
- // If is_ba is TRUE, ba is used; ba is never 0.
- // Otherwise dev is used; dev can be 0 or not.
- union {
- TQByteArray *ba;
- TQIODevice *dev;
- } data;
- bool is_ba;
-};
-
-class TQFtpPI : public TQObject
-{
- Q_OBJECT
- TQ_OBJECT
-
-public:
- TQFtpPI( TQObject *parent = 0 );
-
- void connectToHost( const TQString &host, TQ_UINT16 port );
-
- bool sendCommands( const TQStringList &cmds );
- bool sendCommand( const TQString &cmd )
- { return sendCommands( TQStringList( cmd ) ); }
-
- void clearPendingCommands();
- void abort();
-
- TQString currentCommand() const
- { return currentCmd; }
-
- bool rawCommand;
-
- TQFtpDTP dtp; // the PI has a DTP which is not the design of RFC 959, but it
- // makes the design simpler this way
-Q_SIGNALS:
- void connectState( int );
- void finished( const TQString& );
- void error( int, const TQString& );
- void rawFtpReply( int, const TQString& );
-
-private Q_SLOTS:
- void hostFound();
- void connected();
- void connectionClosed();
- void delayedCloseFinished();
- void readyRead();
- void error( int );
-
- void dtpConnectState( int );
-
-private:
- // the states are modelled after the generalized state diagram of RFC 959,
- // page 58
- enum State {
- Begin,
- Idle,
- Waiting,
- Success,
- Failure
- };
-
- enum AbortState {
- None,
- AbortStarted,
- WaitForAbortToFinish
- };
-
- bool processReply();
- bool startNextCmd();
-
- TQSocket commandSocket;
- TQString replyText;
- char replyCode[3];
- State state;
- AbortState abortState;
- TQStringList pendingCommands;
- TQString currentCmd;
-
- bool waitForDtpToConnect;
- bool waitForDtpToClose;
-};
-
-/**********************************************************************
- *
- * TQFtpCommand implemenatation
- *
- *********************************************************************/
-class TQFtpCommand
-{
-public:
- TQFtpCommand( TQFtp::Command cmd, TQStringList raw );
- TQFtpCommand( TQFtp::Command cmd, TQStringList raw, const TQByteArray &ba );
- TQFtpCommand( TQFtp::Command cmd, TQStringList raw, TQIODevice *dev );
- ~TQFtpCommand();
-
- int id;
- TQFtp::Command command;
- TQStringList rawCmds;
-
- // If is_ba is TRUE, ba is used; ba is never 0.
- // Otherwise dev is used; dev can be 0 or not.
- union {
- TQByteArray *ba;
- TQIODevice *dev;
- } data;
- bool is_ba;
-
- static int idCounter;
-};
-
-int TQFtpCommand::idCounter = 0;
-
-TQFtpCommand::TQFtpCommand( TQFtp::Command cmd, TQStringList raw )
- : command(cmd), rawCmds(raw), is_ba(FALSE)
-{
- id = ++idCounter;
- data.dev = 0;
-}
-
-TQFtpCommand::TQFtpCommand( TQFtp::Command cmd, TQStringList raw, const TQByteArray &ba )
- : command(cmd), rawCmds(raw), is_ba(TRUE)
-{
- id = ++idCounter;
- data.ba = new TQByteArray( ba );
-}
-
-TQFtpCommand::TQFtpCommand( TQFtp::Command cmd, TQStringList raw, TQIODevice *dev )
- : command(cmd), rawCmds(raw), is_ba(FALSE)
-{
- id = ++idCounter;
- data.dev = dev;
-}
-
-TQFtpCommand::~TQFtpCommand()
-{
- if ( is_ba )
- delete data.ba;
-}
-
-/**********************************************************************
- *
- * TQFtpDTP implemenatation
- *
- *********************************************************************/
-TQFtpDTP::TQFtpDTP( TQFtpPI *p, TQObject *parent, const char *name ) :
- TQObject( parent, name ),
- socket( 0, "TQFtpDTP_socket" ),
- pi( p ),
- callWriteData( FALSE )
-{
- clearData();
-
- connect( &socket, TQT_SIGNAL( connected() ),
- TQT_SLOT( socketConnected() ) );
- connect( &socket, TQT_SIGNAL( readyRead() ),
- TQT_SLOT( socketReadyRead() ) );
- connect( &socket, TQT_SIGNAL( error(int) ),
- TQT_SLOT( socketError(int) ) );
- connect( &socket, TQT_SIGNAL( connectionClosed() ),
- TQT_SLOT( socketConnectionClosed() ) );
- connect( &socket, TQT_SIGNAL( bytesWritten(int) ),
- TQT_SLOT( socketBytesWritten(int) ) );
-}
-
-void TQFtpDTP::setData( TQByteArray *ba )
-{
- is_ba = TRUE;
- data.ba = ba;
-}
-
-void TQFtpDTP::setDevice( TQIODevice *dev )
-{
- is_ba = FALSE;
- data.dev = dev;
-}
-
-void TQFtpDTP::writeData()
-{
- if ( is_ba ) {
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::writeData: write %d bytes", data.ba->size() );
-#endif
- if ( data.ba->size() == 0 )
- emit dataTransferProgress( 0, bytesTotal );
- else
- socket.writeBlock( data.ba->data(), data.ba->size() );
- socket.close();
- clearData();
- } else if ( data.dev ) {
- callWriteData = FALSE;
- const int blockSize = 16*1024;
- char buf[blockSize];
- while ( !data.dev->atEnd() && socket.bytesToWrite()==0 ) {
- TQ_LONG read = data.dev->readBlock( buf, blockSize );
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::writeData: writeBlock() of size %d bytes", (int)read );
-#endif
- socket.writeBlock( buf, read );
- if ( !data.dev )
- return; // this can happen when a command is aborted
- }
- if ( data.dev->atEnd() ) {
- if ( bytesDone==0 && socket.bytesToWrite()==0 )
- emit dataTransferProgress( 0, bytesTotal );
- socket.close();
- clearData();
- } else {
- callWriteData = TRUE;
- }
- }
-}
-
-inline bool TQFtpDTP::hasError() const
-{
- return !err.isNull();
-}
-
-inline TQString TQFtpDTP::errorMessage() const
-{
- return err;
-}
-
-inline void TQFtpDTP::clearError()
-{
- err = TQString::null;
-}
-
-void TQFtpDTP::abortConnection()
-{
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::abortConnection" );
-#endif
- callWriteData = FALSE;
- clearData();
-
- socket.clearPendingData();
- socket.close();
-}
-
-bool TQFtpDTP::parseDir( const TQString &buffer, const TQString &userName, TQUrlInfo *info )
-{
- TQStringList lst = TQStringList::split( " ", buffer );
-
- if ( lst.count() < 9 )
- return FALSE;
-
- TQString tmp;
-
- // permissions
- tmp = lst[ 0 ];
-
- if ( tmp[ 0 ] == TQChar( 'd' ) ) {
- info->setDir( TRUE );
- info->setFile( FALSE );
- info->setSymLink( FALSE );
- } else if ( tmp[ 0 ] == TQChar( '-' ) ) {
- info->setDir( FALSE );
- info->setFile( TRUE );
- info->setSymLink( FALSE );
- } else if ( tmp[ 0 ] == TQChar( 'l' ) ) {
- info->setDir( TRUE ); // #### todo
- info->setFile( FALSE );
- info->setSymLink( TRUE );
- } else {
- return FALSE;
- }
-
- static int user = 0;
- static int group = 1;
- static int other = 2;
- static int readable = 0;
- static int writable = 1;
- static int executable = 2;
-
- bool perms[ 3 ][ 3 ];
- perms[0][0] = (tmp[ 1 ] == 'r');
- perms[0][1] = (tmp[ 2 ] == 'w');
- perms[0][2] = (tmp[ 3 ] == 'x');
- perms[1][0] = (tmp[ 4 ] == 'r');
- perms[1][1] = (tmp[ 5 ] == 'w');
- perms[1][2] = (tmp[ 6 ] == 'x');
- perms[2][0] = (tmp[ 7 ] == 'r');
- perms[2][1] = (tmp[ 8 ] == 'w');
- perms[2][2] = (tmp[ 9 ] == 'x');
-
- // owner
- tmp = lst[ 2 ];
- info->setOwner( tmp );
-
- // group
- tmp = lst[ 3 ];
- info->setGroup( tmp );
-
- // ### not correct
- info->setWritable( ( userName == info->owner() && perms[ user ][ writable ] ) ||
- perms[ other ][ writable ] );
- info->setReadable( ( userName == info->owner() && perms[ user ][ readable ] ) ||
- perms[ other ][ readable ] );
-
- int p = 0;
- if ( perms[ user ][ readable ] )
- p |= TQUrlInfo::ReadOwner;
- if ( perms[ user ][ writable ] )
- p |= TQUrlInfo::WriteOwner;
- if ( perms[ user ][ executable ] )
- p |= TQUrlInfo::ExeOwner;
- if ( perms[ group ][ readable ] )
- p |= TQUrlInfo::ReadGroup;
- if ( perms[ group ][ writable ] )
- p |= TQUrlInfo::WriteGroup;
- if ( perms[ group ][ executable ] )
- p |= TQUrlInfo::ExeGroup;
- if ( perms[ other ][ readable ] )
- p |= TQUrlInfo::ReadOther;
- if ( perms[ other ][ writable ] )
- p |= TQUrlInfo::WriteOther;
- if ( perms[ other ][ executable ] )
- p |= TQUrlInfo::ExeOther;
- info->setPermissions( p );
-
- // size
- tmp = lst[ 4 ];
- info->setSize( tmp.toInt() );
-
- // date and time
- TQTime time;
- TQString dateStr;
- dateStr += "Sun ";
- lst[ 5 ][ 0 ] = lst[ 5 ][ 0 ].upper();
- dateStr += lst[ 5 ];
- dateStr += ' ';
- dateStr += lst[ 6 ];
- dateStr += ' ';
-
- if ( lst[ 7 ].contains( ":" ) ) {
- time = TQTime( lst[ 7 ].left( 2 ).toInt(), lst[ 7 ].right( 2 ).toInt() );
- dateStr += TQString::number( TQDate::currentDate().year() );
- } else {
- dateStr += lst[ 7 ];
- }
-
- TQDate date = TQT_TQDATE_OBJECT(TQDate::fromString( dateStr ));
- info->setLastModified( TQDateTime( date, time ) );
-
- if ( lst[ 7 ].contains( ":" ) ) {
- const int futureTolerance = 600;
- if( info->lastModified().secsTo( TQDateTime::tqcurrentDateTime() ) < -futureTolerance ) {
- TQDateTime dt = info->lastModified();
- TQDate d = TQT_TQDATE_OBJECT(dt.date());
- d.setYMD(d.year()-1, d.month(), d.day());
- dt.setDate(d);
- info->setLastModified(dt);
- }
- }
-
- // name
- if ( info->isSymLink() )
- info->setName( lst[ 8 ].stripWhiteSpace() );
- else {
- TQString n;
- for ( uint i = 8; i < lst.count(); ++i )
- n += lst[ i ] + " ";
- n = n.stripWhiteSpace();
- info->setName( n );
- }
- return TRUE;
-}
-
-void TQFtpDTP::socketConnected()
-{
-#if !defined (TQ_WS_TQWS)
- // Use a large send buffer to reduce the number
- // of writeBlocks when download and uploading files.
- // The actual size used here (128k) is default on most
- // Unixes.
- socket.socketDevice()->setSendBufferSize(128 * 1024);
- socket.socketDevice()->setReceiveBufferSize(128 * 1024);
-#endif
-
- bytesDone = 0;
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::connectState( CsConnected )" );
-#endif
- emit connectState( TQFtpDTP::CsConnected );
-}
-
-void TQFtpDTP::socketReadyRead()
-{
- if ( pi->currentCommand().isEmpty() ) {
- socket.close();
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::connectState( CsClosed )" );
-#endif
- emit connectState( TQFtpDTP::CsClosed );
- return;
- }
-
- if ( pi->currentCommand().startsWith("LIST") ) {
- while ( socket.canReadLine() ) {
- TQUrlInfo i;
- TQString line = socket.readLine();
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP read (list): '%s'", line.latin1() );
-#endif
- if ( parseDir( line, "", &i ) ) {
- emit listInfo( i );
- } else {
- // some FTP servers don't return a 550 if the file or directory
- // does not exist, but rather write a text to the data socket
- // -- try to catch these cases
- if ( line.endsWith( "No such file or directory\r\n" ) )
- err = line;
- }
- }
- } else {
- if ( !is_ba && data.dev ) {
- TQByteArray ba( socket.bytesAvailable() );
- TQ_LONG bytesRead = socket.readBlock( ba.data(), ba.size() );
- if ( bytesRead < 0 ) {
- // ### error handling
- return;
- }
- ba.resize( bytesRead );
- bytesDone += bytesRead;
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP read: %d bytes (total %d bytes)", (int)bytesRead, bytesDone );
-#endif
- emit dataTransferProgress( bytesDone, bytesTotal );
- if (data.dev) // make sure it wasn't deleted in the slot
- data.dev->writeBlock( ba );
- } else {
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP readyRead: %d bytes available (total %d bytes read)", (int)bytesAvailable(), bytesDone );
-#endif
- emit dataTransferProgress( bytesDone+socket.bytesAvailable(), bytesTotal );
- emit readyRead();
- }
- }
-}
-
-void TQFtpDTP::socketError( int e )
-{
- if ( e == TQSocket::ErrHostNotFound ) {
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::connectState( CsHostNotFound )" );
-#endif
- emit connectState( TQFtpDTP::CsHostNotFound );
- } else if ( e == TQSocket::ErrConnectionRefused ) {
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::connectState( CsConnectionRefused )" );
-#endif
- emit connectState( TQFtpDTP::CsConnectionRefused );
- }
-}
-
-void TQFtpDTP::socketConnectionClosed()
-{
- if ( !is_ba && data.dev ) {
- clearData();
- }
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::connectState( CsClosed )" );
-#endif
- emit connectState( TQFtpDTP::CsClosed );
-}
-
-void TQFtpDTP::socketBytesWritten( int bytes )
-{
- bytesDone += bytes;
-#if defined(TQFTPDTP_DEBUG)
- qDebug( "TQFtpDTP::bytesWritten( %d )", bytesDone );
-#endif
- emit dataTransferProgress( bytesDone, bytesTotal );
- if ( callWriteData )
- writeData();
-}
-
-/**********************************************************************
- *
- * TQFtpPI implemenatation
- *
- *********************************************************************/
-TQFtpPI::TQFtpPI( TQObject *parent ) :
- TQObject( parent ),
- rawCommand(FALSE),
- dtp( this ),
- commandSocket( 0, "TQFtpPI_socket" ),
- state( Begin ), abortState( None ),
- currentCmd( TQString::null ),
- waitForDtpToConnect( FALSE ),
- waitForDtpToClose( FALSE )
-{
- connect( &commandSocket, TQT_SIGNAL(hostFound()),
- TQT_SLOT(hostFound()) );
- connect( &commandSocket, TQT_SIGNAL(connected()),
- TQT_SLOT(connected()) );
- connect( &commandSocket, TQT_SIGNAL(connectionClosed()),
- TQT_SLOT(connectionClosed()) );
- connect( &commandSocket, TQT_SIGNAL(delayedCloseFinished()),
- TQT_SLOT(delayedCloseFinished()) );
- connect( &commandSocket, TQT_SIGNAL(readyRead()),
- TQT_SLOT(readyRead()) );
- connect( &commandSocket, TQT_SIGNAL(error(int)),
- TQT_SLOT(error(int)) );
-
- connect( &dtp, TQT_SIGNAL(connectState(int)),
- TQT_SLOT(dtpConnectState(int)) );
-}
-
-void TQFtpPI::connectToHost( const TQString &host, TQ_UINT16 port )
-{
- emit connectState( TQFtp::HostLookup );
- commandSocket.connectToHost( host, port );
-}
-
-/*
- Sends the sequence of commands \a cmds to the FTP server. When the commands
- are all done the finished() signal is emitted. When an error occurs, the
- error() signal is emitted.
-
- If there are pending commands in the queue this functions returns FALSE and
- the \a cmds are not added to the queue; otherwise it returns TRUE.
-*/
-bool TQFtpPI::sendCommands( const TQStringList &cmds )
-{
- if ( !pendingCommands.isEmpty() )
- return FALSE;
-
- if ( commandSocket.state()!=TQSocket::Connected || state!=Idle ) {
- emit error( TQFtp::NotConnected, TQFtp::tr( "Not connected" ) );
- return TRUE; // there are no pending commands
- }
-
- pendingCommands = cmds;
- startNextCmd();
- return TRUE;
-}
-
-void TQFtpPI::clearPendingCommands()
-{
- pendingCommands.clear();
- dtp.abortConnection();
- currentCmd = TQString::null;
- state = Idle;
-}
-
-void TQFtpPI::abort()
-{
- pendingCommands.clear();
-
- if ( abortState != None )
- // ABOR already sent
- return;
-
- abortState = AbortStarted;
-#if defined(TQFTPPI_DEBUG)
- qDebug( "TQFtpPI send: ABOR" );
-#endif
- commandSocket.writeBlock( "ABOR\r\n", 6 );
-
- if ( currentCmd.startsWith("STOR ") )
- dtp.abortConnection();
-}
-
-void TQFtpPI::hostFound()
-{
- emit connectState( TQFtp::Connecting );
-}
-
-void TQFtpPI::connected()
-{
- state = Begin;
-#if defined(TQFTPPI_DEBUG)
-// qDebug( "TQFtpPI state: %d [connected()]", state );
-#endif
- emit connectState( TQFtp::Connected );
-}
-
-void TQFtpPI::connectionClosed()
-{
- commandSocket.close();
- emit connectState( TQFtp::Unconnected );
-}
-
-void TQFtpPI::delayedCloseFinished()
-{
- emit connectState( TQFtp::Unconnected );
-}
-
-void TQFtpPI::error( int e )
-{
- if ( e == TQSocket::ErrHostNotFound ) {
- emit connectState( TQFtp::Unconnected );
- emit error( TQFtp::HostNotFound,
- TQFtp::tr( "Host %1 not found" ).arg( commandSocket.peerName() ) );
- } else if ( e == TQSocket::ErrConnectionRefused ) {
- emit connectState( TQFtp::Unconnected );
- emit error( TQFtp::ConnectionRefused,
- TQFtp::tr( "Connection refused to host %1" ).arg( commandSocket.peerName() ) );
- }
-}
-
-void TQFtpPI::readyRead()
-{
- if ( waitForDtpToClose )
- return;
-
- while ( commandSocket.canReadLine() ) {
- // read line with respect to line continuation
- TQString line = commandSocket.readLine();
- if ( replyText.isEmpty() ) {
- if ( line.length() < 3 ) {
- // ### protocol error
- return;
- }
- const int lowerLimit[3] = {1,0,0};
- const int upperLimit[3] = {5,5,9};
- for ( int i=0; i<3; i++ ) {
- replyCode[i] = line[i].digitValue();
- if ( replyCode[i]<lowerLimit[i] || replyCode[i]>upperLimit[i] ) {
- // ### protocol error
- return;
- }
- }
- }
- TQString endOfMultiLine;
- endOfMultiLine[0] = '0' + replyCode[0];
- endOfMultiLine[1] = '0' + replyCode[1];
- endOfMultiLine[2] = '0' + replyCode[2];
- endOfMultiLine[3] = ' ';
- TQString lineCont( endOfMultiLine );
- lineCont[3] = '-';
- TQString lineLeft4 = line.left(4);
-
- while ( lineLeft4 != endOfMultiLine ) {
- if ( lineLeft4 == lineCont )
- replyText += line.mid( 4 ); // strip 'xyz-'
- else
- replyText += line;
- if ( !commandSocket.canReadLine() )
- return;
- line = commandSocket.readLine();
- lineLeft4 = line.left(4);
- }
- replyText += line.mid( 4 ); // strip reply code 'xyz '
- if ( replyText.endsWith("\r\n") )
- replyText.truncate( replyText.length()-2 );
-
- if ( processReply() )
- replyText = "";
- }
-}
-
-/*
- Process a reply from the FTP server.
-
- Returns TRUE if the reply was processed or FALSE if the reply has to be
- processed at a later point.
-*/
-bool TQFtpPI::processReply()
-{
-#if defined(TQFTPPI_DEBUG)
-// qDebug( "TQFtpPI state: %d [processReply() begin]", state );
- if ( replyText.length() < 400 )
- qDebug( "TQFtpPI recv: %d %s", 100*replyCode[0]+10*replyCode[1]+replyCode[2], replyText.latin1() );
- else
- qDebug( "TQFtpPI recv: %d (text skipped)", 100*replyCode[0]+10*replyCode[1]+replyCode[2] );
-#endif
-
- // process 226 replies ("Closing Data Connection") only when the data
- // connection is really closed to avoid short reads of the DTP
- if ( 100*replyCode[0]+10*replyCode[1]+replyCode[2] == 226 ) {
- if ( dtp.socketState() != TQSocket::Idle ) {
- waitForDtpToClose = TRUE;
- return FALSE;
- }
- }
-
- switch ( abortState ) {
- case AbortStarted:
- abortState = WaitForAbortToFinish;
- break;
- case WaitForAbortToFinish:
- abortState = None;
- return TRUE;
- default:
- break;
- }
-
- // get new state
- static const State table[5] = {
- /* 1yz 2yz 3yz 4yz 5yz */
- Waiting, Success, Idle, Failure, Failure
- };
- switch ( state ) {
- case Begin:
- if ( replyCode[0] == 1 ) {
- return TRUE;
- } else if ( replyCode[0] == 2 ) {
- state = Idle;
- emit finished( TQFtp::tr( "Connected to host %1" ).arg( commandSocket.peerName() ) );
- break;
- }
- // ### error handling
- return TRUE;
- case Waiting:
- if ( replyCode[0]<0 || replyCode[0]>5 )
- state = Failure;
- else
- state = table[ replyCode[0] - 1 ];
- break;
- default:
- // ### spontaneous message
- return TRUE;
- }
-#if defined(TQFTPPI_DEBUG)
-// qDebug( "TQFtpPI state: %d [processReply() intermediate]", state );
-#endif
-
- // special actions on certain replies
- int replyCodeInt = 100*replyCode[0] + 10*replyCode[1] + replyCode[2];
- emit rawFtpReply( replyCodeInt, replyText );
- if ( rawCommand ) {
- rawCommand = FALSE;
- } else if ( replyCodeInt == 227 ) {
- // 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)
- // rfc959 does not define this response precisely, and gives
- // both examples where the parenthesis are used, and where
- // they are missing. We need to scan for the address and host
- // info.
- TQRegExp addrPortPattern("(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)");
- if (addrPortPattern.search(replyText) == -1) {
-#if defined(TQFTPPI_DEBUG)
- qDebug( "TQFtp: bad 227 response -- address and port information missing" );
-#endif
- // ### error handling
- } else {
- QStringList lst = addrPortPattern.capturedTexts();
- TQString host = lst[1] + "." + lst[2] + "." + lst[3] + "." + lst[4];
- TQ_UINT16 port = ( lst[5].toUInt() << 8 ) + lst[6].toUInt();
- waitForDtpToConnect = TRUE;
- dtp.connectToHost( host, port );
- }
- } else if ( replyCodeInt == 230 ) {
- if ( currentCmd.startsWith("USER ") && pendingCommands.count()>0 &&
- pendingCommands.first().startsWith("PASS ") ) {
- // no need to send the PASS -- we are already logged in
- pendingCommands.pop_front();
- }
- // 230 User logged in, proceed.
- emit connectState( TQFtp::LoggedIn );
- } else if ( replyCodeInt == 213 ) {
- // 213 File status.
- if ( currentCmd.startsWith("SIZE ") )
- dtp.setBytesTotal( replyText.simplifyWhiteSpace().toInt() );
- } else if ( replyCode[0]==1 && currentCmd.startsWith("STOR ") ) {
- dtp.writeData();
- }
-
- // react on new state
- switch ( state ) {
- case Begin:
- // ### should never happen
- break;
- case Success:
- // ### success handling
- state = Idle;
- // no break!
- case Idle:
- if ( dtp.hasError() ) {
- emit error( TQFtp::UnknownError, dtp.errorMessage() );
- dtp.clearError();
- }
- startNextCmd();
- break;
- case Waiting:
- // ### do nothing
- break;
- case Failure:
- emit error( TQFtp::UnknownError, replyText );
- state = Idle;
- startNextCmd();
- break;
- }
-#if defined(TQFTPPI_DEBUG)
-// qDebug( "TQFtpPI state: %d [processReply() end]", state );
-#endif
- return TRUE;
-}
-
-#ifndef TQT_NO_TEXTCODEC
-TQM_EXPORT_FTP TQTextCodec *qt_ftp_filename_codec = 0;
-#endif
-
-/*
- Starts next pending command. Returns FALSE if there are no pending commands,
- otherwise it returns TRUE.
-*/
-bool TQFtpPI::startNextCmd()
-{
- if ( waitForDtpToConnect )
- // don't process any new commands until we are connected
- return TRUE;
-
-#if defined(TQFTPPI_DEBUG)
- if ( state != Idle )
- qDebug( "TQFtpPI startNextCmd: Internal error! TQFtpPI called in non-Idle state %d", state );
-#endif
- if ( pendingCommands.isEmpty() ) {
- currentCmd = TQString::null;
- emit finished( replyText );
- return FALSE;
- }
- currentCmd = pendingCommands.first();
- pendingCommands.pop_front();
-#if defined(TQFTPPI_DEBUG)
- qDebug( "TQFtpPI send: %s", currentCmd.left( currentCmd.length()-2 ).latin1() );
-#endif
- state = Waiting;
-#ifndef TQT_NO_TEXTCODEC
- if ( qt_ftp_filename_codec ) {
- int len = 0;
- TQCString enc = qt_ftp_filename_codec->fromUnicode(currentCmd,len);
- commandSocket.writeBlock( enc.data(), len );
- } else
-#endif
- {
- commandSocket.writeBlock( currentCmd.latin1(), currentCmd.length() );
- }
- return TRUE;
-}
-
-void TQFtpPI::dtpConnectState( int s )
-{
- switch ( s ) {
- case TQFtpDTP::CsClosed:
- if ( waitForDtpToClose ) {
- // there is an unprocessed reply
- if ( processReply() )
- replyText = "";
- else
- return;
- }
- waitForDtpToClose = FALSE;
- readyRead();
- return;
- case TQFtpDTP::CsConnected:
- waitForDtpToConnect = FALSE;
- startNextCmd();
- return;
- case TQFtpDTP::CsHostNotFound:
- case TQFtpDTP::CsConnectionRefused:
- emit error( TQFtp::ConnectionRefused,
- TQFtp::tr( "Connection refused for data connection" ) );
- startNextCmd();
- return;
- default:
- return;
- }
-}
-
-/**********************************************************************
- *
- * TQFtpPrivate
- *
- *********************************************************************/
-class TQFtpPrivate
-{
-public:
- TQFtpPrivate() :
- close_waitForStateChange(FALSE),
- state( TQFtp::Unconnected ),
- error( TQFtp::NoError ),
- npWaitForLoginDone( FALSE )
- { pending.setAutoDelete( TRUE ); }
-
- TQFtpPI pi;
- TQPtrList<TQFtpCommand> pending;
- bool close_waitForStateChange;
- TQFtp::State state;
- TQFtp::Error error;
- TQString errorString;
-
- bool npWaitForLoginDone;
-};
-
-static TQPtrDict<TQFtpPrivate> *d_ptr = 0;
-static void cleanup_d_ptr()
-{
- delete d_ptr;
- d_ptr = 0;
-}
-static TQFtpPrivate* d( const TQFtp* foo )
-{
- if ( !d_ptr ) {
- d_ptr = new TQPtrDict<TQFtpPrivate>;
- d_ptr->setAutoDelete( TRUE );
- qAddPostRoutine( cleanup_d_ptr );
- }
- TQFtpPrivate* ret = d_ptr->find( (void*)foo );
- if ( ! ret ) {
- ret = new TQFtpPrivate;
- d_ptr->replace( (void*) foo, ret );
- }
- return ret;
-}
-
-static void delete_d( const TQFtp* foo )
-{
- if ( d_ptr )
- d_ptr->remove( (void*) foo );
-}
-
-/**********************************************************************
- *
- * TQFtp implementation
- *
- *********************************************************************/
-/*!
- \class TQFtp tqftp.h
- \brief The TQFtp class provides an implementation of the FTP protocol.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class provides two different interfaces: one is the
- TQNetworkProtocol interface that allows you to use FTP through the
- TQUrlOperator abstraction. The other is a direct interface to FTP
- that gives you lower-level access to the FTP protocol for finer
- control. Using the direct interface you can also execute arbitrary
- FTP commands.
-
- Don't mix the two interfaces, since the behavior is not
- well-defined.
-
- If you want to use TQFtp with the TQNetworkProtocol interface, you
- do not use it directly, but rather through a TQUrlOperator, for
- example:
-
- \code
- TQUrlOperator op( "ftp://ftp.trolltech.com" );
- op.listChildren(); // Asks the server to provide a directory listing
- \endcode
-
- This code will only work if the TQFtp class is registered; to
- register the class, you must call qInitNetworkProtocols() before
- using a TQUrlOperator with TQFtp.
-
- The rest of this descrption describes the direct interface to FTP.
-
- The class works asynchronously, so there are no blocking
- functions. If an operation cannot be executed immediately, the
- function will still return straight away and the operation will be
- scheduled for later execution. The results of scheduled operations
- are reported via Q_SIGNALS. This approach depends on the event loop
- being in operation.
-
- The operations that can be scheduled (they are called "commands"
- in the rest of the documentation) are the following:
- connectToHost(), login(), close(), list(), cd(), get(), put(),
- remove(), mkdir(), rmdir(), rename() and rawCommand().
-
- All of these commands return a unique identifier that allows you
- to keep track of the command that is currently being executed.
- When the execution of a command starts, the commandStarted()
- signal with the command's identifier is emitted. When the command
- is finished, the commandFinished() signal is emitted with the
- command's identifier and a bool that indicates whether the command
- finished with an error.
-
- In some cases, you might want to execute a sequence of commands,
- e.g. if you want to connect and login to a FTP server. This is
- simply achieved:
-
- \code
- TQFtp *ftp = new TQFtp( this ); // this is an optional TQObject parent
- ftp->connectToHost( "ftp.trolltech.com" );
- ftp->login();
- \endcode
-
- In this case two FTP commands have been scheduled. When the last
- scheduled command has finished, a done() signal is emitted with
- a bool argument that tells you whether the sequence finished with
- an error.
-
- If an error occurs during the execution of one of the commands in
- a sequence of commands, all the pending commands (i.e. scheduled,
- but not yet executed commands) are cleared and no Q_SIGNALS are
- emitted for them.
-
- Some commands, e.g. list(), emit additional Q_SIGNALS to report
- their results.
-
- Example: If you want to download the INSTALL file from Trolltech's
- FTP server, you would write this:
-
- \code
- ftp->connectToHost( "ftp.trolltech.com" ); // id == 1
- ftp->login(); // id == 2
- ftp->cd( "qt" ); // id == 3
- ftp->get( "INSTALL" ); // id == 4
- ftp->close(); // id == 5
- \endcode
-
- For this example the following sequence of Q_SIGNALS is emitted
- (with small variations, depending on network traffic, etc.):
-
- \code
- start( 1 )
- stateChanged( HostLookup )
- stateChanged( Connecting )
- stateChanged( Connected )
- finished( 1, FALSE )
-
- start( 2 )
- stateChanged( LoggedIn )
- finished( 2, FALSE )
-
- start( 3 )
- finished( 3, FALSE )
-
- start( 4 )
- dataTransferProgress( 0, 3798 )
- dataTransferProgress( 2896, 3798 )
- readyRead()
- dataTransferProgress( 3798, 3798 )
- readyRead()
- finished( 4, FALSE )
-
- start( 5 )
- stateChanged( Closing )
- stateChanged( Unconnected )
- finished( 5, FALSE )
-
- done( FALSE )
- \endcode
-
- The dataTransferProgress() signal in the above example is useful
- if you want to show a \link TQProgressBar progressbar \endlink to
- inform the user about the progress of the download. The
- readyRead() signal tells you that there is data ready to be read.
- The amount of data can be queried then with the bytesAvailable()
- function and it can be read with the readBlock() or readAll()
- function.
-
- If the login fails for the above example, the Q_SIGNALS would look
- like this:
-
- \code
- start( 1 )
- stateChanged( HostLookup )
- stateChanged( Connecting )
- stateChanged( Connected )
- finished( 1, FALSE )
-
- start( 2 )
- finished( 2, TRUE )
-
- done( TRUE )
- \endcode
-
- You can then get details about the error with the error() and
- errorString() functions.
-
- The functions currentId() and currentCommand() provide more
- information about the currently executing command.
-
- The functions hasPendingCommands() and clearPendingCommands()
- allow you to query and clear the list of pending commands.
-
- The safest and easiest way to use the FTP protocol is to use
- TQUrlOperator() or the FTP commands described above. If you are an
- experienced network programmer and want to have complete control
- you can use rawCommand() to execute arbitrary FTP commands.
-
- \sa \link network.html TQt Network Documentation \endlink TQNetworkProtocol, TQUrlOperator TQHttp
-*/
-
-/*!
- Constructs a TQFtp object.
-*/
-TQFtp::TQFtp() : TQNetworkProtocol()
-{
- init();
-}
-
-/*!
- Constructs a TQFtp object. The \a parent and \a name parameters
- are passed to the TQObject constructor.
-*/
-TQFtp::TQFtp( TQObject *parent, const char *name ) : TQNetworkProtocol()
-{
- if ( parent )
- parent->insertChild( this );
- TQT_TQOBJECT(this)->setName( name );
- init();
-}
-
-void TQFtp::init()
-{
- TQFtpPrivate *d = ::d( this );
- d->errorString = tr( "Unknown error" );
-
- connect( &d->pi, TQT_SIGNAL(connectState(int)),
- TQT_SLOT(piConnectState(int)) );
- connect( &d->pi, TQT_SIGNAL(finished(const TQString&)),
- TQT_SLOT(piFinished(const TQString&)) );
- connect( &d->pi, TQT_SIGNAL(error(int,const TQString&)),
- TQT_SLOT(piError(int,const TQString&)) );
- connect( &d->pi, TQT_SIGNAL(rawFtpReply(int,const TQString&)),
- TQT_SLOT(piFtpReply(int,const TQString&)) );
-
- connect( &d->pi.dtp, TQT_SIGNAL(readyRead()),
- TQT_SIGNAL(readyRead()) );
- connect( &d->pi.dtp, TQT_SIGNAL(dataTransferProgress(int,int)),
- TQT_SIGNAL(dataTransferProgress(int,int)) );
- connect( &d->pi.dtp, TQT_SIGNAL(listInfo(const TQUrlInfo&)),
- TQT_SIGNAL(listInfo(const TQUrlInfo&)) );
-}
-
-/*!
- \enum TQFtp::State
-
- This enum defines the connection state:
-
- \value Unconnected There is no connection to the host.
- \value HostLookup A host name lookup is in progress.
- \value Connecting An attempt to connect to the host is in progress.
- \value Connected Connection to the host has been achieved.
- \value LoggedIn Connection and user login have been achieved.
- \value Closing The connection is closing down, but it is not yet
- closed. (The state will be \c Unconnected when the connection is
- closed.)
-
- \sa stateChanged() state()
-*/
-/*!
- \enum TQFtp::Error
-
- This enum identifies the error that occurred.
-
- \value NoError No error occurred.
- \value HostNotFound The host name lookup failed.
- \value ConnectionRefused The server refused the connection.
- \value NotConnected Tried to send a command, but there is no connection to
- a server.
- \value UnknownError An error other than those specified above
- occurred.
-
- \sa error()
-*/
-
-/*!
- \enum TQFtp::Command
-
- This enum is used as the return value for the currentCommand() function.
- This allows you to perform specific actions for particular
- commands, e.g. in a FTP client, you might want to clear the
- directory view when a list() command is started; in this case you
- can simply check in the slot connected to the start() signal if
- the currentCommand() is \c List.
-
- \value None No command is being executed.
- \value ConnectToHost connectToHost() is being executed.
- \value Login login() is being executed.
- \value Close close() is being executed.
- \value List list() is being executed.
- \value Cd cd() is being executed.
- \value Get get() is being executed.
- \value Put put() is being executed.
- \value Remove remove() is being executed.
- \value Mkdir mkdir() is being executed.
- \value Rmdir rmdir() is being executed.
- \value Rename rename() is being executed.
- \value RawCommand rawCommand() is being executed.
-
- \sa currentCommand()
-*/
-
-/*!
- \fn void TQFtp::stateChanged( int state )
-
- This signal is emitted when the state of the connection changes.
- The argument \a state is the new state of the connection; it is
- one of the \l State values.
-
- It is usually emitted in response to a connectToHost() or close()
- command, but it can also be emitted "spontaneously", e.g. when the
- server closes the connection unexpectedly.
-
- \sa connectToHost() close() state() State
-*/
-
-/*!
- \fn void TQFtp::listInfo( const TQUrlInfo &i );
-
- This signal is emitted for each directory entry the list() command
- finds. The details of the entry are stored in \a i.
-
- \sa list()
-*/
-
-/*!
- \fn void TQFtp::commandStarted( int id )
-
- This signal is emitted when processing the command identified by
- \a id starts.
-
- \sa commandFinished() done()
-*/
-
-/*!
- \fn void TQFtp::commandFinished( int id, bool error )
-
- This signal is emitted when processing the command identified by
- \a id has finished. \a error is TRUE if an error occurred during
- the processing; otherwise \a error is FALSE.
-
- \sa commandStarted() done() error() errorString()
-*/
-
-/*!
- \fn void TQFtp::done( bool error )
-
- This signal is emitted when the last pending command has finished;
- (it is emitted after the last command's commandFinished() signal).
- \a error is TRUE if an error occurred during the processing;
- otherwise \a error is FALSE.
-
- \sa commandFinished() error() errorString()
-*/
-
-/*!
- \fn void TQFtp::readyRead()
-
- This signal is emitted in response to a get() command when there
- is new data to read.
-
- If you specify a tqdevice as the second argument in the get()
- command, this signal is \e not emitted; instead the data is
- written directly to the tqdevice.
-
- You can read the data with the readAll() or readBlock() functions.
-
- This signal is useful if you want to process the data in chunks as
- soon as it becomes available. If you are only interested in the
- complete data, just connect to the commandFinished() signal and
- read the data then instead.
-
- \sa get() readBlock() readAll() bytesAvailable()
-*/
-
-/*!
- \fn void TQFtp::dataTransferProgress( int done, int total )
-
- This signal is emitted in response to a get() or put() request to
- indicate the current progress of the download or upload.
-
- \a done is the amount of data that has already been transferred
- and \a total is the total amount of data to be read or written. It
- is possible that the TQFtp class is not able to determine the total
- amount of data that should be transferred, in which case \a total
- is 0. (If you connect this signal to a TQProgressBar, the progress
- bar shows a busy indicator if the total is 0).
-
- \warning \a done and \a total are not necessarily the size in
- bytes, since for large files these values might need to be
- "scaled" to avoid overflow.
-
- \sa get() put() TQProgressBar::setProgress()
-*/
-
-/*!
- \fn void TQFtp::rawCommandReply( int replyCode, const TQString &detail );
-
- This signal is emitted in response to the rawCommand() function.
- \a replyCode is the 3 digit reply code and \a detail is the text
- that follows the reply code.
-
- \sa rawCommand()
-*/
-
-/*!
- Connects to the FTP server \a host using port \a port.
-
- The stateChanged() signal is emitted when the state of the
- connecting process changes, e.g. to \c HostLookup, then \c
- Connecting, then \c Connected.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa stateChanged() commandStarted() commandFinished()
-*/
-int TQFtp::connectToHost( const TQString &host, TQ_UINT16 port )
-{
- TQStringList cmds;
- cmds << host;
- cmds << TQString::number( (uint)port );
- return addCommand( new TQFtpCommand( ConnectToHost, cmds ) );
-}
-
-/*!
- Logs in to the FTP server with the username \a user and the
- password \a password.
-
- The stateChanged() signal is emitted when the state of the
- connecting process changes, e.g. to \c LoggedIn.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa commandStarted() commandFinished()
-*/
-int TQFtp::login( const TQString &user, const TQString &password )
-{
- TQStringList cmds;
- cmds << ( TQString("USER ") + ( user.isNull() ? TQString("anonymous") : user ) + "\r\n" );
- cmds << ( TQString("PASS ") + ( password.isNull() ? TQString("anonymous@") : password ) + "\r\n" );
- return addCommand( new TQFtpCommand( Login, cmds ) );
-}
-
-/*!
- Closes the connection to the FTP server.
-
- The stateChanged() signal is emitted when the state of the
- connecting process changes, e.g. to \c Closing, then \c
- Unconnected.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa stateChanged() commandStarted() commandFinished()
-*/
-int TQFtp::close()
-{
- return addCommand( new TQFtpCommand( Close, TQStringList("TQUIT\r\n") ) );
-}
-
-/*!
- Lists the contents of directory \a dir on the FTP server. If \a
- dir is empty, it lists the contents of the current directory.
-
- The listInfo() signal is emitted for each directory entry found.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa listInfo() commandStarted() commandFinished()
-*/
-int TQFtp::list( const TQString &dir )
-{
- TQStringList cmds;
- cmds << "TYPE A\r\n";
- cmds << "PASV\r\n";
- if ( dir.isEmpty() )
- cmds << "LIST\r\n";
- else
- cmds << ( "LIST " + dir + "\r\n" );
- return addCommand( new TQFtpCommand( List, cmds ) );
-}
-
-/*!
- Changes the working directory of the server to \a dir.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa commandStarted() commandFinished()
-*/
-int TQFtp::cd( const TQString &dir )
-{
- return addCommand( new TQFtpCommand( Cd, TQStringList("CWD "+dir+"\r\n") ) );
-}
-
-/*!
- Downloads the file \a file from the server.
-
- If \a dev is 0, then the readyRead() signal is emitted when there
- is data available to read. You can then read the data with the
- readBlock() or readAll() functions.
-
- If \a dev is not 0, the data is written directly to the tqdevice \a
- dev. Make sure that the \a dev pointer is valid for the duration
- of the operation (it is safe to delete it when the
- commandFinished() signal is emitted). In this case the readyRead()
- signal is \e not emitted and you cannot read data with the
- readBlock() or readAll() functions.
-
- If you don't read the data immediately it becomes available, i.e.
- when the readyRead() signal is emitted, it is still available
- until the next command is started.
-
- For example, if you want to present the data to the user as soon
- as there is something available, connect to the readyRead() signal
- and read the data immediately. On the other hand, if you only want
- to work with the complete data, you can connect to the
- commandFinished() signal and read the data when the get() command
- is finished.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa readyRead() dataTransferProgress() commandStarted()
- commandFinished()
-*/
-int TQFtp::get( const TQString &file, TQIODevice *dev )
-{
- TQStringList cmds;
- cmds << ( "SIZE " + file + "\r\n" );
- cmds << "TYPE I\r\n";
- cmds << "PASV\r\n";
- cmds << ( "RETR " + file + "\r\n" );
- if ( dev )
- return addCommand( new TQFtpCommand( Get, cmds, dev ) );
- return addCommand( new TQFtpCommand( Get, cmds ) );
-}
-
-/*!
- \overload
-
- Writes the data \a data to the file called \a file on the server.
- The progress of the upload is reported by the
- dataTransferProgress() signal.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa dataTransferProgress() commandStarted() commandFinished()
-*/
-int TQFtp::put( const TQByteArray &data, const TQString &file )
-{
- TQStringList cmds;
- cmds << "TYPE I\r\n";
- cmds << "PASV\r\n";
- cmds << ( "ALLO " + TQString::number(data.size()) + "\r\n" );
- cmds << ( "STOR " + file + "\r\n" );
- return addCommand( new TQFtpCommand( Put, cmds, data ) );
-}
-
-/*!
- Reads the data from the IO tqdevice \a dev, and writes it to the
- file called \a file on the server. The data is read in chunks from
- the IO tqdevice, so this overload allows you to transmit large
- amounts of data without the need to read all the data into memory
- at once.
-
- Make sure that the \a dev pointer is valid for the duration of the
- operation (it is safe to delete it when the commandFinished() is
- emitted).
-*/
-int TQFtp::put( TQIODevice *dev, const TQString &file )
-{
- TQStringList cmds;
- cmds << "TYPE I\r\n";
- cmds << "PASV\r\n";
- if ( !dev->isSequentialAccess() )
- cmds << ( "ALLO " + TQString::number(dev->size()) + "\r\n" );
- cmds << ( "STOR " + file + "\r\n" );
- return addCommand( new TQFtpCommand( Put, cmds, dev ) );
-}
-
-/*!
- Deletes the file called \a file from the server.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa commandStarted() commandFinished()
-*/
-int TQFtp::remove( const TQString &file )
-{
- return addCommand( new TQFtpCommand( Remove, TQStringList("DELE "+file+"\r\n") ) );
-}
-
-/*!
- Creates a directory called \a dir on the server.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa commandStarted() commandFinished()
-*/
-int TQFtp::mkdir( const TQString &dir )
-{
- return addCommand( new TQFtpCommand( Mkdir, TQStringList("MKD "+dir+"\r\n") ) );
-}
-
-/*!
- Removes the directory called \a dir from the server.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa commandStarted() commandFinished()
-*/
-int TQFtp::rmdir( const TQString &dir )
-{
- return addCommand( new TQFtpCommand( Rmdir, TQStringList("RMD "+dir+"\r\n") ) );
-}
-
-/*!
- Renames the file called \a oldname to \a newname on the server.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa commandStarted() commandFinished()
-*/
-int TQFtp::rename( const TQString &oldname, const TQString &newname )
-{
- TQStringList cmds;
- cmds << ( "RNFR " + oldname + "\r\n" );
- cmds << ( "RNTO " + newname + "\r\n" );
- return addCommand( new TQFtpCommand( Rename, cmds ) );
-}
-
-/*!
- Sends the raw FTP command \a command to the FTP server. This is
- useful for low-level FTP access. If the operation you wish to
- perform has an equivalent TQFtp function, we recommend using the
- function instead of raw FTP commands since the functions are
- easier and safer.
-
- The function does not block and returns immediately. The command
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- commandStarted() and commandFinished().
-
- When the command is started the commandStarted() signal is
- emitted. When it is finished the commandFinished() signal is
- emitted.
-
- \sa rawCommandReply() commandStarted() commandFinished()
-*/
-int TQFtp::rawCommand( const TQString &command )
-{
- TQString cmd = command.stripWhiteSpace() + "\r\n";
- return addCommand( new TQFtpCommand( RawCommand, TQStringList(cmd) ) );
-}
-
-/*!
- Returns the number of bytes that can be read from the data socket
- at the moment.
-
- \sa get() readyRead() readBlock() readAll()
-*/
-TQ_ULONG TQFtp::bytesAvailable() const
-{
- TQFtpPrivate *d = ::d( this );
- return d->pi.dtp.bytesAvailable();
-}
-
-/*!
- Reads \a maxlen bytes from the data socket into \a data and
- returns the number of bytes read. Returns -1 if an error occurred.
-
- \sa get() readyRead() bytesAvailable() readAll()
-*/
-TQ_LONG TQFtp::readBlock( char *data, TQ_ULONG maxlen )
-{
- TQFtpPrivate *d = ::d( this );
- return d->pi.dtp.readBlock( data, maxlen );
-}
-
-/*!
- Reads all the bytes available from the data socket and returns
- them.
-
- \sa get() readyRead() bytesAvailable() readBlock()
-*/
-TQByteArray TQFtp::readAll()
-{
- TQFtpPrivate *d = ::d( this );
- return d->pi.dtp.readAll();
-}
-
-/*!
- Aborts the current command and deletes all scheduled commands.
-
- If there is an unfinished command (i.e. a command for which the
- commandStarted() signal has been emitted, but for which the
- commandFinished() signal has not been emitted), this function
- sends an \c ABORT command to the server. When the server replies
- that the command is aborted, the commandFinished() signal with the
- \c error argument set to \c TRUE is emitted for the command. Due
- to timing issues, it is possible that the command had already
- finished before the abort request reached the server, in which
- case, the commandFinished() signal is emitted with the \c error
- argument set to \c FALSE.
-
- For all other commands that are affected by the abort(), no
- Q_SIGNALS are emitted.
-
- If you don't start further FTP commands directly after the
- abort(), there won't be any scheduled commands and the done()
- signal is emitted.
-
- \warning Some FTP servers, for example the BSD FTP daemon (version
- 0.3), wrongly return a positive reply even when an abort has
- occurred. For these servers the commandFinished() signal has its
- error flag set to \c FALSE, even though the command did not
- complete successfully.
-
- \sa clearPendingCommands()
-*/
-void TQFtp::abort()
-{
- TQFtpPrivate *d = ::d( this );
- if ( d->pending.isEmpty() )
- return;
-
- clearPendingCommands();
- d->pi.abort();
-}
-
-/*!
- Returns the identifier of the FTP command that is being executed
- or 0 if there is no command being executed.
-
- \sa currentCommand()
-*/
-int TQFtp::currentId() const
-{
- TQFtpPrivate *d = ::d( this );
- TQFtpCommand *c = d->pending.getFirst();
- if ( c == 0 )
- return 0;
- return c->id;
-}
-
-/*!
- Returns the command type of the FTP command being executed or \c
- None if there is no command being executed.
-
- \sa currentId()
-*/
-TQFtp::Command TQFtp::currentCommand() const
-{
- TQFtpPrivate *d = ::d( this );
- TQFtpCommand *c = d->pending.getFirst();
- if ( c == 0 )
- return None;
- return c->command;
-}
-
-/*!
- Returns the TQIODevice pointer that is used by the FTP command to read data
- from or store data to. If there is no current FTP command being executed or
- if the command does not use an IO tqdevice, this function returns 0.
-
- This function can be used to delete the TQIODevice in the slot connected to
- the commandFinished() signal.
-
- \sa get() put()
-*/
-TQIODevice* TQFtp::currentDevice() const
-{
- TQFtpPrivate *d = ::d( this );
- TQFtpCommand *c = d->pending.getFirst();
- if ( !c )
- return 0;
- if ( c->is_ba )
- return 0;
- return c->data.dev;
-}
-
-/*!
- Returns TRUE if there are any commands scheduled that have not yet
- been executed; otherwise returns FALSE.
-
- The command that is being executed is \e not considered as a
- scheduled command.
-
- \sa clearPendingCommands() currentId() currentCommand()
-*/
-bool TQFtp::hasPendingCommands() const
-{
- TQFtpPrivate *d = ::d( this );
- return d->pending.count() > 1;
-}
-
-/*!
- Deletes all pending commands from the list of scheduled commands.
- This does not affect the command that is being executed. If you
- want to stop this this as well, use abort().
-
- \sa hasPendingCommands() abort()
-*/
-void TQFtp::clearPendingCommands()
-{
- TQFtpPrivate *d = ::d( this );
- TQFtpCommand *c = 0;
- if ( d->pending.count() > 0 )
- c = d->pending.take( 0 );
- d->pending.clear();
- if ( c )
- d->pending.append( c );
-}
-
-/*!
- Returns the current state of the object. When the state changes,
- the stateChanged() signal is emitted.
-
- \sa State stateChanged()
-*/
-TQFtp::State TQFtp::state() const
-{
- TQFtpPrivate *d = ::d( this );
- return d->state;
-}
-
-/*!
- Returns the last error that occurred. This is useful to find out
- what when wrong when receiving a commandFinished() or a done()
- signal with the \c error argument set to \c TRUE.
-
- If you start a new command, the error status is reset to \c NoError.
-*/
-TQFtp::Error TQFtp::error() const
-{
- TQFtpPrivate *d = ::d( this );
- return d->error;
-}
-
-/*!
- Returns a human-readable description of the last error that
- occurred. This is useful for presenting a error message to the
- user when receiving a commandFinished() or a done() signal with
- the \c error argument set to \c TRUE.
-
- The error string is often (but not always) the reply from the
- server, so it is not always possible to translate the string. If
- the message comes from TQt, the string has already passed through
- tr().
-*/
-TQString TQFtp::errorString() const
-{
- TQFtpPrivate *d = ::d( this );
- return d->errorString;
-}
-
-int TQFtp::addCommand( TQFtpCommand *cmd )
-{
- TQFtpPrivate *d = ::d( this );
- d->pending.append( cmd );
-
- if ( d->pending.count() == 1 )
- // don't emit the commandStarted() signal before the id is returned
- TQTimer::singleShot( 0, this, TQT_SLOT(startNextCommand()) );
-
- return cmd->id;
-}
-
-void TQFtp::startNextCommand()
-{
- TQFtpPrivate *d = ::d( this );
-
- TQFtpCommand *c = d->pending.getFirst();
- if ( c == 0 )
- return;
-
- d->error = NoError;
- d->errorString = tr( "Unknown error" );
-
- if ( bytesAvailable() )
- readAll(); // clear the data
- emit commandStarted( c->id );
-
- if ( c->command == ConnectToHost ) {
- d->pi.connectToHost( c->rawCmds[0], c->rawCmds[1].toUInt() );
- } else {
- if ( c->command == Put ) {
- if ( c->is_ba ) {
- d->pi.dtp.setData( c->data.ba );
- d->pi.dtp.setBytesTotal( c->data.ba->size() );
- } else if ( c->data.dev && (c->data.dev->isOpen() || c->data.dev->open(IO_ReadOnly) ) ) {
- d->pi.dtp.setDevice( c->data.dev );
- if ( c->data.dev->isSequentialAccess() )
- d->pi.dtp.setBytesTotal( 0 );
- else
- d->pi.dtp.setBytesTotal( c->data.dev->size() );
- }
- } else if ( c->command == Get ) {
- if ( !c->is_ba && c->data.dev ) {
- d->pi.dtp.setDevice( c->data.dev );
- }
- } else if ( c->command == Close ) {
- d->state = TQFtp::Closing;
- emit stateChanged( d->state );
- }
- if ( !d->pi.sendCommands( c->rawCmds ) ) {
- // ### error handling (this case should not happen)
- }
- }
-}
-
-void TQFtp::piFinished( const TQString& )
-{
- TQFtpPrivate *d = ::d( this );
- TQFtpCommand *c = d->pending.getFirst();
- if ( c == 0 )
- return;
-
- if ( c->command == Close ) {
- // The order of in which the Q_SLOTS are called is arbitrary, so
- // disconnect the SIGNAL-TQT_SIGNAL temporary to make sure that we
- // don't get the commandFinished() signal before the stateChanged()
- // signal.
- if ( d->state != TQFtp::Unconnected ) {
- d->close_waitForStateChange = TRUE;
- return;
- }
- }
- emit commandFinished( c->id, FALSE );
-
- d->pending.removeFirst();
- if ( d->pending.isEmpty() ) {
- emit done( FALSE );
- } else {
- startNextCommand();
- }
-}
-
-void TQFtp::piError( int errorCode, const TQString &text )
-{
- TQFtpPrivate *d = ::d( this );
- TQFtpCommand *c = d->pending.getFirst();
-
- // non-fatal errors
- if ( c->command==Get && d->pi.currentCommand().startsWith("SIZE ") ) {
- d->pi.dtp.setBytesTotal( -1 );
- return;
- } else if ( c->command==Put && d->pi.currentCommand().startsWith("ALLO ") ) {
- return;
- }
-
- d->error = (Error)errorCode;
- switch ( currentCommand() ) {
- case ConnectToHost:
- d->errorString = tr( "Connecting to host failed:\n%1" ).arg( text );
- break;
- case Login:
- d->errorString = tr( "Login failed:\n%1" ).arg( text );
- break;
- case List:
- d->errorString = tr( "Listing directory failed:\n%1" ).arg( text );
- break;
- case Cd:
- d->errorString = tr( "Changing directory failed:\n%1" ).arg( text );
- break;
- case Get:
- d->errorString = tr( "Downloading file failed:\n%1" ).arg( text );
- break;
- case Put:
- d->errorString = tr( "Uploading file failed:\n%1" ).arg( text );
- break;
- case Remove:
- d->errorString = tr( "Removing file failed:\n%1" ).arg( text );
- break;
- case Mkdir:
- d->errorString = tr( "Creating directory failed:\n%1" ).arg( text );
- break;
- case Rmdir:
- d->errorString = tr( "Removing directory failed:\n%1" ).arg( text );
- break;
- default:
- d->errorString = text;
- break;
- }
-
- d->pi.clearPendingCommands();
- clearPendingCommands();
- emit commandFinished( c->id, TRUE );
-
- d->pending.removeFirst();
- if ( d->pending.isEmpty() )
- emit done( TRUE );
- else
- startNextCommand();
-}
-
-void TQFtp::piConnectState( int state )
-{
- TQFtpPrivate *d = ::d( this );
- d->state = (State)state;
- emit stateChanged( d->state );
- if ( d->close_waitForStateChange ) {
- d->close_waitForStateChange = FALSE;
- piFinished( tr( "Connection closed" ) );
- }
-}
-
-void TQFtp::piFtpReply( int code, const TQString &text )
-{
- if ( currentCommand() == RawCommand ) {
- TQFtpPrivate *d = ::d( this );
- d->pi.rawCommand = TRUE;
- emit rawCommandReply( code, text );
- }
-}
-
-/*!
- Destructor.
-*/
-TQFtp::~TQFtp()
-{
- abort();
- close();
- delete_d( this );
-}
-
-/**********************************************************************
- *
- * TQFtp implementation of the TQNetworkProtocol interface
- *
- *********************************************************************/
-/*! \reimp
-*/
-void TQFtp::operationListChildren( TQNetworkOperation *op )
-{
- op->setState( StInProgress );
-
- cd( ( url()->path().isEmpty() ? TQString( "/" ) : url()->path() ) );
- list();
- emit start( op );
-}
-
-/*! \reimp
-*/
-void TQFtp::operationMkDir( TQNetworkOperation *op )
-{
- op->setState( StInProgress );
-
- mkdir( op->arg( 0 ) );
-}
-
-/*! \reimp
-*/
-void TQFtp::operationRemove( TQNetworkOperation *op )
-{
- op->setState( StInProgress );
-
- cd( ( url()->path().isEmpty() ? TQString( "/" ) : url()->path() ) );
- remove( TQUrl( op->arg( 0 ) ).path() );
-}
-
-/*! \reimp
-*/
-void TQFtp::operationRename( TQNetworkOperation *op )
-{
- op->setState( StInProgress );
-
- cd( ( url()->path().isEmpty() ? TQString( "/" ) : url()->path() ) );
- rename( op->arg( 0 ), op->arg( 1 ));
-}
-
-/*! \reimp
-*/
-void TQFtp::operationGet( TQNetworkOperation *op )
-{
- op->setState( StInProgress );
-
- TQUrl u( op->arg( 0 ) );
- get( u.path() );
-}
-
-/*! \reimp
-*/
-void TQFtp::operationPut( TQNetworkOperation *op )
-{
- op->setState( StInProgress );
-
- TQUrl u( op->arg( 0 ) );
- put( op->rawArg(1), u.path() );
-}
-
-/*! \reimp
-*/
-bool TQFtp::checkConnection( TQNetworkOperation *op )
-{
- TQFtpPrivate *d = ::d( this );
- if ( state() == Unconnected && !d->npWaitForLoginDone ) {
- connect( this, TQT_SIGNAL(listInfo(const TQUrlInfo&)),
- this, TQT_SLOT(npListInfo(const TQUrlInfo&)) );
- connect( this, TQT_SIGNAL(done(bool)),
- this, TQT_SLOT(npDone(bool)) );
- connect( this, TQT_SIGNAL(stateChanged(int)),
- this, TQT_SLOT(npStateChanged(int)) );
- connect( this, TQT_SIGNAL(dataTransferProgress(int,int)),
- this, TQT_SLOT(npDataTransferProgress(int,int)) );
- connect( this, TQT_SIGNAL(readyRead()),
- this, TQT_SLOT(npReadyRead()) );
-
- d->npWaitForLoginDone = TRUE;
- switch ( op->operation() ) {
- case OpGet:
- case OpPut:
- {
- TQUrl u( op->arg( 0 ) );
- connectToHost( u.host(), u.port() != -1 ? u.port() : 21 );
- }
- break;
- default:
- connectToHost( url()->host(), url()->port() != -1 ? url()->port() : 21 );
- break;
- }
- TQString user = url()->user().isEmpty() ? TQString( "anonymous" ) : url()->user();
- TQString pass = url()->password().isEmpty() ? TQString( "anonymous@" ) : url()->password();
- login( user, pass );
- }
-
- if ( state() == LoggedIn )
- return TRUE;
- return FALSE;
-}
-
-/*! \reimp
-*/
-int TQFtp::supportedOperations() const
-{
- return OpListChildren | OpMkDir | OpRemove | OpRename | OpGet | OpPut;
-}
-
-/*! \internal
- Parses the string, \a buffer, which is one line of a directory
- listing which came from the FTP server, and sets the values which
- have been parsed to the url info object, \a info.
-*/
-void TQFtp::parseDir( const TQString &buffer, TQUrlInfo &info )
-{
- TQFtpDTP::parseDir( buffer, url()->user(), &info );
-}
-
-void TQFtp::npListInfo( const TQUrlInfo & i )
-{
- if ( url() ) {
- TQRegExp filt( url()->nameFilter(), FALSE, TRUE );
- if ( i.isDir() || filt.search( i.name() ) != -1 ) {
- emit newChild( i, operationInProgress() );
- }
- } else {
- emit newChild( i, operationInProgress() );
- }
-}
-
-void TQFtp::npDone( bool err )
-{
- TQFtpPrivate *d = ::d( this );
-
- bool emitFinishedSignal = FALSE;
- TQNetworkOperation *op = operationInProgress();
- if ( op ) {
- if ( err ) {
- op->setProtocolDetail( errorString() );
- op->setState( StFailed );
- if ( error() == HostNotFound ) {
- op->setErrorCode( (int)ErrHostNotFound );
- } else {
- switch ( op->operation() ) {
- case OpListChildren:
- op->setErrorCode( (int)ErrListChildren );
- break;
- case OpMkDir:
- op->setErrorCode( (int)ErrMkDir );
- break;
- case OpRemove:
- op->setErrorCode( (int)ErrRemove );
- break;
- case OpRename:
- op->setErrorCode( (int)ErrRename );
- break;
- case OpGet:
- op->setErrorCode( (int)ErrGet );
- break;
- case OpPut:
- op->setErrorCode( (int)ErrPut );
- break;
- }
- }
- emitFinishedSignal = TRUE;
- } else if ( !d->npWaitForLoginDone ) {
- switch ( op->operation() ) {
- case OpRemove:
- emit removed( op );
- break;
- case OpMkDir:
- {
- TQUrlInfo inf( op->arg( 0 ), 0, "", "", 0, TQDateTime(),
- TQDateTime(), TRUE, FALSE, FALSE, TRUE, TRUE, TRUE );
- emit newChild( inf, op );
- emit createdDirectory( inf, op );
- }
- break;
- case OpRename:
- emit itemChanged( operationInProgress() );
- break;
- default:
- break;
- }
- op->setState( StDone );
- emitFinishedSignal = TRUE;
- }
- }
- d->npWaitForLoginDone = FALSE;
-
- if ( state() == Unconnected ) {
- disconnect( this, TQT_SIGNAL(listInfo(const TQUrlInfo&)),
- this, TQT_SLOT(npListInfo(const TQUrlInfo&)) );
- disconnect( this, TQT_SIGNAL(done(bool)),
- this, TQT_SLOT(npDone(bool)) );
- disconnect( this, TQT_SIGNAL(stateChanged(int)),
- this, TQT_SLOT(npStateChanged(int)) );
- disconnect( this, TQT_SIGNAL(dataTransferProgress(int,int)),
- this, TQT_SLOT(npDataTransferProgress(int,int)) );
- disconnect( this, TQT_SIGNAL(readyRead()),
- this, TQT_SLOT(npReadyRead()) );
- }
-
- // emit the finished() signal at the very end to avoid reentrance problems
- if ( emitFinishedSignal )
- emit finished( op );
-}
-
-void TQFtp::npStateChanged( int state )
-{
- if ( url() ) {
- if ( state == Connecting )
- emit connectionStateChanged( ConHostFound, tr( "Host %1 found" ).arg( url()->host() ) );
- else if ( state == Connected )
- emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) );
- else if ( state == Unconnected )
- emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) );
- } else {
- if ( state == Connecting )
- emit connectionStateChanged( ConHostFound, tr( "Host found" ) );
- else if ( state == Connected )
- emit connectionStateChanged( ConConnected, tr( "Connected to host" ) );
- else if ( state == Unconnected )
- emit connectionStateChanged( ConClosed, tr( "Connection closed" ) );
- }
-}
-
-void TQFtp::npDataTransferProgress( int bDone, int bTotal )
-{
- emit TQNetworkProtocol::dataTransferProgress( bDone, bTotal, operationInProgress() );
-}
-
-void TQFtp::npReadyRead()
-{
- emit data( readAll(), operationInProgress() );
-}
-
-// ### unused -- delete in TQt 4.0
-/*! \internal
-*/
-void TQFtp::hostFound()
-{
-}
-/*! \internal
-*/
-void TQFtp::connected()
-{
-}
-/*! \internal
-*/
-void TQFtp::closed()
-{
-}
-/*! \internal
-*/
-void TQFtp::dataHostFound()
-{
-}
-/*! \internal
-*/
-void TQFtp::dataConnected()
-{
-}
-/*! \internal
-*/
-void TQFtp::dataClosed()
-{
-}
-/*! \internal
-*/
-void TQFtp::dataReadyRead()
-{
-}
-/*! \internal
-*/
-void TQFtp::dataBytesWritten( int )
-{
-}
-/*! \internal
-*/
-void TQFtp::error( int )
-{
-}
-
-#include "tqftp.tqmoc"
-
-#endif // TQT_NO_NETWORKPROTOCOL_FTP
diff --git a/tqtinterface/qt4/src/network/tqftp.h b/tqtinterface/qt4/src/network/tqftp.h
deleted file mode 100644
index afa7461..0000000
--- a/tqtinterface/qt4/src/network/tqftp.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Definition of TQFtp class.
-**
-** Created : 970521
-**
-** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQFTP_H
-#define TQFTP_H
-
-#ifndef TQT_H
-#include "tqstring.h" // char*->TQString conversion
-#include "tqurlinfo.h"
-#include "tqcstring.h"
-#include "tqnetworkprotocol.h"
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_FTP
-#else
-#define TQM_EXPORT_FTP TQ_EXPORT
-#endif
-
-#ifndef TQT_NO_NETWORKPROTOCOL_FTP
-
-
-class TQSocket;
-class TQFtpCommand;
-
-class TQM_EXPORT_FTP TQFtp : public TQNetworkProtocol
-{
- Q_OBJECT
- TQ_OBJECT
-
-public:
- TQFtp(); // ### TQt 4.0: get rid of this overload
- TQFtp( TQObject *parent, const char *name=0 );
- virtual ~TQFtp();
-
- int supportedOperations() const;
-
- // non-TQNetworkProtocol functions:
- enum State {
- Unconnected,
- HostLookup,
- Connecting,
- Connected,
- LoggedIn,
- Closing
- };
- enum Error {
- NoError,
- UnknownError,
- HostNotFound,
- ConnectionRefused,
- NotConnected
- };
- enum Command {
- None,
- ConnectToHost,
- Login,
- Close,
- List,
- Cd,
- Get,
- Put,
- Remove,
- Mkdir,
- Rmdir,
- Rename,
- RawCommand
- };
-
- int connectToHost( const TQString &host, TQ_UINT16 port=21 );
- int login( const TQString &user=TQString::null, const TQString &password=TQString::null );
- int close();
- int list( const TQString &dir=TQString::null );
- int cd( const TQString &dir );
- int get( const TQString &file, TQIODevice *dev=0 );
- int put( const TQByteArray &data, const TQString &file );
- int put( TQIODevice *dev, const TQString &file );
- int remove( const TQString &file );
- int mkdir( const TQString &dir );
- int rmdir( const TQString &dir );
- int rename( const TQString &oldname, const TQString &newname );
-
- int rawCommand( const TQString &command );
-
- TQ_ULONG bytesAvailable() const;
- TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
- TQByteArray readAll();
-
- int currentId() const;
- TQIODevice* currentDevice() const;
- Command currentCommand() const;
- bool hasPendingCommands() const;
- void clearPendingCommands();
-
- State state() const;
-
- Error error() const;
- TQString errorString() const;
-
-public Q_SLOTS:
- void abort();
-
-Q_SIGNALS:
- void stateChanged( int );
- void listInfo( const TQUrlInfo& );
- void readyRead();
- void dataTransferProgress( int, int );
- void rawCommandReply( int, const TQString& );
-
- void commandStarted( int );
- void commandFinished( int, bool );
- void done( bool );
-
-protected:
- void parseDir( const TQString &buffer, TQUrlInfo &info ); // ### TQt 4.0: delete this? (not public API)
- void operationListChildren( TQNetworkOperation *op );
- void operationMkDir( TQNetworkOperation *op );
- void operationRemove( TQNetworkOperation *op );
- void operationRename( TQNetworkOperation *op );
- void operationGet( TQNetworkOperation *op );
- void operationPut( TQNetworkOperation *op );
-
- // ### TQt 4.0: delete these
- // unused variables:
- TQSocket *commandSocket, *dataSocket;
- bool connectionReady, passiveMode;
- int getTotalSize, getDoneSize;
- bool startGetOnFail;
- int putToWrite, putWritten;
- bool errorInListChildren;
-
-private:
- void init();
- int addCommand( TQFtpCommand * );
-
- bool checkConnection( TQNetworkOperation *op );
-
-private Q_SLOTS:
- void startNextCommand();
- void piFinished( const TQString& );
- void piError( int, const TQString& );
- void piConnectState( int );
- void piFtpReply( int, const TQString& );
-
-private Q_SLOTS:
- void npListInfo( const TQUrlInfo & );
- void npDone( bool );
- void npStateChanged( int );
- void npDataTransferProgress( int, int );
- void npReadyRead();
-
-protected Q_SLOTS:
- // ### TQt 4.0: delete these
- void hostFound();
- void connected();
- void closed();
- void dataHostFound();
- void dataConnected();
- void dataClosed();
- void dataReadyRead();
- void dataBytesWritten( int nbytes );
- void error( int );
-};
-
-#endif // TQT_NO_NETWORKPROTOCOL_FTP
-
-#endif // TQFTP_H
diff --git a/tqtinterface/qt4/src/network/tqhostaddress.cpp b/tqtinterface/qt4/src/network/tqhostaddress.cpp
deleted file mode 100644
index 5a4e5cf..0000000
--- a/tqtinterface/qt4/src/network/tqhostaddress.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQHostAddress class.
-**
-** Created : 979899
-**
-** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqhostaddress.h"
-#include "tqstringlist.h"
-
-#ifdef USE_QT4
-
-#else // USE_QT4
-
-#ifndef TQT_NO_NETWORK
-class TQHostAddressPrivate
-{
-public:
- TQHostAddressPrivate( TQ_UINT32 a_=0 ) : a(a_), isIp4(TRUE)
- {
- }
- TQHostAddressPrivate( TQ_UINT8 *a_ );
- TQHostAddressPrivate(const TQ_IPV6ADDR &a_);
- ~TQHostAddressPrivate()
- {
- }
-
- TQHostAddressPrivate & operator=( const TQHostAddressPrivate &from )
- {
- a = from.a;
- isIp4 = from.isIp4;
- a6 = from.a6;
- return *this;
- }
-
-private:
- TQ_UINT32 a; // ip 4 address
- TQ_IPV6ADDR a6; // ip 6 address
- bool isIp4;
-
- friend class TQHostAddress;
-};
-
-TQHostAddressPrivate::TQHostAddressPrivate(TQ_UINT8 *a_) : a(0), isIp4(FALSE)
-{
- for ( int i=0; i<16; i++ ) {
- a6.c[i] = a_[i];
- }
-}
-
-TQHostAddressPrivate::TQHostAddressPrivate(const TQ_IPV6ADDR &a_) : a(0), isIp4(FALSE)
-{
- a6 = a_;
-}
-
-/*!
- \class TQHostAddress tqhostaddress.h
- \brief The TQHostAddress class provides an IP address.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class contains an IP address in a platform and protocol
- independent manner. It stores both IPv4 and IPv6 addresses in a
- way that you can easily access on any platform.
-
- TQHostAddress is normally used with the classes TQSocket,
- TQServerSocket and TQSocketDevice to set up a server or to connect
- to a host.
-
- Host addresses may be set with setAddress() and retrieved with
- ip4Addr() or toString().
-
- \sa TQSocket, TQServerSocket, TQSocketDevice
-*/
-
-
-/*!
- Creates a host address object with the IP address 0.0.0.0.
-*/
-TQHostAddress::TQHostAddress()
- : d( new TQHostAddressPrivate )
-{
-}
-
-
-/*!
- Creates a host address object for the IPv4 address \a ip4Addr.
-*/
-TQHostAddress::TQHostAddress( TQ_UINT32 ip4Addr )
- : d( new TQHostAddressPrivate( ip4Addr ) )
-{
-}
-
-
-/*!
- Creates a host address object with the specified IPv6 address.
-
- \a ip6Addr must be a 16 byte array in network byte order
- (high-order byte first).
-*/
-TQHostAddress::TQHostAddress( TQ_UINT8 *ip6Addr )
- : d( new TQHostAddressPrivate( ip6Addr ) )
-{
-}
-
-/*!
- Creates a host address object with the IPv6 address, \a ip6Addr.
-*/
-TQHostAddress::TQHostAddress(const TQ_IPV6ADDR &ip6Addr)
- : d(new TQHostAddressPrivate(ip6Addr))
-{
-}
-
-// ### DOC: Can only make this public if we specify precisely the
-// format of the address string.
-/*!
- \internal
-*/
-TQHostAddress::TQHostAddress(const TQString &address)
- : d( new TQHostAddressPrivate )
-{
- setAddress( address );
-}
-
-/*!
- Creates a copy of \a address.
-*/
-TQHostAddress::TQHostAddress( const TQHostAddress &address )
- : d( new TQHostAddressPrivate )
-{
- *d = *(address.d);
-}
-
-
-/*!
- Destroys the host address object.
-*/
-TQHostAddress::~TQHostAddress()
-{
- delete d;
-}
-
-
-/*!
- Assigns another host address object \a address to this object and
- returns a reference to this object.
-*/
-TQHostAddress & TQHostAddress::operator=( const TQHostAddress & address )
-{
- *d = *(address.d);
- return *this;
-}
-
-
-/*!
- Set the IPv4 address specified by \a ip4Addr.
-*/
-void TQHostAddress::setAddress( TQ_UINT32 ip4Addr )
-{
- delete d;
- d = new TQHostAddressPrivate( ip4Addr );
-}
-
-
-/*!
- \overload
-
- Set the IPv6 address specified by \a ip6Addr.
-
- \a ip6Addr must be a 16 byte array in network byte order
- (high-order byte first).
-*/
-void TQHostAddress::setAddress( TQ_UINT8 *ip6Addr )
-{
- delete d;
- d = new TQHostAddressPrivate( ip6Addr );
-}
-
-#ifndef TQT_NO_STRINGLIST
-static bool parseIp4(const TQString& address, TQ_UINT32 *addr)
-{
- TQStringList ipv4 = TQStringList::split(".", address, FALSE);
- if (ipv4.count() == 4) {
- int i = 0;
- bool ok = TRUE;
- while(ok && i < 4) {
- uint byteValue = ipv4[i].toUInt(&ok);
- if (byteValue > 255)
- ok = FALSE;
- if (ok)
- *addr = (*addr << 8) + byteValue;
- ++i;
- }
- if (ok)
- return TRUE;
- }
- return FALSE;
-}
-
-/*!
- \overload
-
- Sets the IPv4 or IPv6 address specified by the string
- representation \a address (e.g. "127.0.0.1"). Returns TRUE and
- sets the address if the address was successfully parsed; otherwise
- returns FALSE and leaves the address unchanged.
-*/
-bool TQHostAddress::setAddress(const TQString& address)
-{
- TQString a = address.simplifyWhiteSpace();
-
- // try ipv4
- TQ_UINT32 maybeIp4 = 0;
- if (parseIp4(address, &maybeIp4)) {
- setAddress(maybeIp4);
- return TRUE;
- }
-
- // try ipv6
- TQStringList ipv6 = TQStringList::split(":", a, TRUE);
- int count = (int)ipv6.count();
- if (count < 3)
- return FALSE; // there must be at least two ":"
- if (count > 8)
- return FALSE; // maximum of seven ":" exceeded
- TQ_UINT8 maybeIp6[16];
- int mc = 16;
- int fillCount = 9 - count;
- for (int i=count-1; i>=0; --i) {
- if ( mc <= 0 )
- return FALSE;
-
- if (ipv6[i].isEmpty()) {
- if (i==count-1) {
- // special case: ":" is last character
- if (!ipv6[i-1].isEmpty())
- return FALSE;
- maybeIp6[--mc] = 0;
- maybeIp6[--mc] = 0;
- } else if (i==0) {
- // special case: ":" is first character
- if (!ipv6[i+1].isEmpty())
- return FALSE;
- maybeIp6[--mc] = 0;
- maybeIp6[--mc] = 0;
- } else {
- for (int j=0; j<fillCount; ++j) {
- if ( mc <= 0 )
- return FALSE;
- maybeIp6[--mc] = 0;
- maybeIp6[--mc] = 0;
- }
- }
- } else {
- bool ok = FALSE;
- uint byteValue = ipv6[i].toUInt(&ok, 16);
- if (ok && byteValue <= 0xffff) {
- maybeIp6[--mc] = byteValue & 0xff;
- maybeIp6[--mc] = (byteValue >> 8) & 0xff;
- } else {
- if (i == count-1) {
- // parse the ipv4 part of a mixed type
- if (!parseIp4(ipv6[i], &maybeIp4))
- return FALSE;
- maybeIp6[--mc] = maybeIp4 & 0xff;
- maybeIp6[--mc] = (maybeIp4 >> 8) & 0xff;
- maybeIp6[--mc] = (maybeIp4 >> 16) & 0xff;
- maybeIp6[--mc] = (maybeIp4 >> 24) & 0xff;
- --fillCount;
- } else {
- return FALSE;
- }
- }
- }
- }
- if (mc == 0) {
- setAddress(maybeIp6);
- return TRUE;
- }
-
- return FALSE;
-}
-#endif
-
-/*!
- \obsolete
-
- Use isIPv4Address() instead.
-*/
-bool TQHostAddress::isIp4Addr() const
-{
- return isIPv4Address();
-}
-
-/*!
- Returns TRUE if the host address represents an IPv4 address;
- otherwise returns FALSE.
-*/
-bool TQHostAddress::isIPv4Address() const
-{
- return d->isIp4;
-}
-
-/*!
- \obsolete
-
- Use toIPv4Address() instead.
-*/
-TQ_UINT32 TQHostAddress::ip4Addr() const
-{
- return toIPv4Address();
-}
-
-/*!
- Returns the IPv4 address as a number.
-
- For example, if the address is 127.0.0.1, the returned value is
- 2130706433 (i.e. 0x7f000001).
-
- This value is only valid when isIp4Addr() returns TRUE.
-
- \sa toString()
-*/
-TQ_UINT32 TQHostAddress::toIPv4Address() const
-{
- return d->a;
-}
-
-/*!
- Returns TRUE if the host address represents an IPv6 address;
- otherwise returns FALSE.
-*/
-bool TQHostAddress::isIPv6Address() const
-{
- return !d->isIp4;
-}
-
-/*!
- Returns the IPv6 address as a TQ_IPV6ADDR structure. The structure
- consists of 16 unsigned characters.
-
- \code
- TQ_IPV6ADDR addr = hostAddr.ip6Addr();
- // addr.c[] contains 16 unsigned characters
-
- for (int i = 0; i < 16; ++i) {
- // process addr.c[i]
- }
- \endcode
-
- This value is only valid when isIPv6Address() returns TRUE.
-
- \sa toString()
-*/
-TQ_IPV6ADDR TQHostAddress::toIPv6Address() const
-{
- return d->a6;
-}
-
-#ifndef TQT_NO_SPRINTF
-/*!
- Returns the address as a string.
-
- For example, if the address is the IPv4 address 127.0.0.1, the
- returned string is "127.0.0.1".
-
- \sa ip4Addr()
-*/
-TQString TQHostAddress::toString() const
-{
- if ( d->isIp4 ) {
- TQ_UINT32 i = ip4Addr();
- TQString s;
- s.sprintf( "%d.%d.%d.%d", (i>>24) & 0xff, (i>>16) & 0xff,
- (i >> 8) & 0xff, i & 0xff );
- return s;
- } else {
- TQ_UINT16 ugle[8];
- for ( int i=0; i<8; i++ ) {
- ugle[i] = ( (TQ_UINT16)( d->a6.c[2*i] ) << 8 ) |
- ( (TQ_UINT16)( d->a6.c[2*i+1] ) );
- }
- TQString s;
- s.sprintf( "%X:%X:%X:%X:%X:%X:%X:%X",
- ugle[0], ugle[1], ugle[2], ugle[3],
- ugle[4], ugle[5], ugle[6], ugle[7] );
- return s;
- }
-}
-#endif
-
-
-/*!
- Returns TRUE if this host address is the same as \a other;
- otherwise returns FALSE.
-*/
-bool TQHostAddress::operator==( const TQHostAddress & other ) const
-{
- return d->a == other.d->a;
-}
-
-
-/*!
- Returns TRUE if this host address is null (INADDR_ANY or in6addr_any). The
- default constructor creates a null address, and that address isn't valid
- for any particular host or interface.
-*/
-bool TQHostAddress::isNull() const
-{
- if ( d->isIp4 )
- return d->a == 0;
- int i = 0;
- while( i < 16 ) {
- if ( d->a6.c[i++] != 0 )
- return FALSE;
- }
- return TRUE;
-}
-
-#endif //TQT_NO_NETWORK
-
-#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/network/tqhostaddress.h b/tqtinterface/qt4/src/network/tqhostaddress.h
deleted file mode 100644
index 692bfd8..0000000
--- a/tqtinterface/qt4/src/network/tqhostaddress.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Definition of TQHostAddress class.
-**
-** Created : 979899
-**
-** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQHOSTADDRESS_H
-#define TQHOSTADDRESS_H
-
-#include "tqtglobaldefines.h"
-
-#ifndef TQT_H
-#include "tqstring.h"
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_NETWORK
-#else
-#define TQM_EXPORT_NETWORK TQ_EXPORT
-#endif
-
-#ifdef USE_QT4
-
-#include <Qt/qhostaddress.h>
-
-#endif // USE_QT4
-
-#ifndef TQT_NO_NETWORK
-class TQHostAddressPrivate;
-
-typedef Q_IPV6ADDR TQ_IPV6ADDR;
-
-#ifdef USE_QT4
-
-class TQM_EXPORT_NETWORK TQHostAddress : public QHostAddress
-{
-public:
- TQHostAddress() : QHostAddress() {}
- TQHostAddress( TQ_UINT32 ip4Addr ) : QHostAddress( ip4Addr ) {}
- TQHostAddress( TQ_UINT8 *ip6Addr ) : QHostAddress( ip6Addr ) {}
- TQHostAddress(const TQ_IPV6ADDR &ip6Addr) : QHostAddress( ip6Addr ) {}
-#ifndef TQT_NO_STRINGLIST
- TQHostAddress(const QString &address) : QHostAddress( address ) {}
-#endif
- TQHostAddress( const QHostAddress &tqha ) : QHostAddress( tqha ) {}
-
- inline quint32 ip4Addr() const { return toIPv4Address(); }
- inline bool isIPv4Address() const { return protocol() == QAbstractSocket::IPv4Protocol || protocol() == QAbstractSocket::UnknownNetworkLayerProtocol; }
- inline bool isIp4Addr() const { return protocol() == QAbstractSocket::IPv4Protocol || protocol() == QAbstractSocket::UnknownNetworkLayerProtocol; }
- inline bool isIPv6Address() const { return protocol() == QAbstractSocket::IPv6Protocol; }
-};
-
-#else // USE_QT4
-
-class TQM_EXPORT_NETWORK TQHostAddress
-{
-public:
- TQHostAddress();
- TQHostAddress( TQ_UINT32 ip4Addr );
- TQHostAddress( TQ_UINT8 *ip6Addr );
- TQHostAddress(const TQ_IPV6ADDR &ip6Addr);
-#ifndef TQT_NO_STRINGLIST
- TQHostAddress(const TQString &address);
-#endif
- TQHostAddress( const TQHostAddress & );
- virtual ~TQHostAddress();
-
- TQHostAddress & operator=( const TQHostAddress & );
-
- void setAddress( TQ_UINT32 ip4Addr );
- void setAddress( TQ_UINT8 *ip6Addr );
-#ifndef TQT_NO_STRINGLIST
- bool setAddress( const TQString& address );
-#endif
- bool isIp4Addr() const; // obsolete
- TQ_UINT32 ip4Addr() const; // obsolete
-
- bool isIPv4Address() const;
- TQ_UINT32 toIPv4Address() const;
- bool isIPv6Address() const;
- TQ_IPV6ADDR toIPv6Address() const;
-
-#ifndef TQT_NO_SPRINTF
- TQString toString() const;
-#endif
-
- bool operator==( const TQHostAddress & ) const;
- bool isNull() const;
-
-private:
- TQHostAddressPrivate* d;
-};
-
-#endif // USE_QT4
-
-#endif //TQT_NO_NETWORK
-#endif
diff --git a/tqtinterface/qt4/src/network/tqhttp.cpp b/tqtinterface/qt4/src/network/tqhttp.cpp
deleted file mode 100644
index 6b1f061..0000000
--- a/tqtinterface/qt4/src/network/tqhttp.cpp
+++ /dev/null
@@ -1,2384 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQHttp and related classes.
-**
-** Created : 970521
-**
-** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqhttp.h"
-
-#ifndef TQT_NO_NETWORKPROTOCOL_HTTP
-
-#include "tqsocket.h"
-#include "tqtextstream.h"
-#include "tqmap.h"
-#include "tqstring.h"
-#include "tqstringlist.h"
-#include "tqcstring.h"
-#include "tqbuffer.h"
-#include "tqurloperator.h"
-#include "tqtimer.h"
-#include "private/tqinternal_p.h"
-
-//#define TQHTTP_DEBUG
-
-class TQHttpPrivate
-{
-public:
- TQHttpPrivate() :
- state( TQHttp::Unconnected ),
- error( TQHttp::NoError ),
- hostname( TQString::null ),
- port( 0 ),
- toDevice( 0 ),
- postDevice( 0 ),
- bytesDone( 0 ),
- chunkedSize( -1 ),
- idleTimer( 0 )
- {
- pending.setAutoDelete( TRUE );
- }
-
- TQSocket socket;
- TQPtrList<TQHttpRequest> pending;
-
- TQHttp::State state;
- TQHttp::Error error;
- TQString errorString;
-
- TQString hostname;
- TQ_UINT16 port;
-
- TQByteArray buffer;
- TQIODevice* toDevice;
- TQIODevice* postDevice;
-
- uint bytesDone;
- uint bytesTotal;
- TQ_LONG chunkedSize;
-
- TQHttpRequestHeader header;
-
- bool readHeader;
- TQString headerStr;
- TQHttpResponseHeader response;
-
- int idleTimer;
-
- TQMembuf rba;
-};
-
-class TQHttpRequest
-{
-public:
- TQHttpRequest()
- {
- id = ++idCounter;
- }
- virtual ~TQHttpRequest()
- { }
-
- virtual void start( TQHttp * ) = 0;
- virtual bool hasRequestHeader();
- virtual TQHttpRequestHeader requestHeader();
-
- virtual TQIODevice* sourceDevice() = 0;
- virtual TQIODevice* destinationDevice() = 0;
-
- int id;
-
-private:
- static int idCounter;
-};
-
-int TQHttpRequest::idCounter = 0;
-
-bool TQHttpRequest::hasRequestHeader()
-{
- return FALSE;
-}
-
-TQHttpRequestHeader TQHttpRequest::requestHeader()
-{
- return TQHttpRequestHeader();
-}
-
-/****************************************************
- *
- * TQHttpNormalRequest
- *
- ****************************************************/
-
-class TQHttpNormalRequest : public TQHttpRequest
-{
-public:
- TQHttpNormalRequest( const TQHttpRequestHeader &h, TQIODevice *d, TQIODevice *t ) :
- header(h), to(t)
- {
- is_ba = FALSE;
- data.dev = d;
- }
-
- TQHttpNormalRequest( const TQHttpRequestHeader &h, TQByteArray *d, TQIODevice *t ) :
- header(h), to(t)
- {
- is_ba = TRUE;
- data.ba = d;
- }
-
- ~TQHttpNormalRequest()
- {
- if ( is_ba )
- delete data.ba;
- }
-
- void start( TQHttp * );
- bool hasRequestHeader();
- TQHttpRequestHeader requestHeader();
-
- TQIODevice* sourceDevice();
- TQIODevice* destinationDevice();
-
-protected:
- TQHttpRequestHeader header;
-
-private:
- union {
- TQByteArray *ba;
- TQIODevice *dev;
- } data;
- bool is_ba;
- TQIODevice *to;
-};
-
-void TQHttpNormalRequest::start( TQHttp *http )
-{
- http->d->header = header;
-
- if ( is_ba ) {
- http->d->buffer = *data.ba;
- if ( http->d->buffer.size() > 0 )
- http->d->header.setContentLength( http->d->buffer.size() );
-
- http->d->postDevice = 0;
- } else {
- http->d->buffer = TQByteArray();
-
- if ( data.dev && ( data.dev->isOpen() || data.dev->open(IO_ReadOnly) ) ) {
- http->d->postDevice = data.dev;
- if ( http->d->postDevice->size() > 0 )
- http->d->header.setContentLength( http->d->postDevice->size() );
- } else {
- http->d->postDevice = 0;
- }
- }
-
- if ( to && ( to->isOpen() || to->open(IO_WriteOnly) ) )
- http->d->toDevice = to;
- else
- http->d->toDevice = 0;
-
- http->sendRequest();
-}
-
-bool TQHttpNormalRequest::hasRequestHeader()
-{
- return TRUE;
-}
-
-TQHttpRequestHeader TQHttpNormalRequest::requestHeader()
-{
- return header;
-}
-
-TQIODevice* TQHttpNormalRequest::sourceDevice()
-{
- if ( is_ba )
- return 0;
- return data.dev;
-}
-
-TQIODevice* TQHttpNormalRequest::destinationDevice()
-{
- return to;
-}
-
-/****************************************************
- *
- * TQHttpPGHRequest
- * (like a TQHttpNormalRequest, but for the convenience
- * functions put(), get() and head() -- i.e. set the
- * host header field correctly before sending the
- * request)
- *
- ****************************************************/
-
-class TQHttpPGHRequest : public TQHttpNormalRequest
-{
-public:
- TQHttpPGHRequest( const TQHttpRequestHeader &h, TQIODevice *d, TQIODevice *t ) :
- TQHttpNormalRequest( h, d, t )
- { }
-
- TQHttpPGHRequest( const TQHttpRequestHeader &h, TQByteArray *d, TQIODevice *t ) :
- TQHttpNormalRequest( h, d, t )
- { }
-
- ~TQHttpPGHRequest()
- { }
-
- void start( TQHttp * );
-};
-
-void TQHttpPGHRequest::start( TQHttp *http )
-{
- header.setValue( "Host", http->d->hostname );
- TQHttpNormalRequest::start( http );
-}
-
-/****************************************************
- *
- * TQHttpSetHostRequest
- *
- ****************************************************/
-
-class TQHttpSetHostRequest : public TQHttpRequest
-{
-public:
- TQHttpSetHostRequest( const TQString &h, TQ_UINT16 p ) :
- hostname(h), port(p)
- { }
-
- void start( TQHttp * );
-
- TQIODevice* sourceDevice()
- { return 0; }
- TQIODevice* destinationDevice()
- { return 0; }
-
-private:
- TQString hostname;
- TQ_UINT16 port;
-};
-
-void TQHttpSetHostRequest::start( TQHttp *http )
-{
- http->d->hostname = hostname;
- http->d->port = port;
- http->finishedWithSuccess();
-}
-
-/****************************************************
- *
- * TQHttpCloseRequest
- *
- ****************************************************/
-
-class TQHttpCloseRequest : public TQHttpRequest
-{
-public:
- TQHttpCloseRequest()
- { }
- void start( TQHttp * );
-
- TQIODevice* sourceDevice()
- { return 0; }
- TQIODevice* destinationDevice()
- { return 0; }
-};
-
-void TQHttpCloseRequest::start( TQHttp *http )
-{
- http->close();
-}
-
-/****************************************************
- *
- * TQHttpHeader
- *
- ****************************************************/
-
-/*!
- \class TQHttpHeader tqhttp.h
- \brief The TQHttpHeader class contains header information for HTTP.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- In most cases you should use the more specialized derivatives of
- this class, TQHttpResponseHeader and TQHttpRequestHeader, rather
- than directly using TQHttpHeader.
-
- TQHttpHeader provides the HTTP header fields. A HTTP header field
- consists of a name followed by a colon, a single space, and the
- field value. (See RFC 1945.) Field names are case-insensitive. A
- typical header field looks like this:
- \code
- content-type: text/html
- \endcode
-
- In the API the header field name is called the "key" and the
- content is called the "value". You can get and set a header
- field's value by using its key with value() and setValue(), e.g.
- \code
- header.setValue( "content-type", "text/html" );
- TQString contentType = header.value( "content-type" );
- \endcode
-
- Some fields are so common that getters and setters are provided
- for them as a convenient alternative to using \l value() and
- \l setValue(), e.g. contentLength() and contentType(),
- setContentLength() and setContentType().
-
- Each header key has a \e single value associated with it. If you
- set the value for a key which already exists the previous value
- will be discarded.
-
- \sa TQHttpRequestHeader TQHttpResponseHeader
-*/
-
-/*!
- \fn int TQHttpHeader::majorVersion() const
-
- Returns the major protocol-version of the HTTP header.
-*/
-
-/*!
- \fn int TQHttpHeader::minorVersion() const
-
- Returns the minor protocol-version of the HTTP header.
-*/
-
-/*!
- Constructs an empty HTTP header.
-*/
-TQHttpHeader::TQHttpHeader()
- : valid( TRUE )
-{
-}
-
-/*!
- Constructs a copy of \a header.
-*/
-TQHttpHeader::TQHttpHeader( const TQHttpHeader& header )
- : valid( header.valid )
-{
- values = header.values;
-}
-
-/*!
- Constructs a HTTP header for \a str.
-
- This constructor parses the string \a str for header fields and
- adds this information. The \a str should consist of one or more
- "\r\n" delimited lines; each of these lines should have the format
- key, colon, space, value.
-*/
-TQHttpHeader::TQHttpHeader( const TQString& str )
- : valid( TRUE )
-{
- parse( str );
-}
-
-/*!
- Destructor.
-*/
-TQHttpHeader::~TQHttpHeader()
-{
-}
-
-/*!
- Assigns \a h and returns a reference to this http header.
-*/
-TQHttpHeader& TQHttpHeader::operator=( const TQHttpHeader& h )
-{
- values = h.values;
- valid = h.valid;
- return *this;
-}
-
-/*!
- Returns TRUE if the HTTP header is valid; otherwise returns FALSE.
-
- A TQHttpHeader is invalid if it was created by parsing a malformed string.
-*/
-bool TQHttpHeader::isValid() const
-{
- return valid;
-}
-
-/*! \internal
- Parses the HTTP header string \a str for header fields and adds
- the keys/values it finds. If the string is not parsed successfully
- the TQHttpHeader becomes \link isValid() invalid\endlink.
-
- Returns TRUE if \a str was successfully parsed; otherwise returns FALSE.
-
- \sa toString()
-*/
-bool TQHttpHeader::parse( const TQString& str )
-{
- TQStringList lst;
- int pos = str.find( '\n' );
- if ( pos > 0 && str.at( pos - 1 ) == '\r' )
- lst = TQStringList::split( "\r\n", str.stripWhiteSpace(), FALSE );
- else
- lst = TQStringList::split( "\n", str.stripWhiteSpace(), FALSE );
-
- if ( lst.isEmpty() )
- return TRUE;
-
- TQStringList lines;
- TQStringList::Iterator it = lst.begin();
- for( ; it != lst.end(); ++it ) {
- if ( !(*it).isEmpty() ) {
- if ( (*it)[0].isSpace() ) {
- if ( !lines.isEmpty() ) {
- lines.last() += " ";
- lines.last() += (*it).stripWhiteSpace();
- }
- } else {
- lines.append( (*it) );
- }
- }
- }
-
- int number = 0;
- it = lines.begin();
- for( ; it != lines.end(); ++it ) {
- if ( !parseLine( *it, number++ ) ) {
- valid = FALSE;
- return FALSE;
- }
- }
- return TRUE;
-}
-
-/*! \internal
-*/
-void TQHttpHeader::setValid( bool v )
-{
- valid = v;
-}
-
-/*!
- Returns the value for the entry with the given \a key. If no entry
- has this \a key, an empty string is returned.
-
- \sa setValue() removeValue() hasKey() keys()
-*/
-TQString TQHttpHeader::value( const TQString& key ) const
-{
- return values[ key.lower() ];
-}
-
-/*!
- Returns a list of the keys in the HTTP header.
-
- \sa hasKey()
-*/
-TQStringList TQHttpHeader::keys() const
-{
- return values.keys();
-}
-
-/*!
- Returns TRUE if the HTTP header has an entry with the given \a
- key; otherwise returns FALSE.
-
- \sa value() setValue() keys()
-*/
-bool TQHttpHeader::hasKey( const TQString& key ) const
-{
- return values.contains( key.lower() );
-}
-
-/*!
- Sets the value of the entry with the \a key to \a value.
-
- If no entry with \a key exists, a new entry with the given \a key
- and \a value is created. If an entry with the \a key already
- exists, its value is discarded and replaced with the given \a
- value.
-
- \sa value() hasKey() removeValue()
-*/
-void TQHttpHeader::setValue( const TQString& key, const TQString& value )
-{
- values[ key.lower() ] = value;
-}
-
-/*!
- Removes the entry with the key \a key from the HTTP header.
-
- \sa value() setValue()
-*/
-void TQHttpHeader::removeValue( const TQString& key )
-{
- values.remove( key.lower() );
-}
-
-/*! \internal
- Parses the single HTTP header line \a line which has the format
- key, colon, space, value, and adds key/value to the headers. The
- linenumber is \a number. Returns TRUE if the line was successfully
- parsed and the key/value added; otherwise returns FALSE.
-
- \sa parse()
-*/
-bool TQHttpHeader::parseLine( const TQString& line, int )
-{
- int i = line.find( ":" );
- if ( i == -1 )
- return FALSE;
-
- values.insert( TQT_TQSTRING(line.left( i )).stripWhiteSpace().lower(), TQT_TQSTRING(line.mid( i + 1 )).stripWhiteSpace() );
-
- return TRUE;
-}
-
-/*!
- Returns a string representation of the HTTP header.
-
- The string is suitable for use by the constructor that takes a
- TQString. It consists of lines with the format: key, colon, space,
- value, "\r\n".
-*/
-TQString TQHttpHeader::toString() const
-{
- if ( !isValid() )
- return "";
-
- TQString ret = "";
-
- TQMap<TQString,TQString>::ConstIterator it = values.begin();
- for( ; it != values.end(); ++it )
- ret += it.key() + ": " + it.data() + "\r\n";
-
- return ret;
-}
-
-/*!
- Returns TRUE if the header has an entry for the special HTTP
- header field \c content-length; otherwise returns FALSE.
-
- \sa contentLength() setContentLength()
-*/
-bool TQHttpHeader::hasContentLength() const
-{
- return hasKey( "content-length" );
-}
-
-/*!
- Returns the value of the special HTTP header field \c
- content-length.
-
- \sa setContentLength() hasContentLength()
-*/
-uint TQHttpHeader::contentLength() const
-{
- return values[ "content-length" ].toUInt();
-}
-
-/*!
- Sets the value of the special HTTP header field \c content-length
- to \a len.
-
- \sa contentLength() hasContentLength()
-*/
-void TQHttpHeader::setContentLength( int len )
-{
- values[ "content-length" ] = TQString::number( len );
-}
-
-/*!
- Returns TRUE if the header has an entry for the the special HTTP
- header field \c content-type; otherwise returns FALSE.
-
- \sa contentType() setContentType()
-*/
-bool TQHttpHeader::hasContentType() const
-{
- return hasKey( "content-type" );
-}
-
-/*!
- Returns the value of the special HTTP header field \c content-type.
-
- \sa setContentType() hasContentType()
-*/
-TQString TQHttpHeader::contentType() const
-{
- TQString type = values[ "content-type" ];
- if ( type.isEmpty() )
- return TQString::null;
-
- int pos = type.find( ";" );
- if ( pos == -1 )
- return type;
-
- return TQT_TQSTRING(type.left( pos )).stripWhiteSpace();
-}
-
-/*!
- Sets the value of the special HTTP header field \c content-type to
- \a type.
-
- \sa contentType() hasContentType()
-*/
-void TQHttpHeader::setContentType( const TQString& type )
-{
- values[ "content-type" ] = type;
-}
-
-/****************************************************
- *
- * TQHttpResponseHeader
- *
- ****************************************************/
-
-/*!
- \class TQHttpResponseHeader tqhttp.h
- \brief The TQHttpResponseHeader class contains response header information for HTTP.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class is used by the TQHttp class to report the header
- information that the client received from the server.
-
- HTTP responses have a status code that indicates the status of the
- response. This code is a 3-digit integer result code (for details
- see to RFC 1945). In addition to the status code, you can also
- specify a human-readable text that describes the reason for the
- code ("reason phrase"). This class allows you to get the status
- code and the reason phrase.
-
- \sa TQHttpRequestHeader TQHttp
-*/
-
-/*!
- Constructs an empty HTTP response header.
-*/
-TQHttpResponseHeader::TQHttpResponseHeader()
-{
- setValid( FALSE );
-}
-
-/*!
- Constructs a HTTP response header with the status code \a code,
- the reason phrase \a text and the protocol-version \a majorVer and
- \a minorVer.
-*/
-TQHttpResponseHeader::TQHttpResponseHeader( int code, const TQString& text, int majorVer, int minorVer )
- : TQHttpHeader(), statCode( code ), reasonPhr( text ), majVer( majorVer ), minVer( minorVer )
-{
-}
-
-/*!
- Constructs a copy of \a header.
-*/
-TQHttpResponseHeader::TQHttpResponseHeader( const TQHttpResponseHeader& header )
- : TQHttpHeader( header ), statCode( header.statCode ), reasonPhr( header.reasonPhr ), majVer( header.majVer ), minVer( header.minVer )
-{
-}
-
-/*!
- Constructs a HTTP response header from the string \a str. The
- string is parsed and the information is set. The \a str should
- consist of one or more "\r\n" delimited lines; the first line should be the
- status-line (format: HTTP-version, space, status-code, space,
- reason-phrase); each of remaining lines should have the format key, colon,
- space, value.
-*/
-TQHttpResponseHeader::TQHttpResponseHeader( const TQString& str )
- : TQHttpHeader()
-{
- parse( str );
-}
-
-/*!
- Sets the status code to \a code, the reason phrase to \a text and
- the protocol-version to \a majorVer and \a minorVer.
-
- \sa statusCode() reasonPhrase() majorVersion() minorVersion()
-*/
-void TQHttpResponseHeader::setqStatusLine( int code, const TQString& text, int majorVer, int minorVer )
-{
- setValid( TRUE );
- statCode = code;
- reasonPhr = text;
- majVer = majorVer;
- minVer = minorVer;
-}
-
-/*!
- Returns the status code of the HTTP response header.
-
- \sa reasonPhrase() majorVersion() minorVersion()
-*/
-int TQHttpResponseHeader::statusCode() const
-{
- return statCode;
-}
-
-/*!
- Returns the reason phrase of the HTTP response header.
-
- \sa statusCode() majorVersion() minorVersion()
-*/
-TQString TQHttpResponseHeader::reasonPhrase() const
-{
- return reasonPhr;
-}
-
-/*!
- Returns the major protocol-version of the HTTP response header.
-
- \sa minorVersion() statusCode() reasonPhrase()
-*/
-int TQHttpResponseHeader::majorVersion() const
-{
- return majVer;
-}
-
-/*!
- Returns the minor protocol-version of the HTTP response header.
-
- \sa majorVersion() statusCode() reasonPhrase()
-*/
-int TQHttpResponseHeader::minorVersion() const
-{
- return minVer;
-}
-
-/*! \reimp
-*/
-bool TQHttpResponseHeader::parseLine( const TQString& line, int number )
-{
- if ( number != 0 )
- return TQHttpHeader::parseLine( line, number );
-
- TQString l = line.simplifyWhiteSpace();
- if ( l.length() < 10 )
- return FALSE;
-
- if ( l.left( 5 ) == "HTTP/" && l[5].isDigit() && l[6] == '.' &&
- l[7].isDigit() && l[8] == ' ' && l[9].isDigit() ) {
- majVer = l[5].latin1() - '0';
- minVer = l[7].latin1() - '0';
-
- int pos = l.find( ' ', 9 );
- if ( pos != -1 ) {
- reasonPhr = l.mid( pos + 1 );
- statCode = l.mid( 9, pos - 9 ).toInt();
- } else {
- statCode = l.mid( 9 ).toInt();
- reasonPhr = TQString::null;
- }
- } else {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*! \reimp
-*/
-TQString TQHttpResponseHeader::toString() const
-{
- TQString ret( "HTTP/%1.%2 %3 %4\r\n%5\r\n" );
- return ret.arg( majVer ).arg ( minVer ).arg( statCode ).arg( reasonPhr ).arg( TQHttpHeader::toString() );
-}
-
-/****************************************************
- *
- * TQHttpRequestHeader
- *
- ****************************************************/
-
-/*!
- \class TQHttpRequestHeader tqhttp.h
- \brief The TQHttpRequestHeader class contains request header information for
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
- HTTP.
-\if defined(commercial_edition)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class is used in the TQHttp class to report the header
- information if the client requests something from the server.
-
- HTTP requests have a method which describes the request's action.
- The most common requests are "GET" and "POST". In addition to the
- request method the header also includes a request-URI to specify
- the location for the method to use.
-
- The method, request-URI and protocol-version can be set using a
- constructor or later using setRequest(). The values can be
- obtained using method(), path(), majorVersion() and
- minorVersion().
-
- This class is a TQHttpHeader subclass so that class's functions,
- e.g. \link TQHttpHeader::setValue() setValue()\endlink, \link
- TQHttpHeader::value() value()\endlink, etc. are also available.
-
- \sa TQHttpResponseHeader TQHttp
-
- \important value() setValue()
-*/
-
-/*!
- Constructs an empty HTTP request header.
-*/
-TQHttpRequestHeader::TQHttpRequestHeader()
- : TQHttpHeader()
-{
- setValid( FALSE );
-}
-
-/*!
- Constructs a HTTP request header for the method \a method, the
- request-URI \a path and the protocol-version \a majorVer and \a minorVer.
-*/
-TQHttpRequestHeader::TQHttpRequestHeader( const TQString& method, const TQString& path, int majorVer, int minorVer )
- : TQHttpHeader(), m( method ), p( path ), majVer( majorVer ), minVer( minorVer )
-{
-}
-
-/*!
- Constructs a copy of \a header.
-*/
-TQHttpRequestHeader::TQHttpRequestHeader( const TQHttpRequestHeader& header )
- : TQHttpHeader( header ), m( header.m ), p( header.p ), majVer( header.majVer ), minVer( header.minVer )
-{
-}
-
-/*!
- Constructs a HTTP request header from the string \a str. The \a
- str should consist of one or more "\r\n" delimited lines; the first line
- should be the request-line (format: method, space, request-URI, space
- HTTP-version); each of the remaining lines should have the format key,
- colon, space, value.
-*/
-TQHttpRequestHeader::TQHttpRequestHeader( const TQString& str )
- : TQHttpHeader()
-{
- parse( str );
-}
-
-/*!
- This function sets the request method to \a method, the
- request-URI to \a path and the protocol-version to \a majorVer and
- \a minorVer.
-
- \sa method() path() majorVersion() minorVersion()
-*/
-void TQHttpRequestHeader::setRequest( const TQString& method, const TQString& path, int majorVer, int minorVer )
-{
- setValid( TRUE );
- m = method;
- p = path;
- majVer = majorVer;
- minVer = minorVer;
-}
-
-/*!
- Returns the method of the HTTP request header.
-
- \sa path() majorVersion() minorVersion() setRequest()
-*/
-TQString TQHttpRequestHeader::method() const
-{
- return m;
-}
-
-/*!
- Returns the request-URI of the HTTP request header.
-
- \sa method() majorVersion() minorVersion() setRequest()
-*/
-TQString TQHttpRequestHeader::path() const
-{
- return p;
-}
-
-/*!
- Returns the major protocol-version of the HTTP request header.
-
- \sa minorVersion() method() path() setRequest()
-*/
-int TQHttpRequestHeader::majorVersion() const
-{
- return majVer;
-}
-
-/*!
- Returns the minor protocol-version of the HTTP request header.
-
- \sa majorVersion() method() path() setRequest()
-*/
-int TQHttpRequestHeader::minorVersion() const
-{
- return minVer;
-}
-
-/*! \reimp
-*/
-bool TQHttpRequestHeader::parseLine( const TQString& line, int number )
-{
- if ( number != 0 )
- return TQHttpHeader::parseLine( line, number );
-
- TQStringList lst = TQStringList::split( " ", line.simplifyWhiteSpace() );
- if ( lst.count() > 0 ) {
- m = lst[0];
- if ( lst.count() > 1 ) {
- p = lst[1];
- if ( lst.count() > 2 ) {
- TQString v = lst[2];
- if ( v.length() >= 8 && v.left( 5 ) == "HTTP/" &&
- v[5].isDigit() && v[6] == '.' && v[7].isDigit() ) {
- majVer = v[5].latin1() - '0';
- minVer = v[7].latin1() - '0';
- return TRUE;
- }
- }
- }
- }
-
- return FALSE;
-}
-
-/*! \reimp
-*/
-TQString TQHttpRequestHeader::toString() const
-{
- TQString first( "%1 %2");
- TQString last(" HTTP/%3.%4\r\n%5\r\n" );
- return first.arg( m ).arg( p ) +
- last.arg( majVer ).arg( minVer ).arg( TQHttpHeader::toString());
-}
-
-
-/****************************************************
- *
- * TQHttp
- *
- ****************************************************/
-/*!
- \class TQHttp tqhttp.h
- \brief The TQHttp class provides an implementation of the HTTP protocol.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class provides two different interfaces: one is the
- TQNetworkProtocol interface that allows you to use HTTP through the
- TQUrlOperator abstraction. The other is a direct interface to HTTP
- that allows you to have more control over the requests and that
- allows you to access the response header fields.
-
- Don't mix the two interfaces, since the behavior is not
- well-defined.
-
- If you want to use TQHttp with the TQNetworkProtocol interface, you
- do not use it directly, but rather through a TQUrlOperator, for
- example:
-
- \code
- TQUrlOperator op( "http://www.trolltech.com" );
- op.get( "index.html" );
- \endcode
-
- This code will only work if the TQHttp class is registered; to
- register the class, you must call qInitNetworkProtocols() before
- using a TQUrlOperator with HTTP.
-
- The TQNetworkProtocol interface for HTTP only supports the
- operations operationGet() and operationPut(), i.e.
- TQUrlOperator::get() and TQUrlOperator::put(), if you use it with a
- TQUrlOperator.
-
- The rest of this descrption describes the direct interface to
- HTTP.
-
- The class works asynchronously, so there are no blocking
- functions. If an operation cannot be executed immediately, the
- function will still return straight away and the operation will be
- scheduled for later execution. The results of scheduled operations
- are reported via Q_SIGNALS. This approach depends on the event loop
- being in operation.
-
- The operations that can be scheduled (they are called "requests"
- in the rest of the documentation) are the following: setHost(),
- get(), post(), head() and request().
-
- All of these requests return a unique identifier that allows you
- to keep track of the request that is currently executed. When the
- execution of a request starts, the requestStarted() signal with
- the identifier is emitted and when the request is finished, the
- requestFinished() signal is emitted with the identifier and a bool
- that indicates if the request finished with an error.
-
- To make an HTTP request you must set up suitable HTTP headers. The
- following example demonstrates, how to request the main HTML page
- from the Trolltech home page (i.e. the URL
- http://www.trolltech.com/index.html):
-
- \code
- TQHttpRequestHeader header( "GET", "/index.html" );
- header.setValue( "Host", "www.trolltech.com" );
- http->setHost( "www.trolltech.com" );
- http->request( header );
- \endcode
-
- For the common HTTP requests \c GET, \c POST and \c HEAD, TQHttp
- provides the convenience functions get(), post() and head(). They
- already use a reasonable header and if you don't have to set
- special header fields, they are easier to use. The above example
- can also be written as:
-
- \code
- http->setHost( "www.trolltech.com" ); // id == 1
- http->get( "/index.html" ); // id == 2
- \endcode
-
- For this example the following sequence of Q_SIGNALS is emitted
- (with small variations, depending on network traffic, etc.):
-
- \code
- requestStarted( 1 )
- requestFinished( 1, FALSE )
-
- requestStarted( 2 )
- stateChanged( Connecting )
- stateChanged( Sending )
- dataSendProgress( 77, 77 )
- stateChanged( Reading )
- responseHeaderReceived( responseheader )
- dataReadProgress( 5388, 0 )
- readyRead( responseheader )
- dataReadProgress( 18300, 0 )
- readyRead( responseheader )
- stateChanged( Connected )
- requestFinished( 2, FALSE )
-
- done( FALSE )
-
- stateChanged( Closing )
- stateChanged( Unconnected )
- \endcode
-
- The dataSendProgress() and dataReadProgress() Q_SIGNALS in the above
- example are useful if you want to show a \link TQProgressBar
- progressbar\endlink to inform the user about the progress of the
- download. The second argument is the total size of data. In
- certain cases it is not possible to know the total amount in
- advance, in which case the second argument is 0. (If you connect
- to a TQProgressBar a total of 0 results in a busy indicator.)
-
- When the response header is read, it is reported with the
- responseHeaderReceived() signal.
-
- The readyRead() signal tells you that there is data ready to be
- read. The amount of data can then be queried with the
- bytesAvailable() function and it can be read with the readBlock()
- or readAll() functions.
-
- If an error occurs during the execution of one of the commands in
- a sequence of commands, all the pending commands (i.e. scheduled,
- but not yet executed commands) are cleared and no Q_SIGNALS are
- emitted for them.
-
- For example, if you have the following sequence of reqeusts
-
- \code
- http->setHost( "www.foo.bar" ); // id == 1
- http->get( "/index.html" ); // id == 2
- http->post( "register.html", data ); // id == 3
- \endcode
-
- and the get() request fails because the host lookup fails, then
- the post() request is never executed and the Q_SIGNALS would look
- like this:
-
- \code
- requestStarted( 1 )
- requestFinished( 1, FALSE )
-
- requestStarted( 2 )
- stateChanged( HostLookup )
- requestFinished( 2, TRUE )
-
- done( TRUE )
-
- stateChanged( Unconnected )
- \endcode
-
- You can then get details about the error with the error() and
- errorString() functions. Note that only unexpected behaviour, like
- network failure is considered as an error. If the server response
- contains an error status, like a 404 response, this is reported as
- a normal response case. So you should always check the \link
- TQHttpResponseHeader::statusCode() status code \endlink of the
- response header.
-
- The functions currentId() and currentRequest() provide more
- information about the currently executing request.
-
- The functions hasPendingRequests() and clearPendingRequests()
- allow you to query and clear the list of pending requests.
-
- \sa \link network.html TQt Network Documentation \endlink TQNetworkProtocol, TQUrlOperator TQFtp
-*/
-
-/*!
- Constructs a TQHttp object.
-*/
-TQHttp::TQHttp()
-{
- init();
-}
-
-/*!
- Constructs a TQHttp object. The parameters \a parent and \a name
- are passed on to the TQObject constructor.
-*/
-TQHttp::TQHttp( TQObject* parent, const char* name )
-{
- if ( parent )
- parent->insertChild( this );
- setName( name );
- init();
-}
-
-/*!
- Constructs a TQHttp object. Subsequent requests are done by
- connecting to the server \a hostname on port \a port. The
- parameters \a parent and \a name are passed on to the TQObject
- constructor.
-
- \sa setHost()
-*/
-TQHttp::TQHttp( const TQString &hostname, TQ_UINT16 port, TQObject* parent, const char* name )
-{
- if ( parent )
- parent->insertChild( this );
- setName( name );
- init();
-
- d->hostname = hostname;
- d->port = port;
-}
-
-void TQHttp::init()
-{
- bytesRead = 0;
- d = new TQHttpPrivate;
- d->errorString = tr( "Unknown error" );
-
- connect( &d->socket, TQT_SIGNAL( connected() ),
- this, TQT_SLOT( slotConnected() ) );
- connect( &d->socket, TQT_SIGNAL( connectionClosed() ),
- this, TQT_SLOT( slotClosed() ) );
- connect( &d->socket, TQT_SIGNAL( delayedCloseFinished() ),
- this, TQT_SLOT( slotClosed() ) );
- connect( &d->socket, TQT_SIGNAL( readyRead() ),
- this, TQT_SLOT( slotReadyRead() ) );
- connect( &d->socket, TQT_SIGNAL( error(int) ),
- this, TQT_SLOT( slotError(int) ) );
- connect( &d->socket, TQT_SIGNAL( bytesWritten(int) ),
- this, TQT_SLOT( slotBytesWritten(int) ) );
-
- d->idleTimer = startTimer( 0 );
-}
-
-/*!
- Destroys the TQHttp object. If there is an open connection, it is
- closed.
-*/
-TQHttp::~TQHttp()
-{
- abort();
- delete d;
-}
-
-/*!
- \enum TQHttp::State
-
- This enum is used to specify the state the client is in:
-
- \value Unconnected There is no connection to the host.
- \value HostLookup A host name lookup is in progress.
- \value Connecting An attempt to connect to the host is in progress.
- \value Sending The client is sending its request to the server.
- \value Reading The client's request has been sent and the client
- is reading the server's response.
- \value Connected The connection to the host is open, but the client is
- neither sending a request, nor waiting for a response.
- \value Closing The connection is closing down, but is not yet
- closed. (The state will be \c Unconnected when the connection is
- closed.)
-
- \sa stateChanged() state()
-*/
-
-/*! \enum TQHttp::Error
-
- This enum identifies the error that occurred.
-
- \value NoError No error occurred.
- \value HostNotFound The host name lookup failed.
- \value ConnectionRefused The server refused the connection.
- \value UnexpectedClose The server closed the connection unexpectedly.
- \value InvalidResponseHeader The server sent an invalid response header.
- \value WrongContentLength The client could not read the content correctly
- because an error with respect to the content length occurred.
- \value Aborted The request was aborted with abort().
- \value UnknownError An error other than those specified above
- occurred.
-
- \sa error()
-*/
-
-/*!
- \fn void TQHttp::stateChanged( int state )
-
- This signal is emitted when the state of the TQHttp object changes.
- The argument \a state is the new state of the connection; it is
- one of the \l State values.
-
- This usually happens when a request is started, but it can also
- happen when the server closes the connection or when a call to
- closeConnection() succeeded.
-
- \sa get() post() head() request() closeConnection() state() State
-*/
-
-/*!
- \fn void TQHttp::responseHeaderReceived( const TQHttpResponseHeader& resp )
-
- This signal is emitted when the HTTP header of a server response
- is available. The header is passed in \a resp.
-
- \sa get() post() head() request() readyRead()
-*/
-
-/*!
- \fn void TQHttp::readyRead( const TQHttpResponseHeader& resp )
-
- This signal is emitted when there is new response data to read.
-
- If you specified a tqdevice in the request where the data should be
- written to, then this signal is \e not emitted; instead the data
- is written directly to the tqdevice.
-
- The response header is passed in \a resp.
-
- You can read the data with the readAll() or readBlock() functions
-
- This signal is useful if you want to process the data in chunks as
- soon as it becomes available. If you are only interested in the
- complete data, just connect to the requestFinished() signal and
- read the data then instead.
-
- \sa get() post() request() readAll() readBlock() bytesAvailable()
-*/
-
-/*!
- \fn void TQHttp::dataSendProgress( int done, int total )
-
- This signal is emitted when this object sends data to a HTTP
- server to inform it about the progress of the upload.
-
- \a done is the amount of data that has already arrived and \a
- total is the total amount of data. It is possible that the total
- amount of data that should be transferred cannot be determined, in
- which case \a total is 0.(If you connect to a TQProgressBar, the
- progress bar shows a busy indicator if the total is 0).
-
- \warning \a done and \a total are not necessarily the size in
- bytes, since for large files these values might need to be
- "scaled" to avoid overflow.
-
- \sa dataReadProgress() post() request() TQProgressBar::setProgress()
-*/
-
-/*!
- \fn void TQHttp::dataReadProgress( int done, int total )
-
- This signal is emitted when this object reads data from a HTTP
- server to indicate the current progress of the download.
-
- \a done is the amount of data that has already arrived and \a
- total is the total amount of data. It is possible that the total
- amount of data that should be transferred cannot be determined, in
- which case \a total is 0.(If you connect to a TQProgressBar, the
- progress bar shows a busy indicator if the total is 0).
-
- \warning \a done and \a total are not necessarily the size in
- bytes, since for large files these values might need to be
- "scaled" to avoid overflow.
-
- \sa dataSendProgress() get() post() request() TQProgressBar::setProgress()
-*/
-
-/*!
- \fn void TQHttp::requestStarted( int id )
-
- This signal is emitted when processing the request identified by
- \a id starts.
-
- \sa requestFinished() done()
-*/
-
-/*!
- \fn void TQHttp::requestFinished( int id, bool error )
-
- This signal is emitted when processing the request identified by
- \a id has finished. \a error is TRUE if an error occurred during
- the processing; otherwise \a error is FALSE.
-
- \sa requestStarted() done() error() errorString()
-*/
-
-/*!
- \fn void TQHttp::done( bool error )
-
- This signal is emitted when the last pending request has finished;
- (it is emitted after the last request's requestFinished() signal).
- \a error is TRUE if an error occurred during the processing;
- otherwise \a error is FALSE.
-
- \sa requestFinished() error() errorString()
-*/
-
-/*!
- Aborts the current request and deletes all scheduled requests.
-
- For the current request, the requestFinished() signal with the \c
- error argument \c TRUE is emitted. For all other requests that are
- affected by the abort(), no Q_SIGNALS are emitted.
-
- Since this slot also deletes the scheduled requests, there are no
- requests left and the done() signal is emitted (with the \c error
- argument \c TRUE).
-
- \sa clearPendingRequests()
-*/
-void TQHttp::abort()
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( r == 0 )
- return;
-
- finishedWithError( tr("Request aborted"), Aborted );
- clearPendingRequests();
- d->socket.clearPendingData();
- close();
-}
-
-/*!
- Returns the number of bytes that can be read from the response
- content at the moment.
-
- \sa get() post() request() readyRead() readBlock() readAll()
-*/
-TQ_ULONG TQHttp::bytesAvailable() const
-{
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp::bytesAvailable(): %d bytes", (int)d->rba.size() );
-#endif
- return d->rba.size();
-}
-
-/*!
- Reads \a maxlen bytes from the response content into \a data and
- returns the number of bytes read. Returns -1 if an error occurred.
-
- \sa get() post() request() readyRead() bytesAvailable() readAll()
-*/
-TQ_LONG TQHttp::readBlock( char *data, TQ_ULONG maxlen )
-{
- if ( data == 0 && maxlen != 0 ) {
-#if defined(TQT_CHECK_NULL)
- qWarning( "TQHttp::readBlock: Null pointer error" );
-#endif
- return -1;
- }
- if ( maxlen >= d->rba.size() )
- maxlen = d->rba.size();
- d->rba.consumeBytes( maxlen, data );
-
- d->bytesDone += maxlen;
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp::readBlock(): read %d bytes (%d bytes done)", (int)maxlen, d->bytesDone );
-#endif
- return maxlen;
-}
-
-/*!
- Reads all the bytes from the response content and returns them.
-
- \sa get() post() request() readyRead() bytesAvailable() readBlock()
-*/
-TQByteArray TQHttp::readAll()
-{
- TQ_ULONG avail = bytesAvailable();
- TQByteArray tmp( avail );
- TQ_LONG read = readBlock( tmp.data(), avail );
- tmp.resize( read );
- return tmp;
-}
-
-/*!
- Returns the identifier of the HTTP request being executed or 0 if
- there is no request being executed (i.e. they've all finished).
-
- \sa currentRequest()
-*/
-int TQHttp::currentId() const
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( r == 0 )
- return 0;
- return r->id;
-}
-
-/*!
- Returns the request header of the HTTP request being executed. If
- the request is one issued by setHost() or closeConnection(), it
- returns an invalid request header, i.e.
- TQHttpRequestHeader::isValid() returns FALSE.
-
- \sa currentId()
-*/
-TQHttpRequestHeader TQHttp::currentRequest() const
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( r != 0 && r->hasRequestHeader() )
- return r->requestHeader();
- return TQHttpRequestHeader();
-}
-
-/*!
- Returns the TQIODevice pointer that is used as the data source of the HTTP
- request being executed. If there is no current request or if the request
- does not use an IO tqdevice as the data source, this function returns 0.
-
- This function can be used to delete the TQIODevice in the slot connected to
- the requestFinished() signal.
-
- \sa currentDestinationDevice() post() request()
-*/
-TQIODevice* TQHttp::currentSourceDevice() const
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( !r )
- return 0;
- return r->sourceDevice();
-}
-
-/*!
- Returns the TQIODevice pointer that is used as to store the data of the HTTP
- request being executed. If there is no current request or if the request
- does not store the data to an IO tqdevice, this function returns 0.
-
- This function can be used to delete the TQIODevice in the slot connected to
- the requestFinished() signal.
-
- \sa currentDestinationDevice() get() post() request()
-*/
-TQIODevice* TQHttp::currentDestinationDevice() const
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( !r )
- return 0;
- return r->destinationDevice();
-}
-
-/*!
- Returns TRUE if there are any requests scheduled that have not yet
- been executed; otherwise returns FALSE.
-
- The request that is being executed is \e not considered as a
- scheduled request.
-
- \sa clearPendingRequests() currentId() currentRequest()
-*/
-bool TQHttp::hasPendingRequests() const
-{
- return d->pending.count() > 1;
-}
-
-/*!
- Deletes all pending requests from the list of scheduled requests.
- This does not affect the request that is being executed. If
- you want to stop this this as well, use abort().
-
- \sa hasPendingRequests() abort()
-*/
-void TQHttp::clearPendingRequests()
-{
- TQHttpRequest *r = 0;
- if ( d->pending.count() > 0 )
- r = d->pending.take( 0 );
- d->pending.clear();
- if ( r )
- d->pending.append( r );
-}
-
-/*!
- Sets the HTTP server that is used for requests to \a hostname on
- port \a port.
-
- The function does not block and returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa get() post() head() request() requestStarted() requestFinished() done()
-*/
-int TQHttp::setHost(const TQString &hostname, TQ_UINT16 port )
-{
- return addRequest( new TQHttpSetHostRequest( hostname, port ) );
-}
-
-/*!
- Sends a get request for \a path to the server set by setHost() or
- as specified in the constructor.
-
- \a path must be an absolute path like \c /index.html or an
- absolute URI like \c http://www.trolltech.com/index.html.
-
- If the IO tqdevice \a to is 0 the readyRead() signal is emitted
- every time new content data is available to read.
-
- If the IO tqdevice \a to is not 0, the content data of the response
- is written directly to the tqdevice. Make sure that the \a to
- pointer is valid for the duration of the operation (it is safe to
- delete it when the requestFinished() signal is emitted).
-
- The function does not block and returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() post() head() request() requestStarted() requestFinished() done()
-*/
-int TQHttp::get( const TQString& path, TQIODevice* to )
-{
- TQHttpRequestHeader header( "GET", path );
- header.setValue( "Connection", "Keep-Alive" );
- return addRequest( new TQHttpPGHRequest( header, (TQIODevice*)0, to ) );
-}
-
-/*!
- Sends a post request for \a path to the server set by setHost() or
- as specified in the constructor.
-
- \a path must be an absolute path like \c /index.html or an
- absolute URI like \c http://www.trolltech.com/index.html.
-
- The incoming data comes via the \a data IO tqdevice.
-
- If the IO tqdevice \a to is 0 the readyRead() signal is emitted
- every time new content data is available to read.
-
- If the IO tqdevice \a to is not 0, the content data of the response
- is written directly to the tqdevice. Make sure that the \a to
- pointer is valid for the duration of the operation (it is safe to
- delete it when the requestFinished() signal is emitted).
-
- The function does not block and returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() get() head() request() requestStarted() requestFinished() done()
-*/
-int TQHttp::post( const TQString& path, TQIODevice* data, TQIODevice* to )
-{
- TQHttpRequestHeader header( "POST", path );
- header.setValue( "Connection", "Keep-Alive" );
- return addRequest( new TQHttpPGHRequest( header, data, to ) );
-}
-
-/*!
- \overload
-
- \a data is used as the content data of the HTTP request.
-*/
-int TQHttp::post( const TQString& path, const TQByteArray& data, TQIODevice* to )
-{
- TQHttpRequestHeader header( "POST", path );
- header.setValue( "Connection", "Keep-Alive" );
- return addRequest( new TQHttpPGHRequest( header, new TQByteArray(data), to ) );
-}
-
-/*!
- Sends a header request for \a path to the server set by setHost()
- or as specified in the constructor.
-
- \a path must be an absolute path like \c /index.html or an
- absolute URI like \c http://www.trolltech.com/index.html.
-
- The function does not block and returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() get() post() request() requestStarted() requestFinished() done()
-*/
-int TQHttp::head( const TQString& path )
-{
- TQHttpRequestHeader header( "HEAD", path );
- header.setValue( "Connection", "Keep-Alive" );
- return addRequest( new TQHttpPGHRequest( header, (TQIODevice*)0, 0 ) );
-}
-
-/*!
- Sends a request to the server set by setHost() or as specified in
- the constructor. Uses the \a header as the HTTP request header.
- You are responsible for setting up a header that is appropriate
- for your request.
-
- The incoming data comes via the \a data IO tqdevice.
-
- If the IO tqdevice \a to is 0 the readyRead() signal is emitted
- every time new content data is available to read.
-
- If the IO tqdevice \a to is not 0, the content data of the response
- is written directly to the tqdevice. Make sure that the \a to
- pointer is valid for the duration of the operation (it is safe to
- delete it when the requestFinished() signal is emitted).
-
- The function does not block and returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() get() post() head() requestStarted() requestFinished() done()
-*/
-int TQHttp::request( const TQHttpRequestHeader &header, TQIODevice *data, TQIODevice *to )
-{
- return addRequest( new TQHttpNormalRequest( header, data, to ) );
-}
-
-/*!
- \overload
-
- \a data is used as the content data of the HTTP request.
-*/
-int TQHttp::request( const TQHttpRequestHeader &header, const TQByteArray &data, TQIODevice *to )
-{
- return addRequest( new TQHttpNormalRequest( header, new TQByteArray(data), to ) );
-}
-
-/*!
- Closes the connection; this is useful if you have a keep-alive
- connection and want to close it.
-
- For the requests issued with get(), post() and head(), TQHttp sets
- the connection to be keep-alive. You can also do this using the
- header you pass to the request() function. TQHttp only closes the
- connection to the HTTP server if the response header requires it
- to do so.
-
- The function does not block and returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- If you want to close the connection immediately, you have to use
- abort() instead.
-
- \sa stateChanged() abort() requestStarted() requestFinished() done()
-*/
-int TQHttp::closeConnection()
-{
- return addRequest( new TQHttpCloseRequest() );
-}
-
-int TQHttp::addRequest( TQHttpRequest *req )
-{
- d->pending.append( req );
-
- if ( d->pending.count() == 1 )
- // don't emit the requestStarted() signal before the id is returned
- TQTimer::singleShot( 0, this, TQT_SLOT(startNextRequest()) );
-
- return req->id;
-}
-
-void TQHttp::startNextRequest()
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( r == 0 )
- return;
-
- d->error = NoError;
- d->errorString = tr( "Unknown error" );
-
- if ( bytesAvailable() )
- readAll(); // clear the data
- emit requestStarted( r->id );
- r->start( this );
-}
-
-void TQHttp::sendRequest()
-{
- if ( d->hostname.isNull() ) {
- finishedWithError( tr("No server set to connect to"), UnknownError );
- return;
- }
-
- killIdleTimer();
-
- // Do we need to setup a new connection or can we reuse an
- // existing one ?
- if ( d->socket.peerName() != d->hostname || d->socket.peerPort() != d->port
- || d->socket.state() != TQSocket::Connection ) {
- setState( TQHttp::Connecting );
- d->socket.connectToHost( d->hostname, d->port );
- } else {
- slotConnected();
- }
-
-}
-
-void TQHttp::finishedWithSuccess()
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( r == 0 )
- return;
-
- emit requestFinished( r->id, FALSE );
- d->pending.removeFirst();
- if ( d->pending.isEmpty() ) {
- emit done( FALSE );
- } else {
- startNextRequest();
- }
-}
-
-void TQHttp::finishedWithError( const TQString& detail, int errorCode )
-{
- TQHttpRequest *r = d->pending.getFirst();
- if ( r == 0 )
- return;
-
- d->error = (Error)errorCode;
- d->errorString = detail;
- emit requestFinished( r->id, TRUE );
-
- d->pending.clear();
- emit done( TRUE );
-}
-
-void TQHttp::slotClosed()
-{
- if ( d->state == Closing )
- return;
-
- if ( d->state == Reading ) {
- if ( d->response.hasKey( "content-length" ) ) {
- // We got Content-Length, so did we get all bytes?
- if ( d->bytesDone+bytesAvailable() != d->response.contentLength() ) {
- finishedWithError( tr("Wrong content length"), WrongContentLength );
- }
- }
- } else if ( d->state == Connecting || d->state == Sending ) {
- finishedWithError( tr("Server closed connection unexpectedly"), UnexpectedClose );
- }
-
- d->postDevice = 0;
- setState( Closing );
- d->idleTimer = startTimer( 0 );
-}
-
-void TQHttp::slotConnected()
-{
- if ( d->state != Sending ) {
- d->bytesDone = 0;
- setState( Sending );
- }
-
- TQString str = d->header.toString();
- d->bytesTotal = str.length();
- d->socket.writeBlock( str.latin1(), d->bytesTotal );
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp: write request header:\n---{\n%s}---", str.latin1() );
-#endif
-
- if ( d->postDevice ) {
- d->bytesTotal += d->postDevice->size();
- } else {
- d->bytesTotal += d->buffer.size();
- d->socket.writeBlock( d->buffer.data(), d->buffer.size() );
- d->buffer = TQByteArray(); // save memory
- }
-}
-
-void TQHttp::slotError( int err )
-{
- d->postDevice = 0;
-
- if ( d->state == Connecting || d->state == Reading || d->state == Sending ) {
- switch ( err ) {
- case TQSocket::ErrConnectionRefused:
- finishedWithError( tr("Connection refused"), ConnectionRefused );
- break;
- case TQSocket::ErrHostNotFound:
- finishedWithError( tr("Host %1 not found").arg(d->socket.peerName()), HostNotFound );
- break;
- default:
- finishedWithError( tr("HTTP request failed"), UnknownError );
- break;
- }
- }
-
- close();
-}
-
-void TQHttp::slotBytesWritten( int written )
-{
- d->bytesDone += written;
- emit dataSendProgress( d->bytesDone, d->bytesTotal );
-
- if ( !d->postDevice )
- return;
-
- if ( d->socket.bytesToWrite() == 0 ) {
- int max = TQMIN( 4096, d->postDevice->size() - d->postDevice->at() );
- TQByteArray arr( max );
-
- int n = d->postDevice->readBlock( arr.data(), max );
- if ( n != max ) {
- qWarning("Could not read enough bytes from the tqdevice");
- close();
- return;
- }
- if ( d->postDevice->atEnd() ) {
- d->postDevice = 0;
- }
-
- d->socket.writeBlock( arr.data(), max );
- }
-}
-
-void TQHttp::slotReadyRead()
-{
- if ( d->state != Reading ) {
- setState( Reading );
- d->buffer = TQByteArray();
- d->readHeader = TRUE;
- d->headerStr = "";
- d->bytesDone = 0;
- d->chunkedSize = -1;
- }
-
- while ( d->readHeader ) {
- bool end = FALSE;
- TQString tmp;
- while ( !end && d->socket.canReadLine() ) {
- tmp = d->socket.readLine();
- if ( tmp == "\r\n" || tmp == "\n" )
- end = TRUE;
- else
- d->headerStr += tmp;
- }
-
- if ( !end )
- return;
-
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp: read response header:\n---{\n%s}---", d->headerStr.latin1() );
-#endif
- d->response = TQHttpResponseHeader( d->headerStr );
- d->headerStr = "";
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp: read response header:\n---{\n%s}---", d->response.toString().latin1() );
-#endif
- // Check header
- if ( !d->response.isValid() ) {
- finishedWithError( tr("Invalid HTTP response header"), InvalidResponseHeader );
- close();
- return;
- }
-
- // The 100-continue header is ignored, because when using the
- // POST method, we send both the request header and data in
- // one chunk.
- if (d->response.statusCode() != 100) {
- d->readHeader = FALSE;
- if ( d->response.hasKey( "transfer-encoding" ) &&
- d->response.value( "transfer-encoding" ).lower().contains( "chunked" ) )
- d->chunkedSize = 0;
-
- emit responseHeaderReceived( d->response );
- }
- }
-
- if ( !d->readHeader ) {
- bool everythingRead = FALSE;
-
- if ( currentRequest().method() == "HEAD" ) {
- everythingRead = TRUE;
- } else {
- TQ_ULONG n = d->socket.bytesAvailable();
- TQByteArray *arr = 0;
- if ( d->chunkedSize != -1 ) {
- // transfer-encoding is chunked
- for ( ;; ) {
- // get chunk size
- if ( d->chunkedSize == 0 ) {
- if ( !d->socket.canReadLine() )
- break;
- TQString sizeString = d->socket.readLine();
- int tPos = sizeString.find( ';' );
- if ( tPos != -1 )
- sizeString.truncate( tPos );
- bool ok;
- d->chunkedSize = sizeString.toInt( &ok, 16 );
- if ( !ok ) {
- finishedWithError( tr("Invalid HTTP chunked body"), WrongContentLength );
- close();
- delete arr;
- return;
- }
- if ( d->chunkedSize == 0 ) // last-chunk
- d->chunkedSize = -2;
- }
-
- // read trailer
- while ( d->chunkedSize == -2 && d->socket.canReadLine() ) {
- TQString read = d->socket.readLine();
- if ( read == "\r\n" || read == "\n" )
- d->chunkedSize = -1;
- }
- if ( d->chunkedSize == -1 ) {
- everythingRead = TRUE;
- break;
- }
-
- // make sure that you can read the terminating CRLF,
- // otherwise wait until next time...
- n = d->socket.bytesAvailable();
- if ( n == 0 )
- break;
- if ( (TQ_LONG)n == d->chunkedSize || (TQ_LONG)n == d->chunkedSize+1 ) {
- n = d->chunkedSize - 1;
- if ( n == 0 )
- break;
- }
-
- // read data
- uint toRead = TQMIN( (TQ_LONG)n, (d->chunkedSize < 0 ? (TQ_LONG)n : d->chunkedSize) );
- if ( !arr )
- arr = new TQByteArray( 0 );
- uint oldArrSize = arr->size();
- arr->resize( oldArrSize + toRead );
- TQ_LONG read = d->socket.readBlock( arr->data()+oldArrSize, toRead );
- arr->resize( oldArrSize + read );
-
- d->chunkedSize -= read;
-
- if ( d->chunkedSize == 0 && n - read >= 2 ) {
- // read terminating CRLF
- char tmp[2];
- d->socket.readBlock( tmp, 2 );
- if ( tmp[0] != '\r' || tmp[1] != '\n' ) {
- finishedWithError( tr("Invalid HTTP chunked body"), WrongContentLength );
- close();
- return;
- }
- }
- }
- } else if ( d->response.hasContentLength() ) {
- n = TQMIN( d->response.contentLength() - d->bytesDone, n );
- if ( n > 0 ) {
- arr = new TQByteArray( n );
- TQ_LONG read = d->socket.readBlock( arr->data(), n );
- arr->resize( read );
- }
- if ( d->bytesDone + bytesAvailable() + n == d->response.contentLength() )
- everythingRead = TRUE;
- } else if ( n > 0 ) {
- // workaround for VC++ bug
- TQByteArray temp = TQT_TQBYTEARRAY_OBJECT(d->socket.readAll());
- arr = new TQByteArray( temp );
- }
-
- if ( arr ) {
- n = arr->size();
- if ( d->toDevice ) {
- d->toDevice->writeBlock( arr->data(), n );
- delete arr;
- d->bytesDone += n;
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp::slotReadyRead(): read %ld bytes (%d bytes done)", n, d->bytesDone );
-#endif
- if ( d->response.hasContentLength() )
- emit dataReadProgress( d->bytesDone, d->response.contentLength() );
- else
- emit dataReadProgress( d->bytesDone, 0 );
- } else {
- d->rba.append( arr );
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp::slotReadyRead(): read %ld bytes (%ld bytes done)", n, d->bytesDone + bytesAvailable() );
-#endif
- if ( d->response.hasContentLength() )
- emit dataReadProgress( d->bytesDone + bytesAvailable(), d->response.contentLength() );
- else
- emit dataReadProgress( d->bytesDone + bytesAvailable(), 0 );
- emit readyRead( d->response );
- }
- }
- }
-
- if ( everythingRead ) {
- // Handle "Connection: close"
- if ( d->response.value("connection").lower() == "close" ) {
- close();
- } else {
- setState( Connected );
- // Start a timer, so that we emit the keep alive signal
- // "after" this method returned.
- d->idleTimer = startTimer( 0 );
- }
- }
- }
-}
-
-/*!
- Returns the current state of the object. When the state changes,
- the stateChanged() signal is emitted.
-
- \sa State stateChanged()
-*/
-TQHttp::State TQHttp::state() const
-{
- return d->state;
-}
-
-/*!
- Returns the last error that occurred. This is useful to find out
- what happened when receiving a requestFinished() or a done()
- signal with the \c error argument \c TRUE.
-
- If you start a new request, the error status is reset to \c NoError.
-*/
-TQHttp::Error TQHttp::error() const
-{
- return d->error;
-}
-
-/*!
- Returns a human-readable description of the last error that
- occurred. This is useful to present a error message to the user
- when receiving a requestFinished() or a done() signal with the \c
- error argument \c TRUE.
-*/
-TQString TQHttp::errorString() const
-{
- return d->errorString;
-}
-
-/*! \reimp
-*/
-void TQHttp::timerEvent( TQTimerEvent *e )
-{
- if ( e->timerId() == d->idleTimer ) {
- killTimer( d->idleTimer );
- d->idleTimer = 0;
-
- if ( d->state == Connected ) {
- finishedWithSuccess();
- } else if ( d->state != Unconnected ) {
- setState( Unconnected );
- finishedWithSuccess();
- }
- } else {
- TQObject::timerEvent( e );
- }
-}
-
-void TQHttp::killIdleTimer()
-{
- killTimer( d->idleTimer );
- d->idleTimer = 0;
-}
-
-void TQHttp::setState( int s )
-{
-#if defined(TQHTTP_DEBUG)
- qDebug( "TQHttp state changed %d -> %d", d->state, s );
-#endif
- d->state = (State)s;
- emit stateChanged( s );
-}
-
-void TQHttp::close()
-{
- // If no connection is open -> ignore
- if ( d->state == Closing || d->state == Unconnected )
- return;
-
- d->postDevice = 0;
- setState( Closing );
-
- // Already closed ?
- if ( !d->socket.isOpen() ) {
- d->idleTimer = startTimer( 0 );
- } else {
- // Close now.
- d->socket.close();
-
- // Did close succeed immediately ?
- if ( d->socket.state() == TQSocket::Idle ) {
- // Prepare to emit the requestFinished() signal.
- d->idleTimer = startTimer( 0 );
- }
- }
-}
-
-/**********************************************************************
- *
- * TQHttp implementation of the TQNetworkProtocol interface
- *
- *********************************************************************/
-/*! \reimp
-*/
-int TQHttp::supportedOperations() const
-{
- return OpGet | OpPut;
-}
-
-/*! \reimp
-*/
-void TQHttp::operationGet( TQNetworkOperation *op )
-{
- connect( this, TQT_SIGNAL(readyRead(const TQHttpResponseHeader&)),
- this, TQT_SLOT(clientReply(const TQHttpResponseHeader&)) );
- connect( this, TQT_SIGNAL(done(bool)),
- this, TQT_SLOT(clientDone(bool)) );
- connect( this, TQT_SIGNAL(stateChanged(int)),
- this, TQT_SLOT(clientStateChanged(int)) );
-
- bytesRead = 0;
- op->setState( StInProgress );
- TQUrl u( operationInProgress()->arg( 0 ) );
- TQHttpRequestHeader header( "GET", u.encodedPathAndQuery(), 1, 0 );
- header.setValue( "Host", u.host() );
- setHost( u.host(), u.port() != -1 ? u.port() : 80 );
- request( header );
-}
-
-/*! \reimp
-*/
-void TQHttp::operationPut( TQNetworkOperation *op )
-{
- connect( this, TQT_SIGNAL(readyRead(const TQHttpResponseHeader&)),
- this, TQT_SLOT(clientReply(const TQHttpResponseHeader&)) );
- connect( this, TQT_SIGNAL(done(bool)),
- this, TQT_SLOT(clientDone(bool)) );
- connect( this, TQT_SIGNAL(stateChanged(int)),
- this, TQT_SLOT(clientStateChanged(int)) );
-
- bytesRead = 0;
- op->setState( StInProgress );
- TQUrl u( operationInProgress()->arg( 0 ) );
- TQHttpRequestHeader header( "POST", u.encodedPathAndQuery(), 1, 0 );
- header.setValue( "Host", u.host() );
- setHost( u.host(), u.port() != -1 ? u.port() : 80 );
- request( header, op->rawArg(1) );
-}
-
-void TQHttp::clientReply( const TQHttpResponseHeader &rep )
-{
- TQNetworkOperation *op = operationInProgress();
- if ( op ) {
- if ( rep.statusCode() >= 400 && rep.statusCode() < 600 ) {
- op->setState( StFailed );
- op->setProtocolDetail(
- TQString("%1 %2").arg(rep.statusCode()).arg(rep.reasonPhrase())
- );
- switch ( rep.statusCode() ) {
- case 401:
- case 403:
- case 405:
- op->setErrorCode( ErrPermissionDenied );
- break;
- case 404:
- op->setErrorCode(ErrFileNotExisting );
- break;
- default:
- if ( op->operation() == OpGet )
- op->setErrorCode( ErrGet );
- else
- op->setErrorCode( ErrPut );
- break;
- }
- }
- // ### In cases of an error, should we still emit the data() Q_SIGNALS?
- if ( op->operation() == OpGet && bytesAvailable() > 0 ) {
- TQByteArray ba = readAll();
- emit data( ba, op );
- bytesRead += ba.size();
- if ( rep.hasContentLength() ) {
- emit dataTransferProgress( bytesRead, rep.contentLength(), op );
- }
- }
- }
-}
-
-void TQHttp::clientDone( bool err )
-{
- disconnect( this, TQT_SIGNAL(readyRead(const TQHttpResponseHeader&)),
- this, TQT_SLOT(clientReply(const TQHttpResponseHeader&)) );
- disconnect( this, TQT_SIGNAL(done(bool)),
- this, TQT_SLOT(clientDone(bool)) );
- disconnect( this, TQT_SIGNAL(stateChanged(int)),
- this, TQT_SLOT(clientStateChanged(int)) );
-
- if ( err ) {
- TQNetworkOperation *op = operationInProgress();
- if ( op ) {
- op->setState( TQNetworkProtocol::StFailed );
- op->setProtocolDetail( errorString() );
- switch ( error() ) {
- case ConnectionRefused:
- op->setErrorCode( ErrHostNotFound );
- break;
- case HostNotFound:
- op->setErrorCode( ErrHostNotFound );
- break;
- default:
- if ( op->operation() == OpGet )
- op->setErrorCode( ErrGet );
- else
- op->setErrorCode( ErrPut );
- break;
- }
- emit finished( op );
- }
- } else {
- TQNetworkOperation *op = operationInProgress();
- if ( op ) {
- if ( op->state() != StFailed ) {
- op->setState( TQNetworkProtocol::StDone );
- op->setErrorCode( TQNetworkProtocol::NoError );
- }
- emit finished( op );
- }
- }
-
-}
-
-void TQHttp::clientStateChanged( int state )
-{
- if ( url() ) {
- switch ( (State)state ) {
- case Connecting:
- emit connectionStateChanged( ConHostFound, tr( "Host %1 found" ).arg( url()->host() ) );
- break;
- case Sending:
- emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) );
- break;
- case Unconnected:
- emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) );
- break;
- default:
- break;
- }
- } else {
- switch ( (State)state ) {
- case Connecting:
- emit connectionStateChanged( ConHostFound, tr( "Host found" ) );
- break;
- case Sending:
- emit connectionStateChanged( ConConnected, tr( "Connected to host" ) );
- break;
- case Unconnected:
- emit connectionStateChanged( ConClosed, tr( "Connection closed" ) );
- break;
- default:
- break;
- }
- }
-}
-
-#endif
diff --git a/tqtinterface/qt4/src/network/tqhttp.h b/tqtinterface/qt4/src/network/tqhttp.h
deleted file mode 100644
index fb20d4f..0000000
--- a/tqtinterface/qt4/src/network/tqhttp.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/****************************************************************************
-**
-** Definition of TQHttp and related classes.
-**
-** Created : 970521
-**
-** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQHTTP_H
-#define TQHTTP_H
-
-#ifndef TQT_H
-#include "tqobject.h"
-#include "tqnetworkprotocol.h"
-#include "tqstringlist.h"
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_HTTP
-#define TQM_TEMPLATE_EXTERN_HTTP
-#else
-#define TQM_EXPORT_HTTP TQ_EXPORT
-#define TQM_TEMPLATE_EXTERN_HTTP TQ_TEMPLATE_EXTERN
-#endif
-
-#ifndef TQT_NO_NETWORKPROTOCOL_HTTP
-
-class TQSocket;
-class TQTimerEvent;
-class TQTextStream;
-class TQIODevice;
-
-class TQHttpPrivate;
-class TQHttpRequest;
-
-class TQM_EXPORT_HTTP TQHttpHeader
-{
-public:
- TQHttpHeader();
- TQHttpHeader( const TQHttpHeader& header );
- TQHttpHeader( const TQString& str );
- virtual ~TQHttpHeader();
-
- TQHttpHeader& operator=( const TQHttpHeader& h );
-
- TQString value( const TQString& key ) const;
- void setValue( const TQString& key, const TQString& value );
- void removeValue( const TQString& key );
-
- TQStringList keys() const;
- bool hasKey( const TQString& key ) const;
-
- bool hasContentLength() const;
- uint contentLength() const;
- void setContentLength( int len );
-
- bool hasContentType() const;
- TQString contentType() const;
- void setContentType( const TQString& type );
-
- virtual TQString toString() const;
- bool isValid() const;
-
- virtual int majorVersion() const = 0;
- virtual int minorVersion() const = 0;
-
-protected:
- virtual bool parseLine( const TQString& line, int number );
- bool parse( const TQString& str );
- void setValid( bool );
-
-private:
- TQMap<TQString,TQString> values;
- bool valid;
-};
-
-class TQM_EXPORT_HTTP TQHttpResponseHeader : public TQHttpHeader
-{
-private:
- TQHttpResponseHeader( int code, const TQString& text = TQString::null, int majorVer = 1, int minorVer = 1 );
- TQHttpResponseHeader( const TQString& str );
-
- void setqStatusLine( int code, const TQString& text = TQString::null, int majorVer = 1, int minorVer = 1 );
-
-public:
- TQHttpResponseHeader();
- TQHttpResponseHeader( const TQHttpResponseHeader& header );
-
- int statusCode() const;
- TQString reasonPhrase() const;
-
- int majorVersion() const;
- int minorVersion() const;
-
- TQString toString() const;
-
-protected:
- bool parseLine( const TQString& line, int number );
-
-private:
- int statCode;
- TQString reasonPhr;
- int majVer;
- int minVer;
-
- friend class TQHttp;
-};
-
-class TQM_EXPORT_HTTP TQHttpRequestHeader : public TQHttpHeader
-{
-public:
- TQHttpRequestHeader();
- TQHttpRequestHeader( const TQString& method, const TQString& path, int majorVer = 1, int minorVer = 1 );
- TQHttpRequestHeader( const TQHttpRequestHeader& header );
- TQHttpRequestHeader( const TQString& str );
-
- void setRequest( const TQString& method, const TQString& path, int majorVer = 1, int minorVer = 1 );
-
- TQString method() const;
- TQString path() const;
-
- int majorVersion() const;
- int minorVersion() const;
-
- TQString toString() const;
-
-protected:
- bool parseLine( const TQString& line, int number );
-
-private:
- TQString m;
- TQString p;
- int majVer;
- int minVer;
-};
-
-class TQM_EXPORT_HTTP TQHttp : public TQNetworkProtocol
-{
- Q_OBJECT
- TQ_OBJECT
-
-public:
- TQHttp();
- TQHttp( TQObject* parent, const char* name = 0 ); // ### TQt 4.0: make parent=0 and get rid of the TQHttp() constructor
- TQHttp( const TQString &hostname, TQ_UINT16 port=80, TQObject* parent=0, const char* name = 0 );
- virtual ~TQHttp();
-
- int supportedOperations() const;
-
- enum State { Unconnected, HostLookup, Connecting, Sending, Reading, Connected, Closing };
- enum Error {
- NoError,
- UnknownError,
- HostNotFound,
- ConnectionRefused,
- UnexpectedClose,
- InvalidResponseHeader,
- WrongContentLength,
- Aborted
- };
-
- int setHost(const TQString &hostname, TQ_UINT16 port=80 );
-
- int get( const TQString& path, TQIODevice* to=0 );
- int post( const TQString& path, TQIODevice* data, TQIODevice* to=0 );
- int post( const TQString& path, const TQByteArray& data, TQIODevice* to=0 );
- int head( const TQString& path );
- int request( const TQHttpRequestHeader &header, TQIODevice *tqdevice=0, TQIODevice *to=0 );
- int request( const TQHttpRequestHeader &header, const TQByteArray &data, TQIODevice *to=0 );
-
- int closeConnection();
-
- TQ_ULONG bytesAvailable() const;
- TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
- TQByteArray readAll();
-
- int currentId() const;
- TQIODevice* currentSourceDevice() const;
- TQIODevice* currentDestinationDevice() const;
- TQHttpRequestHeader currentRequest() const;
- bool hasPendingRequests() const;
- void clearPendingRequests();
-
- State state() const;
-
- Error error() const;
- TQString errorString() const;
-
-public Q_SLOTS:
- void abort();
-
-Q_SIGNALS:
- void stateChanged( int );
- void responseHeaderReceived( const TQHttpResponseHeader& resp );
- void readyRead( const TQHttpResponseHeader& resp );
- void dataSendProgress( int, int );
- void dataReadProgress( int, int );
-
- void requestStarted( int );
- void requestFinished( int, bool );
- void done( bool );
-
-protected:
- void operationGet( TQNetworkOperation *op );
- void operationPut( TQNetworkOperation *op );
-
- void timerEvent( TQTimerEvent * );
-
-private Q_SLOTS:
- void clientReply( const TQHttpResponseHeader &rep );
- void clientDone( bool );
- void clientStateChanged( int );
-
- void startNextRequest();
- void slotReadyRead();
- void slotConnected();
- void slotError( int );
- void slotClosed();
- void slotBytesWritten( int );
-
-private:
- TQHttpPrivate *d;
- void *unused; // ### TQt 4.0: remove this (in for binary compatibility)
- int bytesRead;
-
- int addRequest( TQHttpRequest * );
- void sendRequest();
- void finishedWithSuccess();
- void finishedWithError( const TQString& detail, int errorCode );
-
- void killIdleTimer();
-
- void init();
- void setState( int );
- void close();
-
- friend class TQHttpNormalRequest;
- friend class TQHttpSetHostRequest;
- friend class TQHttpCloseRequest;
- friend class TQHttpPGHRequest;
-};
-
-#define TQ_DEFINED_TQHTTP
-#include "tqwinexport.h"
-#endif
-#endif
diff --git a/tqtinterface/qt4/src/network/tqnetwork.cpp b/tqtinterface/qt4/src/network/tqnetwork.cpp
deleted file mode 100644
index 14cdda5..0000000
--- a/tqtinterface/qt4/src/network/tqnetwork.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Implementation of qInitNetworkProtocols function.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqnetwork.h"
-
-#ifndef TQT_NO_NETWORK
-
-#include "tqnetworkprotocol.h"
-
-// protocols
-#include "tqftp.h"
-#include "tqhttp.h"
-
-/*! \file tqnetwork.h */
-/*!
- \relates TQUrlOperator
-
- This function registers the network protocols for FTP and HTTP.
- You must call this function before you use TQUrlOperator for
- these protocols.
-
- This function is declared in \l tqnetwork.h.
-*/
-void qInitNetworkProtocols()
-{
-#ifndef TQT_NO_NETWORKPROTOCOL_FTP
- TQNetworkProtocol::registerNetworkProtocol( "ftp", new TQNetworkProtocolFactory< TQFtp > );
-#endif
-#ifndef TQT_NO_NETWORKPROTOCOL_HTTP
- TQNetworkProtocol::registerNetworkProtocol( "http", new TQNetworkProtocolFactory< TQHttp > );
-#endif
-}
-
-#endif // TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/network/tqnetwork.h b/tqtinterface/qt4/src/network/tqnetwork.h
deleted file mode 100644
index 131f40f..0000000
--- a/tqtinterface/qt4/src/network/tqnetwork.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Definition of qInitNetworkProtocols function.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQNETWORK_H
-#define TQNETWORK_H
-
-#ifndef TQT_H
-#include "tqglobal.h"
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_NETWORK
-#else
-#define TQM_EXPORT_NETWORK TQ_EXPORT
-#endif
-
-#ifndef TQT_NO_NETWORK
-
-TQM_EXPORT_NETWORK void qInitNetworkProtocols();
-
-#endif
-
-#endif
diff --git a/tqtinterface/qt4/src/network/tqserversocket.cpp b/tqtinterface/qt4/src/network/tqserversocket.cpp
deleted file mode 100644
index 02a15b0..0000000
--- a/tqtinterface/qt4/src/network/tqserversocket.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQServerSocket class.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqserversocket.h"
-
-#ifndef TQT_NO_NETWORK
-
-#include "tqsocketnotifier.h"
-
-class TQServerSocketPrivate {
-public:
- TQServerSocketPrivate(): s(0), n(0) {}
- ~TQServerSocketPrivate() { delete n; delete s; }
- TQSocketDevice *s;
- TQSocketNotifier *n;
-};
-
-
-/*!
- \class TQServerSocket tqserversocket.h
- \brief The TQServerSocket class provides a TCP-based server.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class is a convenience class for accepting incoming TCP
- connections. You can specify the port or have TQServerSocket pick
- one, and listen on just one address or on all the machine's
- addresses.
-
- Using the API is very simple: subclass TQServerSocket, call the
- constructor of your choice, and implement newConnection() to
- handle new incoming connections. There is nothing more to do.
-
- (Note that due to lack of support in the underlying APIs,
- TQServerSocket cannot accept or reject connections conditionally.)
-
- \sa TQSocket, TQSocketDevice, TQHostAddress, TQSocketNotifier
-*/
-
-
-/*!
- Creates a server socket object, that will serve the given \a port
- on all the addresses of this host. If \a port is 0, TQServerSocket
- will pick a suitable port in a system-dependent manner. Use \a
- backlog to specify how many pending connections the server can
- have.
-
- The \a parent and \a name arguments are passed on to the TQObject
- constructor.
-
- \warning On Tru64 Unix systems a value of 0 for \a backlog means
- that you don't accept any connections at all; you should specify a
- value larger than 0.
-*/
-
-TQServerSocket::TQServerSocket( TQ_UINT16 port, int backlog,
- TQObject *parent, const char *name )
- : TQObject( parent, name )
-{
- d = new TQServerSocketPrivate;
- init( TQHostAddress(), port, backlog );
-}
-
-
-/*!
- Creates a server socket object, that will serve the given \a port
- only on the given \a address. Use \a backlog to specify how many
- pending connections the server can have.
-
- The \a parent and \a name arguments are passed on to the TQObject
- constructor.
-
- \warning On Tru64 Unix systems a value of 0 for \a backlog means
- that you don't accept any connections at all; you should specify a
- value larger than 0.
-*/
-
-TQServerSocket::TQServerSocket( const TQHostAddress & address, TQ_UINT16 port,
- int backlog,
- TQObject *parent, const char *name )
- : TQObject( parent, name )
-{
- d = new TQServerSocketPrivate;
- init( address, port, backlog );
-}
-
-
-/*!
- Construct an empty server socket.
-
- This constructor, in combination with setSocket(), allows us to
- use the TQServerSocket class as a wrapper for other socket types
- (e.g. Unix Domain Sockets under Unix).
-
- The \a parent and \a name arguments are passed on to the TQObject
- constructor.
-
- \sa setSocket()
-*/
-
-TQServerSocket::TQServerSocket( TQObject *parent, const char *name )
- : TQObject( parent, name )
-{
- d = new TQServerSocketPrivate;
-}
-
-
-/*!
- Returns TRUE if the construction succeeded; otherwise returns FALSE.
-*/
-bool TQServerSocket::ok() const
-{
- return !!d->s;
-}
-
-/*
- The common bit of the constructors.
- */
-void TQServerSocket::init( const TQHostAddress & address, TQ_UINT16 port, int backlog )
-{
- d->s = new TQSocketDevice( TQSocketDevice::Stream, address.isIPv4Address()
- ? TQSocketDevice::IPv4 : TQSocketDevice::IPv6, 0 );
-#if !defined(TQ_OS_WIN32)
- // Under Unix, we want to be able to use the port, even if a socket on the
- // same address-port is in TIME_WAIT. Under Windows this is possible anyway
- // -- furthermore, the meaning of reusable is different: it means that you
- // can use the same address-port for multiple listening sockets.
- d->s->setAddressReusable( TRUE );
-#endif
- if ( d->s->bind( address, port )
- && d->s->listen( backlog ) )
- {
- d->n = new TQSocketNotifier( d->s->socket(), TQSocketNotifier::Read,
- this, "accepting new connections" );
- connect( d->n, TQT_SIGNAL(activated(int)),
- this, TQT_SLOT(incomingConnection(int)) );
- } else {
- qWarning( "TQServerSocket: failed to bind or listen to the socket" );
- delete d->s;
- d->s = 0;
- }
-}
-
-
-/*!
- Destroys the socket.
-
- This causes any backlogged connections (connections that have
- reached the host, but not yet been completely set up by calling
- TQSocketDevice::accept()) to be severed.
-
- Existing connections continue to exist; this only affects the
- acceptance of new connections.
-*/
-TQServerSocket::~TQServerSocket()
-{
- delete d;
-}
-
-
-/*!
- \fn void TQServerSocket::newConnection( int socket )
-
- This pure virtual function is responsible for setting up a new
- incoming connection. \a socket is the fd (file descriptor) for the
- newly accepted connection.
-*/
-
-
-void TQServerSocket::incomingConnection( int )
-{
- int fd = d->s->accept();
- if ( fd >= 0 )
- newConnection( fd );
-}
-
-
-/*!
- Returns the port number on which this server socket listens. This
- is always non-zero; if you specify 0 in the constructor,
- TQServerSocket will pick a non-zero port itself. ok() must be TRUE
- before calling this function.
-
- \sa address() TQSocketDevice::port()
-*/
-TQ_UINT16 TQServerSocket::port() const
-{
- if ( !d || !d->s )
- return 0;
- return d->s->port();
-}
-
-
-/*!
- Returns the operating system socket.
-*/
-int TQServerSocket::socket() const
-{
- if ( !d || !d->s )
- return -1;
-
- return d->s->socket();
-}
-
-/*!
- Returns the address on which this object listens, or 0.0.0.0 if
- this object listens on more than one address. ok() must be TRUE
- before calling this function.
-
- \sa port() TQSocketDevice::address()
-*/
-TQHostAddress TQServerSocket::address() const
-{
- if ( !d || !d->s )
- return TQHostAddress();
-
- return d->s->address();
-}
-
-
-/*!
- Returns a pointer to the internal socket tqdevice. The returned
- pointer is 0 if there is no connection or pending connection.
-
- There is normally no need to manipulate the socket tqdevice directly
- since this class does all the necessary setup for most client or
- server socket applications.
-*/
-TQSocketDevice *TQServerSocket::socketDevice()
-{
- if ( !d )
- return 0;
-
- return d->s;
-}
-
-
-/*!
- Sets the socket to use \a socket. bind() and listen() should
- already have been called for \a socket.
-
- This allows us to use the TQServerSocket class as a wrapper for
- other socket types (e.g. Unix Domain Sockets).
-*/
-void TQServerSocket::setSocket( int socket )
-{
- delete d;
- d = new TQServerSocketPrivate;
- d->s = new TQSocketDevice( socket, TQSocketDevice::Stream );
- d->n = new TQSocketNotifier( d->s->socket(), TQSocketNotifier::Read,
- this, "accepting new connections" );
- connect( d->n, TQT_SIGNAL(activated(int)),
- this, TQT_SLOT(incomingConnection(int)) );
-}
-
-#endif //TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/network/tqserversocket.h b/tqtinterface/qt4/src/network/tqserversocket.h
deleted file mode 100644
index d1f4a83..0000000
--- a/tqtinterface/qt4/src/network/tqserversocket.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Definition of TQServerSocketClass.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQSERVERSOCKET_H
-#define TQSERVERSOCKET_H
-
-#ifndef TQT_H
-#include "tqobject.h"
-#include "tqhostaddress.h"
-#include "tqsocketdevice.h" // ### remove or keep for users' convenience?
-#endif // TQT_H
-#ifndef TQT_NO_NETWORK
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_NETWORK
-#else
-#define TQM_EXPORT_NETWORK TQ_EXPORT
-#endif
-
-class TQServerSocketPrivate;
-
-
-class TQM_EXPORT_NETWORK TQServerSocket : public TQObject
-{
- Q_OBJECT
- TQ_OBJECT
-public:
- TQServerSocket( TQ_UINT16 port, int backlog = 1,
- TQObject *parent=0, const char *name=0 );
- TQServerSocket( const TQHostAddress & address, TQ_UINT16 port, int backlog = 1,
- TQObject *parent=0, const char *name=0 );
- TQServerSocket( TQObject *parent=0, const char *name=0 );
- virtual ~TQServerSocket();
-
- bool ok() const;
-
- TQ_UINT16 port() const ;
-
- int socket() const ;
- virtual void setSocket( int socket );
-
- TQHostAddress address() const ;
-
- virtual void newConnection( int socket ) = 0;
-
-protected:
- TQSocketDevice *socketDevice();
-
-private Q_SLOTS:
- void incomingConnection( int socket );
-
-private:
- TQServerSocketPrivate *d;
- void init( const TQHostAddress & address, TQ_UINT16 port, int backlog );
-};
-
-#endif // TQT_NO_NETWORK
-#endif // TQSERVERSOCKET_H
diff --git a/tqtinterface/qt4/src/network/tqsocket.cpp b/tqtinterface/qt4/src/network/tqsocket.cpp
deleted file mode 100644
index 8e4d40a..0000000
--- a/tqtinterface/qt4/src/network/tqsocket.cpp
+++ /dev/null
@@ -1,1668 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQSocket class.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqsocket.h"
-#ifndef TQT_NO_NETWORK
-#include "tqptrlist.h"
-#include "tqtimer.h"
-#include "tqsocketdevice.h"
-#include "tqdns.h"
-#include "private/tqinternal_p.h"
-
-#include <string.h>
-#ifndef NO_ERRNO_H
-#include <errno.h>
-#endif
-
-//#define TQSOCKET_DEBUG
-
-/*
- Perhaps this private functionality needs to be refactored.
-
- Comment from Robert D Gatlin (Intel):
-
- It would be nice to have the functionality inherent in TQSocket available
- as a separate class as a standard part of the TQt library, something along
- the line of:
-
- class TQByteBuffer : public TQIODevice { ... }
-
- The same class could/would be used within TQSocket for the Read/Write
- buffers.
-
- The above class could be used in the following way(s):
-
- buffer.open( IO_WriteOnly | IO_Append );
- buffer.writeBlock( a ); // a = TQByteArray
- buffer.close();
-
- TQByteArray b;
- b.resize( buffer.size() );
- buffer.open( IO_ReadOnly );
- buffer.readBlock( b.data(), b.size() );
- buffer.close();
-
- But would also be useable with TQDataStream (via TQIODevice) with:
-
- buffer.open( IO_WriteOnly | IO_Append );
- TQDataStream is( &buffer );
- is << 100;
- buffer.close();
-
- buffer.open( IO_ReadOnly );
- TQDataStream os( &buffer );
- TQ_UINT32 x;
- os >> x;
- buffer.close();
-
- The real usefulness is with any situations where data (TQByteArray) arrives
- incrementally (as in TQSocket and filter case above).
-
- I tried using TQBuffer, but TQBuffer does not trim bytes from the front of
- the buffer in cases like:
-
- TQBuffer buf;
- buf.open( IO_ReadOnly );
- TQDataStream ds( &buf );
- TQ_INT32 x;
- ds >> x;
- buf.close();
-
- In the above case, buf.size() will be identical before and after the
- operation with TQDataStream. Based on the implementation of TQBuffer, it
- does not appear well suited for this kind of operation.
-*/
-
-// Private class for TQSocket
-
-class TQSocketPrivate {
-public:
- TQSocketPrivate();
- ~TQSocketPrivate();
- void closeSocket();
- void close();
- void connectionClosed();
- void setSocketDevice( TQSocket *q, TQSocketDevice *tqdevice );
-
- TQSocket::State state; // connection state
- TQString host; // host name
- TQ_UINT16 port; // host port
- TQSocketDevice *socket; // connection socket
- TQSocketNotifier *rsn, *wsn; // socket notifiers
- TQMembuf rba; // read buffer
- TQ_ULONG readBufferSize; // limit for the read buffer size
- TQPtrList<TQByteArray> wba; // list of write bufs
- TQHostAddress addr; // connection address
- TQValueList<TQHostAddress> addresses; // alternatives looked up
- TQIODevice::Offset wsize; // write total buf size
- TQIODevice::Offset windex; // write index
-#ifndef TQT_NO_DNS
- TQDns *dns4;
- TQDns *dns6;
-#endif
- static TQPtrList<TQSocket> sn_read_alreadyCalled; // used to avoid unwanted recursion
- TQValueList<TQHostAddress> l4;
- TQValueList<TQHostAddress> l6;
-};
-
-TQPtrList<TQSocket> TQSocketPrivate::sn_read_alreadyCalled;
-
-TQSocketPrivate::TQSocketPrivate()
- : state(TQSocket::Idle), host(TQString::tqfromLatin1("")), port(0),
- socket(0), rsn(0), wsn(0), readBufferSize(0), wsize(0), windex(0)
-{
-#ifndef TQT_NO_DNS
- dns4 = 0;
- dns6 = 0;
-#endif
- wba.setAutoDelete( TRUE );
-}
-
-TQSocketPrivate::~TQSocketPrivate()
-{
- close();
- delete socket;
-#ifndef TQT_NO_DNS
- delete dns4;
- delete dns6;
-#endif
-}
-
-void TQSocketPrivate::closeSocket()
-{
- // Order is important here - the socket notifiers must go away
- // before the socket does, otherwise libc or the kernel will
- // become unhappy.
- delete rsn;
- rsn = 0;
- delete wsn;
- wsn = 0;
- if ( socket )
- socket->close();
-}
-
-void TQSocketPrivate::close()
-{
- closeSocket();
- wsize = 0;
- rba.clear(); wba.clear();
- windex = 0;
-}
-
-void TQSocketPrivate::connectionClosed()
-{
- // We keep the open state in case there's unread incoming data
- state = TQSocket::Idle;
- closeSocket();
- wba.clear();
- windex = wsize = 0;
-}
-
-void TQSocketPrivate::setSocketDevice( TQSocket *q, TQSocketDevice *tqdevice )
-{
- delete socket;
- delete rsn;
- delete wsn;
-
- if ( tqdevice ) {
- socket = tqdevice;
- } else {
- socket = new TQSocketDevice( TQSocketDevice::Stream,
- ( addr.isIPv4Address() ?
- TQSocketDevice::IPv4 :
- TQSocketDevice::IPv6 ), 0 );
- socket->setBlocking( FALSE );
- socket->setAddressReusable( TRUE );
- }
-
- rsn = new TQSocketNotifier( socket->socket(),
- TQSocketNotifier::Read, TQT_TQOBJECT(q), "read" );
- wsn = new TQSocketNotifier( socket->socket(),
- TQSocketNotifier::Write, TQT_TQOBJECT(q), "write" );
-
- TQObject::connect( rsn, TQT_SIGNAL(activated(int)), q, TQT_SLOT(sn_read()) );
- rsn->setEnabled( FALSE );
- TQObject::connect( wsn, TQT_SIGNAL(activated(int)), q, TQT_SLOT(sn_write()) );
- wsn->setEnabled( FALSE );
-}
-
-/*!
- \class TQSocket tqsocket.h
- \brief The TQSocket class provides a buffered TCP connection.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- It provides a totally non-blocking TQIODevice, and modifies and
- extends the API of TQIODevice with socket-specific code.
-
- Note that a TQApplication must have been constructed before this
- class can be used.
-
- The functions you're likely to call most are connectToHost(),
- bytesAvailable(), canReadLine() and the ones it inherits from
- TQIODevice.
-
- connectToHost() is the most-used function. As its name implies,
- it opens a connection to a named host.
-
- Most network protocols are either packet-oriented or
- line-oriented. canReadLine() indicates whether a connection
- contains an entire unread line or not, and bytesAvailable()
- returns the number of bytes available for reading.
-
- The Q_SIGNALS error(), connected(), readyRead() and
- connectionClosed() inform you of the progress of the connection.
- There are also some less commonly used Q_SIGNALS. hostFound() is
- emitted when connectToHost() has finished its DNS lookup and is
- starting its TCP connection. delayedCloseFinished() is emitted
- when close() succeeds. bytesWritten() is emitted when TQSocket
- moves data from its "to be written" queue into the TCP
- implementation.
-
- There are several access functions for the socket: state() returns
- whether the object is idle, is doing a DNS lookup, is connecting,
- has an operational connection, etc. address() and port() return
- the IP address and port used for the connection. The peerAddress()
- and peerPort() functions return the IP address and port used by
- the peer, and peerName() returns the name of the peer (normally
- the name that was passed to connectToHost()). socketDevice()
- returns a pointer to the TQSocketDevice used for this socket.
-
- TQSocket inherits TQIODevice, and reimplements some functions. In
- general, you can treat it as a TQIODevice for writing, and mostly
- also for reading. The match isn't perfect, since the TQIODevice
- API is designed for tqdevices that are controlled by the same
- machine, and an asynchronous peer-to-peer network connection isn't
- quite like that. For example, there is nothing that matches
- TQIODevice::size() exactly. The documentation for open(), close(),
- flush(), size(), at(), atEnd(), readBlock(), writeBlock(),
- getch(), putch(), ungetch() and readLine() describes the
- differences in detail.
-
- \warning TQSocket is not suitable for use in threads. If you need
- to uses sockets in threads use the lower-level TQSocketDevice class.
-
- \warning Because TQt doesn't use the native socketstream
- implementation on Mac OS X, TQSocket has an implicit transfer
- latency of 100ms. You can achieve lower latency on Mac OS X by
- using TQSocketDevice instead.
-
- \sa TQSocketDevice, TQHostAddress, TQSocketNotifier
-*/
-
-#ifdef USE_QT4
-
-/*!
- Reads \a maxlen bytes from the socket into \a data and returns the
- number of bytes read. Returns -1 if an error occurred.
-*/
-
-qint64 TQSocket::readData( char *data, qint64 maxlen )
-{
- if ( data == 0 && maxlen != 0 ) {
-#if defined(QT_CHECK_NULL)
- qWarning( "TQSocket::readBlock: Null pointer error" );
-#endif
- return -1;
- }
- if ( !isOpen() ) {
-#if defined(QT_CHECK_STATE)
- qWarning( "TQSocket::readBlock: Socket is not open" );
-#endif
- return -1;
- }
- if ( maxlen >= d->rba.size() )
- maxlen = d->rba.size();
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): readBlock %d bytes", name(), (int)maxlen );
-#endif
- d->rba.consumeBytes( maxlen, data );
- // After we read data from our internal buffer, if we use the
- // setReadBufferSize() to limit our buffer, we might now be able to
- // read more data in our buffer. So enable the read socket notifier,
- // but do this only if we are not in a slot connected to the
- // readyRead() signal since this might cause a bad recursive behavior.
- // We can test for this condition by looking at the
- // sn_read_alreadyCalled flag.
- if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
- d->rsn->setEnabled( true );
- return maxlen;
-}
-
-
-/*!
- Writes \a len bytes to the socket from \a data and returns the
- number of bytes written. Returns -1 if an error occurred.
-*/
-
-qint64 TQSocket::writeData( const char *data, qint64 len )
-{
-#if defined(QT_CHECK_NULL)
- if ( data == 0 && len != 0 ) {
- qWarning( "TQSocket::writeBlock: Null pointer error" );
- }
-#endif
-#if defined(QT_CHECK_STATE)
- if ( !isOpen() ) {
- qWarning( "TQSocket::writeBlock: Socket is not open" );
- return -1;
- }
-#endif
-#if defined(QT_CHECK_STATE)
- if ( d->state == Closing ) {
- qWarning( "TQSocket::writeBlock: Cannot write, socket is closing" );
- }
-#endif
- if ( len == 0 || d->state == Closing || d->state == Idle )
- return 0;
- TQByteArray *a = d->wba.last();
-
- // next bit is sensitive. if we're writing really small chunks,
- // try to buffer up since system calls are expensive, and nagle's
- // algorithm is even more expensive. but if anything even
- // remotely large is being written, try to issue a write at once.
-
- bool writeNow = ( d->wsize + len >= 1400 || len > 512 );
-
- if ( a && a->size() + len < 128 ) {
- // small buffer, resize
- int i = a->size();
- a->resize( i+len );
- memcpy( a->data()+i, data, len );
- } else {
- // append new buffer
- a = new TQByteArray( len );
- memcpy( a->data(), data, len );
- d->wba.append( a );
- }
- d->wsize += len;
- if ( writeNow )
- flush();
- else if ( d->wsn )
- d->wsn->setEnabled( true );
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): writeBlock %d bytes", name(), (int)len );
-#endif
- return len;
-}
-
-#endif // USE_QT4
-
-
-/*!
- Creates a TQSocket object in \c TQSocket::Idle state.
-
- The \a parent and \a name arguments are passed on to the TQObject
- constructor.
-
- Note that a TQApplication must have been constructed before sockets
- can be used.
-*/
-
-TQSocket::TQSocket( TQObject *parent, const char *name )
-#ifdef USE_QT4
- : TQIODevice()
-#else // USE_QT4
- : TQObject( parent, name )
-#endif // USE_QT4
-{
-#ifdef USE_QT4
- setParent(parent);
- setObjectName(name);
-#endif // USE_QT4
- d = new TQSocketPrivate;
- setSocketDevice( 0 );
- setFlags( IO_Direct );
- resetqStatus();
-}
-
-
-/*!
- Destroys the socket. Closes the connection if necessary.
-
- \sa close()
-*/
-
-TQSocket::~TQSocket()
-{
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): Destroy", name() );
-#endif
- if ( state() != Idle )
- close();
- TQ_ASSERT( d != 0 );
- delete d;
-}
-
-
-/*!
- Returns a pointer to the internal socket tqdevice.
-
- There is normally no need to manipulate the socket tqdevice directly
- since this class does the necessary setup for most applications.
-*/
-
-TQSocketDevice *TQSocket::socketDevice()
-{
- return d->socket;
-}
-
-/*!
- Sets the internal socket tqdevice to \a tqdevice. Passing a \a tqdevice
- of 0 will cause the internal socket tqdevice to be used. Any
- existing connection will be disconnected before using the new \a
- tqdevice.
-
- The new tqdevice should not be connected before being associated
- with a TQSocket; after setting the socket call connectToHost() to
- make the connection.
-
- This function is useful if you need to subclass TQSocketDevice and
- want to use the TQSocket API, for example, to implement Unix domain
- sockets.
-*/
-
-void TQSocket::setSocketDevice( TQSocketDevice *tqdevice )
-{
- if ( state() != Idle )
- close();
- d->setSocketDevice( this, tqdevice );
-}
-
-/*!
- \enum TQSocket::State
-
- This enum defines the connection states:
-
- \value Idle if there is no connection
- \value HostLookup during a DNS lookup
- \value Connecting during TCP connection establishment
- \value Connected when there is an operational connection
- \value Closing if the socket is closing down, but is not yet closed.
-*/
-
-/*!
- Returns the current state of the socket connection.
-
- \sa TQSocket::State
-*/
-
-TQSocket::State TQSocket::state() const
-{
- return d->state;
-}
-
-
-#ifndef TQT_NO_DNS
-
-/*!
- Attempts to make a connection to \a host on the specified \a port
- and return immediately.
-
- Any connection or pending connection is closed immediately, and
- TQSocket goes into the \c HostLookup state. When the lookup
- succeeds, it emits hostFound(), starts a TCP connection and goes
- into the \c Connecting state. Finally, when the connection
- succeeds, it emits connected() and goes into the \c Connected
- state. If there is an error at any point, it emits error().
-
- \a host may be an IP address in string form, or it may be a DNS
- name. TQSocket will do a normal DNS lookup if required. Note that
- \a port is in native byte order, unlike some other libraries.
-
- \sa state()
-*/
-
-void TQSocket::connectToHost( const TQString &host, TQ_UINT16 port )
-{
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s)::connectToHost: host %s, port %d",
- name(), host.ascii(), port );
-#endif
- setSocketIntern( -1 );
- d->state = HostLookup;
- d->host = host;
- d->port = port;
- d->dns4 = new TQDns( host, TQDns::A );
- d->dns6 = new TQDns( host, TQDns::Aaaa );
-
- // try if the address is already available (for faster connecting...)
- tryConnecting();
- if ( d->state == HostLookup ) {
- connect( d->dns4, TQT_SIGNAL(resultsReady()),
- this, TQT_SLOT(tryConnecting()) );
- connect( d->dns6, TQT_SIGNAL(resultsReady()),
- this, TQT_SLOT(tryConnecting()) );
- }
-}
-
-#endif
-
-
-/*!
- This private Q_SLOTS continues the connection process where
- connectToHost() leaves off.
-*/
-
-void TQSocket::tryConnecting()
-{
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s)::tryConnecting()", name() );
-#endif
- // ### this ifdef isn't correct - addresses() also does /etc/hosts and
- // numeric-address-as-string handling.
-#ifndef TQT_NO_DNS
-
- if ( d->dns4 ) {
- d->l4 = d->dns4->addresses();
- if ( !d->l4.isEmpty() || !d->dns4->isWorking() ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s)::tryConnecting: host %s, port %d: "
- "%d IPv4 addresses",
- name(), d->host.ascii(), d->port, d->l4.count() );
-#endif
- delete d->dns4;
- d->dns4 = 0;
- }
- }
-
- if ( d->dns6 ) {
- d->l6 = d->dns6->addresses();
- if ( !d->l6.isEmpty() || !d->dns6->isWorking() ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s)::tryConnecting: host %s, port %d: "
- "%d IPv6 addresses",
- name(), d->host.ascii(), d->port, d->l6.count() );
-#endif
- delete d->dns6;
- d->dns6 = 0;
- }
- }
-
- if ( d->state == HostLookup ) {
- if ( d->l4.isEmpty() && d->l6.isEmpty() &&
- !d->dns4 && !d->dns6 ) {
- // no results and we're not still looking: give up
- d->state = Idle;
- emit error( ErrHostNotFound );
- return;
- }
- if ( d->l4.isEmpty() && d->l6.isEmpty() ) {
- // no results (yet): try again later
- return;
- }
-
- // we've found something. press on with that. if we later find
- // more, fine.
- emit hostFound();
- d->state = Connecting;
- }
-
- if ( d->state == Connecting ) {
- d->addresses += d->l4;
- d->addresses += d->l6;
- d->l4.clear();
- d->l6.clear();
-
- // try one address at a time, falling back to the next one if
- // there is a connection failure. (should also support a timeout,
- // or do multiple TCP-level connects at a time, with staggered
- // starts to avoid bandwidth waste and cause fewer
- // "connect-and-abort" errors. but that later.)
- bool stuck = TRUE;
- while( stuck ) {
- stuck = FALSE;
- if ( d->socket &&
- d->socket->connect( d->addr, d->port ) == FALSE ) {
- if ( d->socket->error() == TQSocketDevice::NoError ) {
- if ( d->wsn )
- d->wsn->setEnabled( TRUE );
- return; // not serious, try again later
- }
-
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s)::tryConnecting: "
- "Gave up on IP address %s",
- name(), d->socket->peerAddress().toString().ascii() );
-#endif
- delete d->wsn;
- d->wsn = 0;
- delete d->rsn;
- d->rsn = 0;
- delete d->socket;
- d->socket = 0;
-
- if(d->addresses.isEmpty()) {
- emit error( ErrConnectionRefused );
- return;
- }
- }
- // if the host has more addresses, try another some.
- if ( d->socket == 0 && !d->addresses.isEmpty() ) {
- d->addr = *d->addresses.begin();
- d->addresses.remove( d->addresses.begin() );
- d->setSocketDevice( this, 0 );
- stuck = TRUE;
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s)::tryConnecting: Trying IP address %s",
- name(), d->addr.toString().ascii() );
-#endif
- }
- };
-
- // The socket write notifier will fire when the connection succeeds
- if ( d->wsn )
- d->wsn->setEnabled( TRUE );
- }
-#endif
-}
-
-/*!
- \enum TQSocket::Error
-
- This enum specifies the possible errors:
- \value ErrConnectionRefused if the connection was refused
- \value ErrHostNotFound if the host was not found
- \value ErrSocketRead if a read from the socket failed
-*/
-
-/*!
- \fn void TQSocket::error( int )
-
- This signal is emitted after an error occurred. The parameter is
- the \l Error value.
-*/
-
-/*!
- \fn void TQSocket::hostFound()
-
- This signal is emitted after connectToHost() has been called and
- the host lookup has succeeded.
-
- \sa connected()
-*/
-
-
-/*!
- \fn void TQSocket::connected()
-
- This signal is emitted after connectToHost() has been called and a
- connection has been successfully established.
-
- \sa connectToHost(), connectionClosed()
-*/
-
-
-/*!
- \fn void TQSocket::connectionClosed()
-
- This signal is emitted when the other end has closed the
- connection. The read buffers may contain buffered input data which
- you can read after the connection was closed.
-
- \sa connectToHost(), close()
-*/
-
-
-/*!
- \fn void TQSocket::delayedCloseFinished()
-
- This signal is emitted when a delayed close is finished.
-
- If you call close() and there is buffered output data to be
- written, TQSocket goes into the \c TQSocket::Closing state and
- returns immediately. It will then keep writing to the socket until
- all the data has been written. Then, the delayedCloseFinished()
- signal is emitted.
-
- \sa close()
-*/
-
-
-/*!
- \fn void TQSocket::readyRead()
-
- This signal is emitted every time there is new incoming data.
-
- Bear in mind that new incoming data is only reported once; if you do not
- read all the data, this class buffers the data and you can read it later,
- but no signal is emitted unless new data arrives. A good practice is to
- read all data in the slot connected to this signal unless you are sure that
- you need to receive more data to be able to process it.
-
- \sa readBlock(), readLine(), bytesAvailable()
-*/
-
-
-/*!
- \fn void TQSocket::bytesWritten( int nbytes )
-
- This signal is emitted when data has been written to the network.
- The \a nbytes parameter specifies how many bytes were written.
-
- The bytesToWrite() function is often used in the same context; it
- indicates how many buffered bytes there are left to write.
-
- \sa writeBlock(), bytesToWrite()
-*/
-
-
-/*!
- Opens the socket using the specified TQIODevice file mode \a m.
- This function is called automatically when needed and you should
- not call it yourself.
-
- \sa close()
-*/
-
-bool TQSocket::open( int m )
-{
- if ( isOpen() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQSocket::open: Already open" );
-#endif
- return FALSE;
- }
- TQIODevice::setMode( m & IO_ReadWrite );
- setState( IO_Open );
- return TRUE;
-}
-
-
-/*!
- Closes the socket.
-
- The read buffer is cleared.
-
- If the output buffer is empty, the state is set to \c
- TQSocket::Idle and the connection is terminated immediately. If the
- output buffer still contains data to be written, TQSocket goes into
- the \c TQSocket::Closing state and the rest of the data will be
- written. When all of the outgoing data have been written, the
- state is set to \c TQSocket::Idle and the connection is terminated.
- At this point, the delayedCloseFinished() signal is emitted.
-
- If you don't want that the data of the output buffer is written, call
- clearPendingData() before you call close().
-
- \sa state(), bytesToWrite() clearPendingData()
-*/
-
-void TQSocket::close()
-{
- if ( !isOpen() || d->state == Idle ) // already closed
- return;
- if ( d->state == Closing )
- return;
- if ( !d->rsn || !d->wsn )
- return;
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): close socket", name() );
-#endif
- if ( d->socket && d->wsize ) { // there's data to be written
- d->state = Closing;
- if ( d->rsn )
- d->rsn->setEnabled( FALSE );
- if ( d->wsn )
- d->wsn->setEnabled( TRUE );
- d->rba.clear(); // clear incoming data
- return;
- }
- setFlags( IO_Sequential );
- resetqStatus();
- setState( 0 );
- d->close();
- d->state = Idle;
-}
-
-
-/*!
- This function consumes \a nbytes bytes of data from the write
- buffer.
-*/
-
-bool TQSocket::consumeWriteBuf( TQ_ULONG nbytes )
-{
- if ( nbytes <= 0 || nbytes > d->wsize )
- return FALSE;
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): skipWriteBuf %d bytes", name(), (int)nbytes );
-#endif
- d->wsize -= nbytes;
- for ( ;; ) {
- TQByteArray *a = d->wba.first();
- if ( d->windex + nbytes >= a->size() ) {
- nbytes -= a->size() - d->windex;
- d->wba.remove();
- d->windex = 0;
- if ( nbytes == 0 )
- break;
- } else {
- d->windex += nbytes;
- break;
- }
- }
- return TRUE;
-}
-
-
-
-/*!
- Implementation of the abstract virtual TQIODevice::flush() function.
-*/
-
-void TQSocket::flush()
-{
- if ( !d->socket )
- return;
- bool osBufferFull = FALSE;
- int consumed = 0;
- while ( !osBufferFull && d->state >= Connecting && d->wsize > 0 ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): flush: Write data to the socket", name() );
-#endif
- TQByteArray *a = d->wba.first();
- int nwritten;
- int i = 0;
- if ( (int)a->size() - d->windex < 1460 ) {
- // Concatenate many smaller blocks. the first may be
- // partial, but each subsequent block is copied entirely
- // or not at all. the sizes here are picked so that we
- // generally won't trigger nagle's algorithm in the tcp
- // implementation: we concatenate if we'd otherwise send
- // less than PMTU bytes (we assume PMTU is 1460 bytes),
- // and concatenate up to the largest payload TCP/IP can
- // carry. with these precautions, nagle's algorithm
- // should apply only when really appropriate.
- TQByteArray out( 65536 );
- int j = d->windex;
- int s = a->size() - j;
- while ( a && i+s < (int)out.size() ) {
- memcpy( out.data()+i, a->data()+j, s );
- j = 0;
- i += s;
- a = d->wba.next();
- s = a ? a->size() : 0;
- }
- nwritten = d->socket->writeBlock( out.data(), i );
- if ( d->wsn )
- d->wsn->setEnabled( FALSE ); // the TQSocketNotifier documentation says so
- } else {
- // Big block, write it immediately
- i = a->size() - d->windex;
- nwritten = d->socket->writeBlock( a->data() + d->windex, i );
- if ( d->wsn )
- d->wsn->setEnabled( FALSE ); // the TQSocketNotifier documentation says so
- }
- if ( nwritten > 0 ) {
- if ( consumeWriteBuf( nwritten ) )
- consumed += nwritten;
- }
- if ( nwritten < i )
- osBufferFull = TRUE;
- }
- if ( consumed > 0 ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): flush: wrote %d bytes, %d left",
- name(), consumed, (int)d->wsize );
-#endif
- emit bytesWritten( consumed );
- }
- if ( d->state == Closing && d->wsize == 0 ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): flush: Delayed close done. Terminating.",
- name() );
-#endif
- setFlags( IO_Sequential );
- resetqStatus();
- setState( 0 );
- d->close();
- d->state = Idle;
- emit delayedCloseFinished();
- return;
- }
- if ( !d->socket->isOpen() ) {
- d->connectionClosed();
- emit connectionClosed();
- return;
- }
- if ( d->wsn )
- d->wsn->setEnabled( d->wsize > 0 ); // write if there's data
-}
-
-
-/*!
- Returns the number of incoming bytes that can be read right now
- (like bytesAvailable()).
-*/
-
-#ifdef USE_QT4
-qint64 TQSocket::size() const
-#else // USE_QT4
-TQIODevice::Offset TQSocket::size() const
-#endif // USE_QT4
-{
- return (Offset)bytesAvailable();
-}
-
-
-/*!
- Returns the current read index. Since TQSocket is a sequential
- tqdevice, the current read index is always zero.
-*/
-
-#ifdef USE_QT4
-qint64 TQSocket::at() const
-#else // USE_QT4
-TQIODevice::Offset TQSocket::at() const
-#endif // USE_QT4
-{
- return 0;
-}
-
-
-/*!
- \overload
-
- Moves the read index forward to \a index and returns TRUE if the
- operation was successful; otherwise returns FALSE. Moving the
- index forward means skipping incoming data.
-*/
-
-bool TQSocket::at( Offset index )
-{
- if ( index > d->rba.size() )
- return FALSE;
- d->rba.consumeBytes( (TQ_ULONG)index, 0 ); // throw away data 0..index-1
- // After we read data from our internal buffer, if we use the
- // setReadBufferSize() to limit our buffer, we might now be able to
- // read more data in our buffer. So enable the read socket notifier,
- // but do this only if we are not in a slot connected to the
- // readyRead() signal since this might cause a bad recursive behavior.
- // We can test for this condition by looking at the
- // sn_read_alreadyCalled flag.
- if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
- d->rsn->setEnabled( TRUE );
- return TRUE;
-}
-
-
-/*!
- Returns TRUE if there is no more data to read; otherwise returns FALSE.
-*/
-
-bool TQSocket::atEnd() const
-{
- if ( d->socket == 0 )
- return TRUE;
- TQSocket * that = (TQSocket *)this;
- if ( that->d->socket->bytesAvailable() ) // a little slow, perhaps...
- that->sn_read();
- return that->d->rba.size() == 0;
-}
-
-
-/*!
- Returns the number of incoming bytes that can be read, i.e. the
- size of the input buffer. Equivalent to size().
-
- This function can trigger the readyRead() signal, if more data has
- arrived on the socket.
-
- \sa bytesToWrite()
-*/
-
-#ifdef USE_QT4
-qint64 TQSocket::bytesAvailable() const
-#else // USE_QT4
-TQ_ULONG TQSocket::bytesAvailable() const
-#endif // USE_QT4
-{
- if ( d->socket == 0 )
- return 0;
- TQSocket * that = (TQSocket *)this;
- if ( that->d->socket->bytesAvailable() ) // a little slow, perhaps...
- (void)that->sn_read();
- return that->d->rba.size();
-}
-
-
-/*!
- Wait up to \a msecs milliseconds for more data to be available.
-
- If \a msecs is -1 the call will block indefinitely.
-
- Returns the number of bytes available.
-
- If \a timeout is non-null and no error occurred (i.e. it does not
- return -1): this function sets \a *timeout to TRUE, if the reason
- for returning was that the timeout was reached; otherwise it sets
- \a *timeout to FALSE. This is useful to find out if the peer
- closed the connection.
-
- \warning This is a blocking call and should be avoided in event
- driven applications.
-
- \sa bytesAvailable()
-*/
-
-TQ_ULONG TQSocket::waitForMore( int msecs, bool *timeout ) const
-{
- if ( d->socket == 0 )
- return 0;
- TQSocket * that = (TQSocket *)this;
- if ( that->d->socket->waitForMore( msecs, timeout ) > 0 )
- (void)that->sn_read( TRUE );
- return that->d->rba.size();
-}
-
-/*! \overload
-*/
-
-TQ_ULONG TQSocket::waitForMore( int msecs ) const
-{
- return waitForMore( msecs, 0 );
-}
-
-/*!
- Returns the number of bytes that are waiting to be written, i.e.
- the size of the output buffer.
-
- \sa bytesAvailable() clearPendingData()
-*/
-
-#ifdef USE_QT4
-qint64 TQSocket::bytesToWrite() const
-#else // USE_QT4
-TQ_ULONG TQSocket::bytesToWrite() const
-#endif // USE_QT4
-{
- return d->wsize;
-}
-
-/*!
- Deletes the data that is waiting to be written. This is useful if you want
- to close the socket without waiting for all the data to be written.
-
- \sa bytesToWrite() close() delayedCloseFinished()
-*/
-
-void TQSocket::clearPendingData()
-{
- d->wba.clear();
- d->windex = d->wsize = 0;
-}
-
-/*!
- Reads \a maxlen bytes from the socket into \a data and returns the
- number of bytes read. Returns -1 if an error occurred.
-*/
-
-TQ_LONG TQSocket::readBlock( char *data, TQ_ULONG maxlen )
-{
- if ( data == 0 && maxlen != 0 ) {
-#if defined(TQT_CHECK_NULL)
- qWarning( "TQSocket::readBlock: Null pointer error" );
-#endif
- return -1;
- }
- if ( !isOpen() ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQSocket::readBlock: Socket is not open" );
-#endif
- return -1;
- }
- if ( maxlen >= d->rba.size() )
- maxlen = d->rba.size();
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): readBlock %d bytes", name(), (int)maxlen );
-#endif
- d->rba.consumeBytes( maxlen, data );
- // After we read data from our internal buffer, if we use the
- // setReadBufferSize() to limit our buffer, we might now be able to
- // read more data in our buffer. So enable the read socket notifier,
- // but do this only if we are not in a slot connected to the
- // readyRead() signal since this might cause a bad recursive behavior.
- // We can test for this condition by looking at the
- // sn_read_alreadyCalled flag.
- if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
- d->rsn->setEnabled( TRUE );
- return maxlen;
-}
-
-
-/*!
- Writes \a len bytes to the socket from \a data and returns the
- number of bytes written. Returns -1 if an error occurred.
-*/
-
-TQ_LONG TQSocket::writeBlock( const char *data, TQ_ULONG len )
-{
-#if defined(TQT_CHECK_NULL)
- if ( data == 0 && len != 0 ) {
- qWarning( "TQSocket::writeBlock: Null pointer error" );
- }
-#endif
-#if defined(TQT_CHECK_STATE)
- if ( !isOpen() ) {
- qWarning( "TQSocket::writeBlock: Socket is not open" );
- return -1;
- }
-#endif
-#if defined(TQT_CHECK_STATE)
- if ( d->state == Closing ) {
- qWarning( "TQSocket::writeBlock: Cannot write, socket is closing" );
- }
-#endif
- if ( len == 0 || d->state == Closing || d->state == Idle )
- return 0;
- TQByteArray *a = d->wba.last();
-
- // next bit is sensitive. if we're writing really small chunks,
- // try to buffer up since system calls are expensive, and nagle's
- // algorithm is even more expensive. but if anything even
- // remotely large is being written, try to issue a write at once.
-
- bool writeNow = ( d->wsize + len >= 1400 || len > 512 );
-
- if ( a && a->size() + len < 128 ) {
- // small buffer, resize
- int i = a->size();
- a->resize( i+len );
- memcpy( a->data()+i, data, len );
- } else {
- // append new buffer
- a = new TQByteArray( len );
- memcpy( a->data(), data, len );
- d->wba.append( a );
- }
- d->wsize += len;
- if ( writeNow )
- flush();
- else if ( d->wsn )
- d->wsn->setEnabled( TRUE );
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): writeBlock %d bytes", name(), (int)len );
-#endif
- return len;
-}
-
-
-/*!
- Reads a single byte/character from the internal read buffer.
- Returns the byte/character read, or -1 if there is nothing to be
- read.
-
- \sa bytesAvailable(), putch()
-*/
-
-int TQSocket::getch()
-{
- if ( isOpen() && d->rba.size() > 0 ) {
- uchar c;
- d->rba.consumeBytes( 1, (char*)&c );
- // After we read data from our internal buffer, if we use the
- // setReadBufferSize() to limit our buffer, we might now be able to
- // read more data in our buffer. So enable the read socket notifier,
- // but do this only if we are not in a slot connected to the
- // readyRead() signal since this might cause a bad recursive behavior.
- // We can test for this condition by looking at the
- // sn_read_alreadyCalled flag.
- if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )
- d->rsn->setEnabled( TRUE );
- return c;
- }
- return -1;
-}
-
-
-/*!
- Writes the character \a ch to the output buffer.
-
- Returns \a ch, or -1 if an error occurred.
-
- \sa getch()
-*/
-
-int TQSocket::putch( int ch )
-{
- char buf[2];
- buf[0] = ch;
- return writeBlock(buf, 1) == 1 ? ch : -1;
-}
-
-
-/*!
- This implementation of the virtual function TQIODevice::ungetch()
- prepends the character \a ch to the read buffer so that the next
- read returns this character as the first character of the output.
-*/
-
-int TQSocket::ungetch( int ch )
-{
-#if defined(TQT_CHECK_STATE)
- if ( !isOpen() ) {
- qWarning( "TQSocket::ungetch: Socket not open" );
- return -1;
- }
-#endif
- return d->rba.ungetch( ch );
-}
-
-
-/*!
- Returns TRUE if it's possible to read an entire line of text from
- this socket at this time; otherwise returns FALSE.
-
- Note that if the peer closes the connection unexpectedly, this
- function returns FALSE. This means that loops such as this won't
- work:
-
- \code
- while( !socket->canReadLine() ) // WRONG
- ;
- \endcode
-
- \sa readLine()
-*/
-
-bool TQSocket::canReadLine() const
-{
- if ( ((TQSocket*)this)->d->rba.scanNewline( 0 ) )
- return TRUE;
- return ( bytesAvailable() > 0 &&
- ((TQSocket*)this)->d->rba.scanNewline( 0 ) );
-}
-
-/*!
- \reimp
- \internal
- So that it's not hidden by our other readLine().
-*/
-TQ_LONG TQSocket::readLine( char *data, TQ_ULONG maxlen )
-{
- return TQIODevice::readLine(data,maxlen);
-}
-
-/*!
- Returns a line of text including a terminating newline character
- (\n). Returns "" if canReadLine() returns FALSE.
-
- \sa canReadLine()
-*/
-
-TQString TQSocket::readLine()
-{
- TQByteArray a(256);
- bool nl = d->rba.scanNewline( &a );
- TQString s;
- if ( nl ) {
- at( a.size() ); // skips the data read
- s = TQString( a );
- }
- return s;
-}
-
-/*!
- \internal
- Internal slot for handling socket read notifications.
-
- This function has can usually only be entered once (i.e. no
- recursive calls). If the argument \a force is TRUE, the function
- is executed, but no readyRead() Q_SIGNALS are emitted. This
- behaviour is useful for the waitForMore() function, so that it is
- possible to call waitForMore() in a slot connected to the
- readyRead() signal.
-*/
-
-void TQSocket::sn_read( bool force )
-{
- TQ_LONG maxToRead = 0;
- if ( d->readBufferSize > 0 ) {
- maxToRead = d->readBufferSize - d->rba.size();
- if ( maxToRead <= 0 ) {
- if ( d->rsn )
- d->rsn->setEnabled( FALSE );
- return;
- }
- }
-
- // Use TQSocketPrivate::sn_read_alreadyCalled to avoid recursive calls of
- // sn_read() (and as a result avoid emitting the readyRead() signal in a
- // slot for readyRead(), if you use bytesAvailable()).
- if ( !force && TQSocketPrivate::sn_read_alreadyCalled.findRef(this) != -1 )
- return;
- TQSocketPrivate::sn_read_alreadyCalled.append( this );
-
- char buf[4096];
- TQ_LONG nbytes = d->socket->bytesAvailable();
- TQ_LONG nread;
- TQByteArray *a = 0;
-
- if ( state() == Connecting ) {
- if ( nbytes > 0 ) {
- tryConnection();
- } else {
- // nothing to do, nothing to care about
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- }
- }
- if ( state() == Idle ) {
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- }
-
- if ( nbytes <= 0 ) { // connection closed?
- // On Windows this may happen when the connection is still open.
- // This happens when the system is heavily loaded and we have
- // read all the data on the socket before a new WSAAsyncSelect
- // event is processed. A new read operation would then block.
- // This code is also useful when TQSocket is used without an
- // event loop.
- nread = d->socket->readBlock( buf, maxToRead ? TQMIN((TQ_LONG)sizeof(buf),maxToRead) : sizeof(buf) );
- if ( nread == 0 ) { // really closed
- if ( !d->socket->isOpen() ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): sn_read: Connection closed", name() );
-#endif
- d->connectionClosed();
- emit connectionClosed();
- }
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- } else {
- if ( nread < 0 ) {
- if ( d->socket->error() == TQSocketDevice::NoError ) {
- // all is fine
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- }
-#if defined(TQSOCKET_DEBUG)
- qWarning( "TQSocket::sn_read (%s): Close error", name() );
-#endif
- if ( d->rsn )
- d->rsn->setEnabled( FALSE );
- emit error( ErrSocketRead );
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- }
- a = new TQByteArray( nread );
- memcpy( a->data(), buf, nread );
- }
-
- } else { // data to be read
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): sn_read: %ld incoming bytes", name(), nbytes );
-#endif
- if ( nbytes > (int)sizeof(buf) ) {
- // big
- a = new TQByteArray( nbytes );
- nread = d->socket->readBlock( a->data(), maxToRead ? TQMIN(nbytes,maxToRead) : nbytes );
- } else {
- a = 0;
- nread = d->socket->readBlock( buf, maxToRead ? TQMIN((TQ_LONG)sizeof(buf),maxToRead) : sizeof(buf) );
- if ( nread > 0 ) {
- // ##### could setRawData
- a = new TQByteArray( nread );
- memcpy( a->data(), buf, nread );
- }
- }
- if ( nread == 0 ) {
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): sn_read: Connection closed", name() );
-#endif
- // ### we should rather ask the socket tqdevice if it is closed
- d->connectionClosed();
- emit connectionClosed();
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- delete a;
- return;
- } else if ( nread < 0 ) {
- delete a;
-
- if ( d->socket->error() == TQSocketDevice::NoError ) {
- // all is fine
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- }
-#if defined(TQT_CHECK_RANGE)
- qWarning( "TQSocket::sn_read: Read error" );
-#endif
- if ( d->rsn )
- d->rsn->setEnabled( FALSE );
- emit error( ErrSocketRead );
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
- return;
- }
- if ( nread != (int)a->size() ) { // unexpected
-#if defined(CHECK_RANGE) && !defined(TQ_OS_WIN32)
- qWarning( "TQSocket::sn_read: Unexpected short read" );
-#endif
- a->resize( nread );
- }
- }
- d->rba.append( a );
- if ( !force ) {
- if ( d->rsn )
- d->rsn->setEnabled( FALSE );
- emit readyRead();
- if ( d->rsn )
- d->rsn->setEnabled( TRUE );
- }
-
- TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
-}
-
-
-/*!
- \internal
- Internal slot for handling socket write notifications.
-*/
-
-void TQSocket::sn_write()
-{
- if ( d->state == Connecting ) // connection established?
- tryConnection();
- flush();
-}
-
-void TQSocket::emitErrorConnectionRefused()
-{
- emit error( ErrConnectionRefused );
-}
-
-void TQSocket::tryConnection()
-{
- if ( d->socket->connect( d->addr, d->port ) ) {
- d->state = Connected;
-#if defined(TQSOCKET_DEBUG)
- qDebug( "TQSocket (%s): sn_write: Got connection to %s",
- name(), peerName().ascii() );
-#endif
- if ( d->rsn )
- d->rsn->setEnabled( TRUE );
- emit connected();
- } else {
- d->state = Idle;
- TQTimer::singleShot( 0, this, TQT_SLOT(emitErrorConnectionRefused()) );
- return;
- }
-}
-
-
-/*!
- Returns the socket number, or -1 if there is no socket at the moment.
-*/
-
-int TQSocket::socket() const
-{
- if ( d->socket == 0 )
- return -1;
- return d->socket->socket();
-}
-
-/*!
- Sets the socket to use \a socket and the state() to \c Connected.
- The socket must already be connected.
-
- This allows us to use the TQSocket class as a wrapper for other
- socket types (e.g. Unix Domain Sockets).
-*/
-
-void TQSocket::setSocket( int socket )
-{
- setSocketIntern( socket );
- d->state = Connection;
- d->rsn->setEnabled( TRUE );
-}
-
-
-/*!
- Sets the socket to \a socket. This is used by both setSocket() and
- connectToHost() and can also be used on unconnected sockets.
-*/
-
-void TQSocket::setSocketIntern( int socket )
-{
- if ( state() != Idle ) {
- clearPendingData();
- close();
- }
- TQ_ULONG oldBufferSize = d ? d->readBufferSize : 0;
- delete d;
-
- d = new TQSocketPrivate;
- if (oldBufferSize)
- d->readBufferSize = oldBufferSize;
- if ( socket >= 0 ) {
- TQSocketDevice *sd = new TQSocketDevice( socket, TQSocketDevice::Stream );
- sd->setBlocking( FALSE );
- sd->setAddressReusable( TRUE );
- d->setSocketDevice( this, sd );
- }
- d->state = Idle;
-
- // Initialize the IO tqdevice flags
- setFlags( IO_Direct );
- resetqStatus();
- open( IO_ReadWrite );
-
- // hm... this is not very nice.
- d->host = TQString::null;
- d->port = 0;
-#ifndef TQT_NO_DNS
- delete d->dns4;
- d->dns4 = 0;
- delete d->dns6;
- d->dns6 = 0;
-#endif
-}
-
-
-/*!
- Returns the host port number of this socket, in native byte order.
-*/
-
-TQ_UINT16 TQSocket::port() const
-{
- if ( d->socket == 0 )
- return 0;
- return d->socket->port();
-}
-
-
-/*!
- Returns the peer's host port number, normally as specified to the
- connectToHost() function. If none has been set, this function
- returns 0.
-
- Note that TQt always uses native byte order, i.e. 67 is 67 in TQt;
- there is no need to call htons().
-*/
-
-TQ_UINT16 TQSocket::peerPort() const
-{
- if ( d->socket == 0 )
- return 0;
- return d->socket->peerPort();
-}
-
-
-/*!
- Returns the host address of this socket. (This is normally the
- main IP address of the host, but can be e.g. 127.0.0.1 for
- connections to localhost.)
-*/
-
-TQHostAddress TQSocket::address() const
-{
- if ( d->socket == 0 ) {
- TQHostAddress tmp;
- return tmp;
- }
- return d->socket->address();
-}
-
-
-/*!
- Returns the address of the connected peer if the socket is in
- Connected state; otherwise an empty TQHostAddress is returned.
-*/
-
-TQHostAddress TQSocket::peerAddress() const
-{
- if ( d->socket == 0 ) {
- TQHostAddress tmp;
- return tmp;
- }
- return d->socket->peerAddress();
-}
-
-
-/*!
- Returns the host name as specified to the connectToHost()
- function. An empty string is returned if none has been set.
-*/
-
-TQString TQSocket::peerName() const
-{
- return d->host;
-}
-
-/*!
- Sets the size of the TQSocket's internal read buffer to \a bufSize.
-
- Usually TQSocket reads all data that is available from the operating
- system's socket. If the buffer size is limited to a certain size, this
- means that the TQSocket class doesn't buffer more than this size of data.
-
- If the size of the read buffer is 0, the read buffer is unlimited and all
- incoming data is buffered. This is the default.
-
- If you read the data in the readyRead() signal, you shouldn't use this
- option since it might slow down your program unnecessary. This option is
- useful if you only need to read the data at certain points in time, like in
- a realtime streaming application.
-
- \sa readBufferSize()
-*/
-
-void TQSocket::setReadBufferSize( TQ_ULONG bufSize )
-{
- d->readBufferSize = bufSize;
-}
-
-/*!
- Returns the size of the read buffer.
-
- \sa setReadBufferSize()
-*/
-
-TQ_ULONG TQSocket::readBufferSize() const
-{
- return d->readBufferSize;
-}
-
-#endif //TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/network/tqsocket.h b/tqtinterface/qt4/src/network/tqsocket.h
deleted file mode 100644
index 7b9453e..0000000
--- a/tqtinterface/qt4/src/network/tqsocket.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/****************************************************************************
-**
-** Definition of TQSocket class.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQSOCKET_H
-#define TQSOCKET_H
-
-#ifndef TQT_H
-#include "tqobject.h"
-#include "tqiodevice.h"
-#include "tqhostaddress.h" // int->TQHostAddress conversion
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_NETWORK
-#else
-#define TQM_EXPORT_NETWORK TQ_EXPORT
-#endif
-
-#ifndef TQT_NO_NETWORK
-class TQSocketPrivate;
-class TQSocketDevice;
-
-// #ifdef USE_QT4
-class TQM_EXPORT_NETWORK TQSocket : public TQIODevice
-// #else // USE_QT4
-// class TQM_EXPORT_NETWORK TQSocket : public TQObject, public TQIODevice
-// #endif // USE_QT4
-{
- Q_OBJECT
- TQ_OBJECT
-public:
- enum Error {
- ErrConnectionRefused,
- ErrHostNotFound,
- ErrSocketRead
- };
-
- TQSocket( TQObject *parent=0, const char *name=0 );
- virtual ~TQSocket();
-
- enum State { Idle, HostLookup, Connecting,
- Connected, Closing,
- Connection=Connected };
- State state() const;
-
- int socket() const;
- virtual void setSocket( int );
-
- TQSocketDevice *socketDevice();
- virtual void setSocketDevice( TQSocketDevice * );
-
-#ifndef TQT_NO_DNS
- virtual void connectToHost( const TQString &host, TQ_UINT16 port );
-#endif
- TQString peerName() const;
-
- // Implementation of TQIODevice abstract virtual functions
- bool open( int mode );
- void close();
- void flush();
-#ifdef USE_QT4
- qint64 size() const;
- qint64 at() const;
-#else // USE_QT4
- Offset size() const;
- Offset at() const;
-#endif // USE_QT4
- bool at( Offset );
- bool atEnd() const;
-
-#ifdef USE_QT4
- qint64 bytesAvailable() const; // ### TQIODevice::Offset instead?
- qint64 bytesToWrite() const;
-#else // USE_QT4
- TQ_ULONG bytesAvailable() const; // ### TQIODevice::Offset instead?
- TQ_ULONG bytesToWrite() const;
-#endif // USE_QT4
- TQ_ULONG waitForMore( int msecs, bool *timeout ) const;
- TQ_ULONG waitForMore( int msecs ) const; // ### TQt 4.0: merge the two overloads
- void clearPendingData();
-
- TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
- TQ_LONG writeBlock( const char *data, TQ_ULONG len );
- TQ_LONG readLine( char *data, TQ_ULONG maxlen );
-
- int getch();
- int putch( int );
- int ungetch(int);
-
- bool canReadLine() const;
- virtual TQString readLine();
-
- TQ_UINT16 port() const;
- TQ_UINT16 peerPort() const;
- TQHostAddress address() const;
- TQHostAddress peerAddress() const;
-
- void setReadBufferSize( TQ_ULONG );
- TQ_ULONG readBufferSize() const;
-
-Q_SIGNALS:
- void hostFound();
- void connected();
- void connectionClosed();
- void delayedCloseFinished();
- void readyRead();
- void bytesWritten( int nbytes );
- void error( int );
-
-protected Q_SLOTS:
- virtual void sn_read( bool force=FALSE );
- virtual void sn_write();
-
-private Q_SLOTS:
- void tryConnecting();
- void emitErrorConnectionRefused();
-
-private:
- TQSocketPrivate *d;
-
- bool consumeWriteBuf( TQ_ULONG nbytes );
- void tryConnection();
- void setSocketIntern( int socket );
-
-private: // Disabled copy constructor and operator=
-#if defined(TQ_DISABLE_COPY)
- TQSocket( const TQSocket & );
- TQSocket &operator=( const TQSocket & );
-#endif
-
-protected:
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
-};
-
-#endif //TQT_NO_NETWORK
-#endif // TQSOCKET_H
diff --git a/tqtinterface/qt4/src/network/tqsocketdevice.cpp b/tqtinterface/qt4/src/network/tqsocketdevice.cpp
deleted file mode 100644
index e2f7287..0000000
--- a/tqtinterface/qt4/src/network/tqsocketdevice.cpp
+++ /dev/null
@@ -1,584 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQSocketDevice class.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqsocketdevice.h"
-#ifndef TQT_NO_NETWORK
-
-#include "tqwindowdefs.h"
-#include <string.h>
-
-
-//#define TQSOCKETDEVICE_DEBUG
-
-
-class TQSocketDevicePrivate
-{
-public:
- TQSocketDevicePrivate( TQSocketDevice::Protocol p )
- : protocol(p)
- { }
-
- TQSocketDevice::Protocol protocol;
-};
-
-
-/*!
- \class TQSocketDevice tqsocketdevice.h
- \brief The TQSocketDevice class provides a platform-independent low-level socket API.
-\if defined(commercial)
- It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
-\endif
-
- \ingroup io
- \module network
-
- This class provides a low level API for working with sockets. Users of
- this class are assumed to have networking experience. For most users the
- TQSocket class provides a much easier and high level alternative, but
- certain things (like UDP) can't be done with TQSocket and if you need a
- platform-independent API for those, TQSocketDevice is the right choice.
-
- The essential purpose of the class is to provide a TQIODevice that
- works on sockets, wrapped in a platform-independent API.
-
- When calling connect() or bind(), TQSocketDevice detects the
- protocol family (IPv4, IPv6) automatically. Passing the protocol
- family to TQSocketDevice's constructor or to setSocket() forces
- creation of a socket tqdevice of a specific protocol. If not set, the
- protocol will be detected at the first call to connect() or bind().
-
- \sa TQSocket, TQSocketNotifier, TQHostAddress
-*/
-
-
-/*!
- \enum TQSocketDevice::Protocol
-
- This enum type describes the protocol family of the socket. Possible values
- are:
-
- \value IPv4 The socket is an IPv4 socket.
- \value IPv6 The socket is an IPv6 socket.
- \value Unknown The protocol family of the socket is not known. This can
- happen if you use TQSocketDevice with an already existing socket; it
- tries to determine the protocol family, but this can fail if the
- protocol family is not known to TQSocketDevice.
-
- \sa protocol() setSocket()
-*/
-
-/*!
- \enum TQSocketDevice::Error
-
- This enum type describes the error states of TQSocketDevice.
-
- \value NoError No error has occurred.
-
- \value AlreadyBound The tqdevice is already bound, according to bind().
-
- \value Inaccessible The operating system or firewall prohibited
- the action.
-
- \value NoResources The operating system ran out of a resource.
-
- \value InternalError An internal error occurred in TQSocketDevice.
-
- \value Impossible An attempt was made to do something which makes
- no sense. For example:
- \code
- ::close( sd->socket() );
- sd->writeBlock( someData, 42 );
- \endcode
- The libc ::close() closes the socket, but TQSocketDevice is not aware
- of this. So when you call writeBlock(), the impossible happens.
-
- \value NoFiles The operating system will not let TQSocketDevice open
- another file.
-
- \value ConnectionRefused A connection attempt was rejected by the
- peer.
-
- \value NetworkFailure There is a network failure.
-
- \value UnknownError The operating system did something
- unexpected.
-*/
-
-/*!
- \enum TQSocketDevice::Type
-
- This enum type describes the type of the socket:
- \value Stream a stream socket (TCP, usually)
- \value Datagram a datagram socket (UDP, usually)
-*/
-
-
-/*!
- Creates a TQSocketDevice object for the existing socket \a socket.
-
- The \a type argument must match the actual socket type; use \c
- TQSocketDevice::Stream for a reliable, connection-oriented TCP
- socket, or \c TQSocketDevice::Datagram for an unreliable,
- connectionless UDP socket.
-*/
-TQSocketDevice::TQSocketDevice( int socket, Type type )
- : fd( socket ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
- d(new TQSocketDevicePrivate(Unknown))
-{
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice: Created TQSocketDevice %p (socket %x, type %d)",
- this, socket, type );
-#endif
- init();
- setSocket( socket, type );
-}
-
-/*!
- Creates a TQSocketDevice object for a stream or datagram socket.
-
- The \a type argument must be either \c TQSocketDevice::Stream for a
- reliable, connection-oriented TCP socket, or \c
- TQSocketDevice::Datagram for an unreliable UDP socket.
-
- The socket is created as an IPv4 socket.
-
- \sa blocking() protocol()
-*/
-TQSocketDevice::TQSocketDevice( Type type )
- : fd( -1 ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
- d(new TQSocketDevicePrivate(IPv4))
-{
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice: Created TQSocketDevice object %p, type %d",
- this, type );
-#endif
- init();
- setSocket( createNewSocket(), type );
-}
-
-/*!
- Creates a TQSocketDevice object for a stream or datagram socket.
-
- The \a type argument must be either \c TQSocketDevice::Stream for a
- reliable, connection-oriented TCP socket, or \c
- TQSocketDevice::Datagram for an unreliable UDP socket.
-
- The \a protocol indicates whether the socket should be of type IPv4
- or IPv6. Passing \c Unknown is not meaningful in this context and you
- should avoid using (it creates an IPv4 socket, but your code is not easily
- readable).
-
- The argument \a dummy is necessary for compatibility with some
- compilers.
-
- \sa blocking() protocol()
-*/
-TQSocketDevice::TQSocketDevice( Type type, Protocol protocol, int )
- : fd( -1 ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
- d(new TQSocketDevicePrivate(protocol))
-{
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice: Created TQSocketDevice object %p, type %d",
- this, type );
-#endif
- init();
- setSocket( createNewSocket(), type );
-}
-
-/*!
- Destroys the socket tqdevice and closes the socket if it is open.
-*/
-TQSocketDevice::~TQSocketDevice()
-{
- close();
- delete d;
- d = 0;
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice: Destroyed TQSocketDevice %p", this );
-#endif
-}
-
-
-/*!
- Returns TRUE if this is a valid socket; otherwise returns FALSE.
-
- \sa socket()
-*/
-bool TQSocketDevice::isValid() const
-{
- return fd != -1;
-}
-
-
-/*!
- \fn Type TQSocketDevice::type() const
-
- Returns the socket type which is either \c TQSocketDevice::Stream
- or \c TQSocketDevice::Datagram.
-
- \sa socket()
-*/
-TQSocketDevice::Type TQSocketDevice::type() const
-{
- return t;
-}
-
-/*!
- Returns the socket's protocol family, which is one of \c Unknown, \c IPv4,
- or \c IPv6.
-
- TQSocketDevice either creates a socket with a well known protocol family or
- it uses an already existing socket. In the first case, this function
- returns the protocol family it was constructed with. In the second case, it
- tries to determine the protocol family of the socket; if this fails, it
- returns \c Unknown.
-
- \sa Protocol setSocket()
-*/
-TQSocketDevice::Protocol TQSocketDevice::protocol() const
-{
- if ( d->protocol == Unknown )
- d->protocol = getProtocol();
- return d->protocol;
-}
-
-/*!
- Returns the socket number, or -1 if it is an invalid socket.
-
- \sa isValid(), type()
-*/
-int TQSocketDevice::socket() const
-{
- return fd;
-}
-
-
-/*!
- Sets the socket tqdevice to operate on the existing socket \a
- socket.
-
- The \a type argument must match the actual socket type; use \c
- TQSocketDevice::Stream for a reliable, connection-oriented TCP
- socket, or \c TQSocketDevice::Datagram for an unreliable,
- connectionless UDP socket.
-
- Any existing socket is closed.
-
- \sa isValid(), close()
-*/
-void TQSocketDevice::setSocket( int socket, Type type )
-{
- if ( fd != -1 ) // close any open socket
- close();
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice::setSocket: socket %x, type %d", socket, type );
-#endif
- t = type;
- fd = socket;
- d->protocol = Unknown;
- e = NoError;
- setFlags( IO_Sequential );
- resetqStatus();
- open( IO_ReadWrite );
- fetchConnectionParameters();
-}
-
-
-/*!
- \reimp
-
- Opens the socket using the specified TQIODevice file \a mode. This
- function is called from the TQSocketDevice constructors and from
- the setSocket() function. You should not call it yourself.
-
- \sa close().
-*/
-bool TQSocketDevice::open( int mode )
-{
- if ( isOpen() || !isValid() )
- return FALSE;
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice::open: mode %x", mode );
-#endif
- setMode( mode & IO_ReadWrite );
- setState( IO_Open );
- return TRUE;
-}
-
-
-/*!
- \reimp
-
- The current TQSocketDevice implementation does not buffer at all,
- so this is a no-op.
-*/
-void TQSocketDevice::flush()
-{
-}
-
-
-/*!
- \reimp
-
- The size is meaningless for a socket, therefore this function returns 0.
-*/
-#ifdef USE_QT4
-qint64 TQSocketDevice::size() const
-#else // USE_QT4
-TQIODevice::Offset TQSocketDevice::size() const
-#endif // USE_QT4
-{
- return 0;
-}
-
-
-/*!
- \reimp
-
- The read/write index is meaningless for a socket, therefore this
- function returns 0.
-*/
-#ifdef USE_QT4
-qint64 TQSocketDevice::at() const
-#else // USE_QT4
-TQIODevice::Offset TQSocketDevice::at() const
-#endif // USE_QT4
-{
- return 0;
-}
-
-
-/*!
- \reimp
-
- The read/write index is meaningless for a socket, therefore this
- function does nothing and returns TRUE.
-*/
-bool TQSocketDevice::at( Offset )
-{
- return TRUE;
-}
-
-
-/*!
- \reimp
-
- Returns TRUE if no data is currently available at the socket;
- otherwise returns FALSE.
-*/
-bool TQSocketDevice::atEnd() const
-{
- return bytesAvailable() <= 0;
-}
-
-
-/*!
- \reimp
-
- \warning getch() is implemented as a one-byte readBlock(), so it
- may be very slow if you call it more than a few times.
-
- \sa putch() readBlock()
-*/
-int TQSocketDevice::getch()
-{
- char buf[2];
- return readBlock(buf,1) == 1 ? buf[0] : -1;
-}
-
-
-/*!
- \reimp
-
- \warning putch() is implemented as a one-byte writeBlock(), so it
- may be very slow if you call it more than a few times.
-
- \sa getch()
-*/
-int TQSocketDevice::putch( int ch )
-{
- char buf[2];
- buf[0] = ch;
- return writeBlock(buf, 1) == 1 ? ch : -1;
-}
-
-
-/*!
- \reimp
-
- This implementation of ungetch returns -1 (error). A socket is a
- sequential tqdevice and does not allow any ungetch operation.
-*/
-int TQSocketDevice::ungetch( int )
-{
- return -1;
-}
-
-
-/*!
- Returns TRUE if the address of this socket can be used by other
- sockets at the same time, and FALSE if this socket claims
- exclusive ownership.
-
- \sa setAddressReusable()
-*/
-bool TQSocketDevice::addressReusable() const
-{
- return option( ReuseAddress );
-}
-
-
-/*!
- Sets the address of this socket to be usable by other sockets too
- if \a enable is TRUE, and to be used exclusively by this socket if
- \a enable is FALSE.
-
- When a socket is reusable, other sockets can use the same port
- number (and IP address), which is generally useful. Of course
- other sockets cannot use the same
- (address,port,peer-address,peer-port) 4-tuple as this socket, so
- there is no risk of confusing the two TCP connections.
-
- \sa addressReusable()
-*/
-void TQSocketDevice::setAddressReusable( bool enable )
-{
- setOption( ReuseAddress, enable );
-}
-
-
-/*!
- Returns the size of the operating system receive buffer.
-
- \sa setReceiveBufferSize()
-*/
-int TQSocketDevice::receiveBufferSize() const
-{
- return option( ReceiveBuffer );
-}
-
-
-/*!
- Sets the size of the operating system receive buffer to \a size.
-
- The operating system receive buffer size effectively limits two
- things: how much data can be in transit at any one moment, and how
- much data can be received in one iteration of the main event loop.
-
- The default is operating system-dependent. A socket that receives
- large amounts of data is probably best with a buffer size of
- 49152.
-*/
-void TQSocketDevice::setReceiveBufferSize( uint size )
-{
- setOption( ReceiveBuffer, size );
-}
-
-
-/*!
- Returns the size of the operating system send buffer.
-
- \sa setSendBufferSize()
-*/
-int TQSocketDevice::sendBufferSize() const
-{
- return option( SendBuffer );
-}
-
-
-/*!
- Sets the size of the operating system send buffer to \a size.
-
- The operating system send buffer size effectively limits how much
- data can be in transit at any one moment.
-
- The default is operating system-dependent. A socket that sends
- large amounts of data is probably best with a buffer size of
- 49152.
-*/
-void TQSocketDevice::setSendBufferSize( uint size )
-{
- setOption( SendBuffer, size );
-}
-
-
-/*!
- Returns the port number of this socket tqdevice. This may be 0 for a
- while, but is set to something sensible as soon as a sensible
- value is available.
-
- Note that TQt always uses native byte order, i.e. 67 is 67 in TQt;
- there is no need to call htons().
-*/
-TQ_UINT16 TQSocketDevice::port() const
-{
- return p;
-}
-
-
-/*!
- Returns the address of this socket tqdevice. This may be 0.0.0.0 for
- a while, but is set to something sensible as soon as a sensible
- value is available.
-*/
-TQHostAddress TQSocketDevice::address() const
-{
- return a;
-}
-
-
-/*!
- Returns the first error seen.
-*/
-TQSocketDevice::Error TQSocketDevice::error() const
-{
- return e;
-}
-
-
-/*!
- Allows subclasses to set the error state to \a err.
-*/
-void TQSocketDevice::setError( Error err )
-{
- e = err;
-}
-#endif //TQT_NO_NETWORK
-
diff --git a/tqtinterface/qt4/src/network/tqsocketdevice.h b/tqtinterface/qt4/src/network/tqsocketdevice.h
deleted file mode 100644
index 050ad5b..0000000
--- a/tqtinterface/qt4/src/network/tqsocketdevice.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/****************************************************************************
-**
-** Definition of TQSocketDevice class.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#ifndef TQSOCKETDEVICE_H
-#define TQSOCKETDEVICE_H
-
-#ifndef TQT_H
-#include "tqiodevice.h"
-#include "tqhostaddress.h" // int->TQHostAddress conversion
-#endif // TQT_H
-
-#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
-#define TQM_EXPORT_NETWORK
-#else
-#define TQM_EXPORT_NETWORK TQ_EXPORT
-#endif
-
-#ifndef TQT_NO_NETWORK
-class TQSocketDevicePrivate;
-
-#define QT_SOCKLEN_T socklen_t
-
-class TQM_EXPORT_NETWORK TQSocketDevice: public TQIODevice
-{
-public:
- enum Type { Stream, Datagram };
- enum Protocol { IPv4, IPv6, Unknown };
-
- TQSocketDevice( Type type = Stream );
- TQSocketDevice( Type type, Protocol protocol, int dummy );
- TQSocketDevice( int socket, Type type );
- virtual ~TQSocketDevice();
-
- bool isValid() const;
- Type type() const;
- Protocol protocol() const;
-
- int socket() const;
- virtual void setSocket( int socket, Type type );
-
- bool open( int mode );
- void close();
- void flush();
-
- // Implementation of TQIODevice abstract virtual functions
-#ifdef USE_QT4
- qint64 size() const;
- qint64 at() const;
-#else // USE_QT4
- Offset size() const;
- Offset at() const;
-#endif // USE_QT4
- bool at( Offset );
- bool atEnd() const;
-
- bool blocking() const;
- virtual void setBlocking( bool );
-
- bool addressReusable() const;
- virtual void setAddressReusable( bool );
-
- int receiveBufferSize() const;
- virtual void setReceiveBufferSize( uint );
- int sendBufferSize() const;
- virtual void setSendBufferSize( uint );
-
- virtual bool connect( const TQHostAddress &, TQ_UINT16 );
-
- virtual bool bind( const TQHostAddress &, TQ_UINT16 );
- virtual bool listen( int backlog );
- virtual int accept();
-
-#ifdef USE_QT4
- qint64 bytesAvailable() const;
-#else // USE_QT4
- TQ_LONG bytesAvailable() const;
-#endif // USE_QT4
- TQ_LONG waitForMore( int msecs, bool *timeout=0 ) const;
- TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
- TQ_LONG writeBlock( const char *data, TQ_ULONG len );
- virtual TQ_LONG writeBlock( const char *data, TQ_ULONG len,
- const TQHostAddress & host, TQ_UINT16 port );
-
- int getch();
- int putch( int );
- int ungetch(int);
-
- TQ_UINT16 port() const;
- TQ_UINT16 peerPort() const;
- TQHostAddress address() const;
- TQHostAddress peerAddress() const;
-
- enum Error {
- NoError,
- AlreadyBound,
- Inaccessible,
- NoResources,
- InternalError,
- Bug = InternalError, // ### remove in 4.0?
- Impossible,
- NoFiles,
- ConnectionRefused,
- NetworkFailure,
- UnknownError
- };
- Error error() const;
-
-protected:
- void setError( Error err );
-
-private:
- int fd;
- Type t;
- TQ_UINT16 p;
- TQHostAddress a;
- TQ_UINT16 pp;
- TQHostAddress pa;
- TQSocketDevice::Error e;
- TQSocketDevicePrivate * d;
-
- enum Option { Broadcast, ReceiveBuffer, ReuseAddress, SendBuffer };
-
- int option( Option ) const;
- virtual void setOption( Option, int );
-
- void fetchConnectionParameters();
-#if defined(TQ_OS_WIN32)
- void fetchPeerConnectionParameters();
-#endif
-
- static void init();
- int createNewSocket();
- Protocol getProtocol() const;
-
-private: // Disabled copy constructor and operator=
-#if defined(TQ_DISABLE_COPY)
- TQSocketDevice( const TQSocketDevice & );
- TQSocketDevice &operator=( const TQSocketDevice & );
-#endif
-
-protected:
-// void setError( Error err );
- qint64 readData(char *data, qint64 maxlen);
- qint64 writeData(const char *data, qint64 len);
-};
-
-#endif // TQT_NO_NETWORK
-#endif // TQSOCKETDEVICE_H
diff --git a/tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp b/tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp
deleted file mode 100644
index 46c3932..0000000
--- a/tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp
+++ /dev/null
@@ -1,1269 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQSocketDevice class.
-**
-** Created : 970521
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the network module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqplatformdefs.h"
-
-// Almost always the same. If not, specify in qplatformdefs.h.
-#if !defined(TQT_SOCKOPTLEN_T)
-# define TQT_SOCKOPTLEN_T TQT_SOCKLEN_T
-#endif
-
-// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED
-static inline int qt_socket_accept(int s, struct sockaddr *addr, TQT_SOCKLEN_T *addrlen)
-{ return ::accept(s, addr, addrlen); }
-#if defined(accept)
-# undef accept
-#endif
-
-// Solaris redefines bind -> __xnet_bind with _XOPEN_SOURCE_EXTENDED
-static inline int qt_socket_bind(int s, struct sockaddr *addr, TQT_SOCKLEN_T addrlen)
-{ return ::bind(s, addr, addrlen); }
-#if defined(bind)
-# undef bind
-#endif
-
-// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED
-static inline int qt_socket_connect(int s, struct sockaddr *addr, TQT_SOCKLEN_T addrlen)
-{ return ::connect(s, addr, addrlen); }
-#if defined(connect)
-# undef connect
-#endif
-
-// UnixWare 7 redefines listen -> _listen
-static inline int qt_socket_listen(int s, int backlog)
-{ return ::listen(s, backlog); }
-#if defined(listen)
-# undef listen
-#endif
-
-// UnixWare 7 redefines socket -> _socket
-static inline int qt_socket_socket(int domain, int type, int protocol)
-{ return ::socket(domain, type, protocol); }
-#if defined(socket)
-# undef socket
-#endif
-
-#include "tqsocketdevice.h"
-
-#ifndef TQT_NO_NETWORK
-
-#include "tqwindowdefs.h"
-
-#include <errno.h>
-#include <sys/types.h>
-
-
-static inline void qt_socket_getportaddr( struct sockaddr *sa,
- TQ_UINT16 *port, TQHostAddress *addr )
-{
-#if !defined(TQT_NO_IPV6)
- if ( sa->sa_family == AF_INET6 ) {
- struct sockaddr_in6 *sa6 = ( struct sockaddr_in6 * )sa;
- TQ_IPV6ADDR tmp;
- memcpy( &tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp) );
- TQHostAddress a( tmp );
- *addr = a;
- *port = ntohs( sa6->sin6_port );
- return;
- }
-#endif
- struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
- TQHostAddress a( ntohl( sa4->sin_addr.s_addr ) );
- *port = ntohs( sa4->sin_port );
- *addr = TQHostAddress( ntohl( sa4->sin_addr.s_addr ) );
- return;
-}
-
-#ifdef USE_QT4
-
-qint64 TQSocketDevice::readData( char *data, qint64 maxlen )
-{
-#if defined(QT_CHECK_NULL)
- if ( data == 0 && maxlen != 0 ) {
- qWarning( "TQSocketDevice::readBlock: Null pointer error" );
- }
-#endif
-#if defined(QT_CHECK_STATE)
- if ( !isValid() ) {
- qWarning( "TQSocketDevice::readBlock: Invalid socket" );
- return -1;
- }
- if ( !isOpen() ) {
- qWarning( "TQSocketDevice::readBlock: Device is not open" );
- return -1;
- }
- if ( !isReadable() ) {
- qWarning( "TQSocketDevice::readBlock: Read operation not permitted" );
- return -1;
- }
-#endif
- bool done = false;
- int r = 0;
- while ( done == false ) {
- if ( t == Datagram ) {
-#if !defined(QT_NO_IPV6)
- struct sockaddr_storage aa;
-#else
- struct sockaddr_in aa;
-#endif
- memset( &aa, 0, sizeof(aa) );
- QT_SOCKLEN_T sz;
- sz = sizeof( aa );
- r = ::recvfrom( fd, data, maxlen, 0,
- (struct sockaddr *)&aa, &sz );
-
- qt_socket_getportaddr( (struct sockaddr *)&aa, &pp, &pa);
-
- } else {
- r = ::read( fd, data, maxlen );
- }
- done = true;
- if ( r == 0 && t == Stream && maxlen > 0 ) {
- // connection closed
- close();
- } else if ( r >= 0 || errno == EAGAIN || errno == EWOULDBLOCK ) {
- // nothing
- } else if ( errno == EINTR ) {
- done = false;
- } else if ( e == NoError ) {
- switch( errno ) {
- case EIO:
- case EISDIR:
- case EBADF:
- case EINVAL:
- case EFAULT:
- case ENOTCONN:
- case ENOTSOCK:
- e = Impossible;
- break;
-#if defined(ENONET)
- case ENONET:
-#endif
- case EHOSTUNREACH:
- case ENETDOWN:
- case ENETUNREACH:
- case ETIMEDOUT:
- e = NetworkFailure;
- break;
- case EPIPE:
- case ECONNRESET:
- // connection closed
- close();
- r = 0;
- break;
- default:
- e = UnknownError;
- break;
- }
- }
- }
- return r;
-}
-
-
-qint64 TQSocketDevice::writeData( const char *data, qint64 len )
-{
- if ( data == 0 && len != 0 ) {
-#if defined(QT_CHECK_NULL) || defined(QSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Null pointer error" );
-#endif
- return -1;
- }
- if ( !isValid() ) {
-#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Invalid socket" );
-#endif
- return -1;
- }
- if ( !isOpen() ) {
-#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Device is not open" );
-#endif
- return -1;
- }
- if ( !isWritable() ) {
-#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Write operation not permitted" );
-#endif
- return -1;
- }
- bool done = false;
- int r = 0;
- bool timeout;
- while ( !done ) {
- r = ::write( fd, data, len );
- done = true;
- if ( r < 0 && e == NoError &&
- errno != EAGAIN && errno != EWOULDBLOCK ) {
- switch( errno ) {
- case EINTR: // signal - call read() or whatever again
- done = false;
- break;
- case EPIPE:
- case ECONNRESET:
- // connection closed
- close();
- r = 0;
- break;
- case ENOSPC:
- case EIO:
- case EISDIR:
- case EBADF:
- case EINVAL:
- case EFAULT:
- case ENOTCONN:
- case ENOTSOCK:
- e = Impossible;
- break;
-#if defined(ENONET)
- case ENONET:
-#endif
- case EHOSTUNREACH:
- case ENETDOWN:
- case ENETUNREACH:
- case ETIMEDOUT:
- e = NetworkFailure;
- break;
- default:
- e = UnknownError;
- break;
- }
- } else if ( waitForMore( 0, &timeout ) == 0 ) {
- if ( !timeout ) {
- // connection closed
- close();
- }
- }
- }
- return r;
-}
-
-#endif // USE_QT4
-
-
-//#define TQSOCKETDEVICE_DEBUG
-
-// internal
-void TQSocketDevice::init()
-{
-}
-
-
-TQSocketDevice::Protocol TQSocketDevice::getProtocol() const
-{
- if ( isValid() ) {
-#if !defined (TQT_NO_IPV6)
- struct sockaddr_storage sa;
-#else
- struct sockaddr sa;
-#endif
- memset( &sa, 0, sizeof(sa) );
- TQT_SOCKLEN_T sz = sizeof( sa );
-#if !defined (TQT_NO_IPV6)
- struct sockaddr *sap = reinterpret_cast<struct sockaddr *>(&sa);
- if ( !::getsockname(fd, sap, &sz) ) {
- switch ( sap->sa_family ) {
- case AF_INET:
- return IPv4;
- case AF_INET6:
- return IPv6;
- default:
- return Unknown;
- }
- }
-#else
- if ( !::getsockname(fd, &sa, &sz) ) {
- switch ( sa.sa_family ) {
- case AF_INET:
- return IPv4;
- default:
- return Unknown;
- }
- }
-#endif
- }
- return Unknown;
-}
-
-/*!
- Creates a new socket identifier. Returns -1 if there is a failure
- to create the new identifier; error() explains why.
-
- \sa setSocket()
-*/
-
-int TQSocketDevice::createNewSocket()
-{
-#if !defined(TQT_NO_IPV6)
- int s = qt_socket_socket( protocol() == IPv6 ? AF_INET6 : AF_INET,
- t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0 );
-#else
- int s = qt_socket_socket( AF_INET, t==Datagram?SOCK_DGRAM:SOCK_STREAM, 0 );
-#endif
- if ( s < 0 ) {
- switch( errno ) {
- case EPROTONOSUPPORT:
- e = InternalError; // 0 is supposed to work for both types
- break;
- case ENFILE:
- e = NoFiles; // special case for this
- break;
- case EACCES:
- e = Inaccessible;
- break;
- case ENOBUFS:
- case ENOMEM:
- e = NoResources;
- break;
- case EINVAL:
- e = Impossible;
- break;
- default:
- e = UnknownError;
- break;
- }
- } else {
- // ensure that the socket is closed on exec..() after being dup()'ed by
- // fork() in TQProcess.
- ::fcntl(s, F_SETFD, FD_CLOEXEC);
- return s;
- }
- return -1;
-}
-
-/*!
- \reimp
-
- Closes the socket and sets the socket identifier to -1 (invalid).
-
- (This function ignores errors; if there are any then a file
- descriptor leakage might result. As far as we know, the only error
- that can arise is EBADF, and that would of course not cause
- leakage. There may be OS-specfic errors that we haven't come
- across, however.)
-
- \sa open()
-*/
-void TQSocketDevice::close()
-{
- if ( fd == -1 || !isOpen() ) // already closed
- return;
- setFlags( IO_Sequential );
- resetqStatus();
- setState( 0 );
- ::close( fd );
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice::close: Closed socket %x", fd );
-#endif
- fd = -1;
- fetchConnectionParameters();
-}
-
-
-/*!
- Returns TRUE if the socket is valid and in blocking mode;
- otherwise returns FALSE.
-
- Note that this function does not set error().
-
- \warning On Windows, this function always returns TRUE since the
- ioctlsocket() function is broken.
-
- \sa setBlocking(), isValid()
-*/
-bool TQSocketDevice::blocking() const
-{
- if ( !isValid() )
- return TRUE;
- int s = fcntl(fd, F_GETFL, 0);
- return !(s >= 0 && ((s & O_NDELAY) != 0));
-}
-
-
-/*!
- Makes the socket blocking if \a enable is TRUE or nonblocking if
- \a enable is FALSE.
-
- Sockets are blocking by default, but we recommend using
- nonblocking socket operations, especially for GUI programs that
- need to be responsive.
-
- \warning On Windows, this function should be used with care since
- whenever you use a TQSocketNotifier on Windows, the socket is
- immediately made nonblocking.
-
- \sa blocking(), isValid()
-*/
-void TQSocketDevice::setBlocking( bool enable )
-{
-#if defined(TQSOCKETDEVICE_DEBUG)
- qDebug( "TQSocketDevice::setBlocking( %d )", enable );
-#endif
- if ( !isValid() )
- return;
- int tmp = ::fcntl(fd, F_GETFL, 0);
- if ( tmp >= 0 )
- tmp = ::fcntl( fd, F_SETFL, enable ? (tmp&~O_NDELAY) : (tmp|O_NDELAY) );
- if ( tmp >= 0 )
- return;
- if ( e )
- return;
- switch( errno ) {
- case EACCES:
- case EBADF:
- e = Impossible;
- break;
- case EFAULT:
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- case EDEADLK:
- case EINTR:
- case EINVAL:
- case EMFILE:
- case ENOLCK:
- case EPERM:
- default:
- e = UnknownError;
- }
-}
-
-
-/*!
- Returns the value of the socket option \a opt.
-*/
-int TQSocketDevice::option( Option opt ) const
-{
- if ( !isValid() )
- return -1;
- int n = -1;
- int v = -1;
- switch ( opt ) {
- case Broadcast:
- n = SO_BROADCAST;
- break;
- case ReceiveBuffer:
- n = SO_RCVBUF;
- break;
- case ReuseAddress:
- n = SO_REUSEADDR;
- break;
- case SendBuffer:
- n = SO_SNDBUF;
- break;
- }
- if ( n != -1 ) {
- TQT_SOCKOPTLEN_T len;
- len = sizeof(v);
- int r = ::getsockopt( fd, SOL_SOCKET, n, (char*)&v, &len );
- if ( r >= 0 )
- return v;
- if ( !e ) {
- TQSocketDevice *that = (TQSocketDevice*)this; // mutable function
- switch( errno ) {
- case EBADF:
- case ENOTSOCK:
- that->e = Impossible;
- break;
- case EFAULT:
- that->e = InternalError;
- break;
- default:
- that->e = UnknownError;
- break;
- }
- }
- return -1;
- }
- return v;
-}
-
-
-/*!
- Sets the socket option \a opt to \a v.
-*/
-void TQSocketDevice::setOption( Option opt, int v )
-{
- if ( !isValid() )
- return;
- int n = -1; // for really, really bad compilers
- switch ( opt ) {
- case Broadcast:
- n = SO_BROADCAST;
- break;
- case ReceiveBuffer:
- n = SO_RCVBUF;
- break;
- case ReuseAddress:
- n = SO_REUSEADDR;
- break;
- case SendBuffer:
- n = SO_SNDBUF;
- break;
- default:
- return;
- }
- if ( ::setsockopt( fd, SOL_SOCKET, n, (char*)&v, sizeof(v)) < 0 &&
- e == NoError ) {
- switch( errno ) {
- case EBADF:
- case ENOTSOCK:
- e = Impossible;
- break;
- case EFAULT:
- e = InternalError;
- break;
- default:
- e = UnknownError;
- break;
- }
- }
-}
-
-
-/*!
- Connects to the IP address and port specified by \a addr and \a
- port. Returns TRUE if it establishes a connection; otherwise returns FALSE.
- If it returns FALSE, error() explains why.
-
- Note that error() commonly returns NoError for non-blocking
- sockets; this just means that you can call connect() again in a
- little while and it'll probably succeed.
-*/
-bool TQSocketDevice::connect( const TQHostAddress &addr, TQ_UINT16 port )
-{
- if ( !isValid() )
- return FALSE;
-
- pa = addr;
- pp = port;
-
- struct sockaddr_in a4;
- struct sockaddr *aa;
- TQT_SOCKLEN_T aalen;
-
-#if !defined(TQT_NO_IPV6)
- struct sockaddr_in6 a6;
-
- if ( addr.isIPv6Address() ) {
- memset( &a6, 0, sizeof(a6) );
- a6.sin6_family = AF_INET6;
- a6.sin6_port = htons( port );
- TQ_IPV6ADDR ip6 = addr.toIPv6Address();
- memcpy( &a6.sin6_addr.s6_addr, &ip6, sizeof(ip6) );
-
- aalen = sizeof( a6 );
- aa = (struct sockaddr *)&a6;
- } else
-#endif
- if ( addr.isIPv4Address() ) {
- memset( &a4, 0, sizeof(a4) );
- a4.sin_family = AF_INET;
- a4.sin_port = htons( port );
- a4.sin_addr.s_addr = htonl( addr.toIPv4Address() );
-
- aalen = sizeof(a4);
- aa = (struct sockaddr *)&a4;
- } else {
- e = Impossible;
- return FALSE;
- }
-
- int r = qt_socket_connect( fd, aa, aalen );
- if ( r == 0 ) {
- fetchConnectionParameters();
- return TRUE;
- }
- if ( errno == EISCONN || errno == EALREADY || errno == EINPROGRESS ) {
- fetchConnectionParameters();
- return TRUE;
- }
- if ( e != NoError || errno == EAGAIN || errno == EWOULDBLOCK ) {
- return FALSE;
- }
- switch( errno ) {
- case EBADF:
- case ENOTSOCK:
- e = Impossible;
- break;
- case EFAULT:
- case EAFNOSUPPORT:
- e = InternalError;
- break;
- case ECONNREFUSED:
- e = ConnectionRefused;
- break;
- case ETIMEDOUT:
- case ENETUNREACH:
- e = NetworkFailure;
- break;
- case EADDRINUSE:
- e = NoResources;
- break;
- case EACCES:
- case EPERM:
- e = Inaccessible;
- break;
- default:
- e = UnknownError;
- break;
- }
- return FALSE;
-}
-
-
-/*!
- Assigns a name to an unnamed socket. The name is the host address
- \a address and the port number \a port. If the operation succeeds,
- bind() returns TRUE; otherwise it returns FALSE without changing
- what port() and address() return.
-
- bind() is used by servers for setting up incoming connections.
- Call bind() before listen().
-*/
-bool TQSocketDevice::bind( const TQHostAddress &address, TQ_UINT16 port )
-{
- if ( !isValid() )
- return FALSE;
- int r;
- struct sockaddr_in a4;
-#if !defined(TQT_NO_IPV6)
- struct sockaddr_in6 a6;
-
- if ( address.isIPv6Address() ) {
- memset( &a6, 0, sizeof(a6) );
- a6.sin6_family = AF_INET6;
- a6.sin6_port = htons( port );
- TQ_IPV6ADDR tmp = address.toIPv6Address();
- memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );
-
- r = qt_socket_bind( fd, (struct sockaddr *)&a6, sizeof(a6) );
- } else
-#endif
- if ( address.isIPv4Address() ) {
- memset( &a4, 0, sizeof(a4) );
- a4.sin_family = AF_INET;
- a4.sin_port = htons( port );
- a4.sin_addr.s_addr = htonl( address.toIPv4Address() );
-
- r = qt_socket_bind( fd, (struct sockaddr*)&a4, sizeof(a4) );
- } else {
- e = Impossible;
- return FALSE;
- }
-
- if ( r < 0 ) {
- switch( errno ) {
- case EINVAL:
- e = AlreadyBound;
- break;
- case EACCES:
- e = Inaccessible;
- break;
- case ENOMEM:
- e = NoResources;
- break;
- case EFAULT: // a was illegal
- case ENAMETOOLONG: // sz was wrong
- e = InternalError;
- break;
- case EBADF: // AF_UNIX only
- case ENOTSOCK: // AF_UNIX only
- case EROFS: // AF_UNIX only
- case ENOENT: // AF_UNIX only
- case ENOTDIR: // AF_UNIX only
- case ELOOP: // AF_UNIX only
- e = Impossible;
- break;
- default:
- e = UnknownError;
- break;
- }
- return FALSE;
- }
- fetchConnectionParameters();
- return TRUE;
-}
-
-
-/*!
- Specifies how many pending connections a server socket can have.
- Returns TRUE if the operation was successful; otherwise returns
- FALSE. A \a backlog value of 50 is quite common.
-
- The listen() call only applies to sockets where type() is \c
- Stream, i.e. not to \c Datagram sockets. listen() must not be
- called before bind() or after accept().
-
- \sa bind(), accept()
-*/
-bool TQSocketDevice::listen( int backlog )
-{
- if ( !isValid() )
- return FALSE;
- if ( qt_socket_listen( fd, backlog ) >= 0 )
- return TRUE;
- if ( !e )
- e = Impossible;
- return FALSE;
-}
-
-
-/*!
- Extracts the first connection from the queue of pending
- connections for this socket and returns a new socket identifier.
- Returns -1 if the operation failed.
-
- \sa bind(), listen()
-*/
-int TQSocketDevice::accept()
-{
- if ( !isValid() )
- return -1;
-
-#if !defined (TQT_NO_IPV6)
- struct sockaddr_storage aa;
-#else
- struct sockaddr aa;
-#endif
- TQT_SOCKLEN_T l = sizeof( aa );
- bool done;
- int s;
- do {
- s = qt_socket_accept( fd, (struct sockaddr*)&aa, &l );
- // we'll blithely throw away the stuff accept() wrote to aa
- done = TRUE;
- if ( s < 0 && e == NoError ) {
- switch( errno ) {
- case EINTR:
- done = FALSE;
- break;
-#if defined(EPROTO)
- case EPROTO:
-#endif
-#if defined(ENONET)
- case ENONET:
-#endif
- case ENOPROTOOPT:
- case EHOSTDOWN:
- case EOPNOTSUPP:
- case EHOSTUNREACH:
- case ENETDOWN:
- case ENETUNREACH:
- case ETIMEDOUT:
- // in all these cases, an error happened during connection
- // setup. we're not interested in what happened, so we
- // just treat it like the client-closed-quickly case.
- case EPERM:
- // firewalling wouldn't let us accept. we treat it like
- // the client-closed-quickly case.
- case EAGAIN:
-#if EAGAIN != EWOULDBLOCK
- case EWOULDBLOCK:
-#endif
- // the client closed the connection before we got around
- // to accept()ing it.
- break;
- case EBADF:
- case ENOTSOCK:
- e = Impossible;
- break;
- case EFAULT:
- e = InternalError;
- break;
- case ENOMEM:
- case ENOBUFS:
- e = NoResources;
- break;
- default:
- e = UnknownError;
- break;
- }
- }
- } while (!done);
- // ensure that the socket is closed on exec..() after being dup()'ed by
- // fork() in TQProcess.
- ::fcntl(s, F_SETFD, FD_CLOEXEC);
- return s;
-}
-
-
-/*!
- Returns the number of bytes available for reading, or -1 if an
- error occurred.
-
- \warning On Microsoft Windows, we use the ioctlsocket() function
- to determine the number of bytes queued on the socket. According
- to Microsoft (KB Q125486), ioctlsocket() sometimes returns an
- incorrect number. The only safe way to determine the amount of
- data on the socket is to read it using readBlock(). TQSocket has
- workarounds to deal with this problem.
-*/
-#ifdef USE_QT4
-qint64 TQSocketDevice::bytesAvailable() const
-#else // USE_QT4
-TQ_LONG TQSocketDevice::bytesAvailable() const
-#endif // USE_QT4
-{
- if ( !isValid() )
- return -1;
-
- /*
- Apparently, there is not consistency among different operating
- systems on how to use FIONREAD.
-
- FreeBSD, Linux and Solaris all expect the 3rd argument to
- ioctl() to be an int, which is normally 32-bit even on 64-bit
- machines.
-
- IRIX, on the other hand, expects a size_t, which is 64-bit on
- 64-bit machines.
-
- So, the solution is to use size_t initialized to zero to make
- sure all bits are set to zero, preventing underflow with the
- FreeBSD/Linux/Solaris ioctls.
- */
- size_t nbytes = 0;
- // gives shorter than true amounts on Unix domain sockets.
- if ( ::ioctl(fd, FIONREAD, (char*)&nbytes) < 0 )
- return -1;
- return (TQ_LONG) *((int *) &nbytes);
-}
-
-
-/*!
- Wait up to \a msecs milliseconds for more data to be available. If
- \a msecs is -1 the call will block indefinitely.
-
- Returns the number of bytes available for reading, or -1 if an
- error occurred.
-
- If \a timeout is non-null and no error occurred (i.e. it does not
- return -1): this function sets \a *timeout to TRUE, if the reason
- for returning was that the timeout was reached; otherwise it sets
- \a *timeout to FALSE. This is useful to find out if the peer
- closed the connection.
-
- \warning This is a blocking call and should be avoided in event
- driven applications.
-
- \sa bytesAvailable()
-*/
-TQ_LONG TQSocketDevice::waitForMore( int msecs, bool *timeout ) const
-{
- if ( !isValid() )
- return -1;
- if ( fd >= FD_SETSIZE )
- return -1;
-
- fd_set fds;
- struct timeval tv;
-
- FD_ZERO( &fds );
- FD_SET( fd, &fds );
-
- tv.tv_sec = msecs / 1000;
- tv.tv_usec = (msecs % 1000) * 1000;
-
- int rv = select( fd+1, &fds, 0, 0, msecs < 0 ? 0 : &tv );
-
- if ( rv < 0 )
- return -1;
-
- if ( timeout ) {
- if ( rv == 0 )
- *timeout = TRUE;
- else
- *timeout = FALSE;
- }
-
- return bytesAvailable();
-}
-
-
-/*!
- Reads \a maxlen bytes from the socket into \a data and returns the
- number of bytes read. Returns -1 if an error occurred. Returning 0
- is not an error. For Stream sockets, 0 is returned when the remote
- host closes the connection. For Datagram sockets, 0 is a valid
- datagram size.
-*/
-TQ_LONG TQSocketDevice::readBlock( char *data, TQ_ULONG maxlen )
-{
-#if defined(TQT_CHECK_NULL)
- if ( data == 0 && maxlen != 0 ) {
- qWarning( "TQSocketDevice::readBlock: Null pointer error" );
- }
-#endif
-#if defined(TQT_CHECK_STATE)
- if ( !isValid() ) {
- qWarning( "TQSocketDevice::readBlock: Invalid socket" );
- return -1;
- }
- if ( !isOpen() ) {
- qWarning( "TQSocketDevice::readBlock: Device is not open" );
- return -1;
- }
- if ( !isReadable() ) {
- qWarning( "TQSocketDevice::readBlock: Read operation not permitted" );
- return -1;
- }
-#endif
- bool done = FALSE;
- int r = 0;
- while ( done == FALSE ) {
- if ( t == Datagram ) {
-#if !defined(TQT_NO_IPV6)
- struct sockaddr_storage aa;
-#else
- struct sockaddr_in aa;
-#endif
- memset( &aa, 0, sizeof(aa) );
- TQT_SOCKLEN_T sz;
- sz = sizeof( aa );
- r = ::recvfrom( fd, data, maxlen, 0,
- (struct sockaddr *)&aa, &sz );
-
- qt_socket_getportaddr( (struct sockaddr *)&aa, &pp, &pa);
-
- } else {
- r = ::read( fd, data, maxlen );
- }
- done = TRUE;
- if ( r == 0 && t == Stream && maxlen > 0 ) {
- // connection closed
- close();
- } else if ( r >= 0 || errno == EAGAIN || errno == EWOULDBLOCK ) {
- // nothing
- } else if ( errno == EINTR ) {
- done = FALSE;
- } else if ( e == NoError ) {
- switch( errno ) {
- case EIO:
- case EISDIR:
- case EBADF:
- case EINVAL:
- case EFAULT:
- case ENOTCONN:
- case ENOTSOCK:
- e = Impossible;
- break;
-#if defined(ENONET)
- case ENONET:
-#endif
- case EHOSTUNREACH:
- case ENETDOWN:
- case ENETUNREACH:
- case ETIMEDOUT:
- e = NetworkFailure;
- break;
- case EPIPE:
- case ECONNRESET:
- // connection closed
- close();
- r = 0;
- break;
- default:
- e = UnknownError;
- break;
- }
- }
- }
- return r;
-}
-
-
-/*!
- Writes \a len bytes to the socket from \a data and returns the
- number of bytes written. Returns -1 if an error occurred.
-
- This is used for \c TQSocketDevice::Stream sockets.
-*/
-TQ_LONG TQSocketDevice::writeBlock( const char *data, TQ_ULONG len )
-{
- if ( data == 0 && len != 0 ) {
-#if defined(TQT_CHECK_NULL) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Null pointer error" );
-#endif
- return -1;
- }
- if ( !isValid() ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Invalid socket" );
-#endif
- return -1;
- }
- if ( !isOpen() ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Device is not open" );
-#endif
- return -1;
- }
- if ( !isWritable() ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::writeBlock: Write operation not permitted" );
-#endif
- return -1;
- }
- bool done = FALSE;
- int r = 0;
- bool timeout;
- while ( !done ) {
- r = ::write( fd, data, len );
- done = TRUE;
- if ( r < 0 && e == NoError &&
- errno != EAGAIN && errno != EWOULDBLOCK ) {
- switch( errno ) {
- case EINTR: // signal - call read() or whatever again
- done = FALSE;
- break;
- case EPIPE:
- case ECONNRESET:
- // connection closed
- close();
- r = 0;
- break;
- case ENOSPC:
- case EIO:
- case EISDIR:
- case EBADF:
- case EINVAL:
- case EFAULT:
- case ENOTCONN:
- case ENOTSOCK:
- e = Impossible;
- break;
-#if defined(ENONET)
- case ENONET:
-#endif
- case EHOSTUNREACH:
- case ENETDOWN:
- case ENETUNREACH:
- case ETIMEDOUT:
- e = NetworkFailure;
- break;
- default:
- e = UnknownError;
- break;
- }
- } else if ( waitForMore( 0, &timeout ) == 0 ) {
- if ( !timeout ) {
- // connection closed
- close();
- }
- }
- }
- return r;
-}
-
-
-/*!
- \overload
-
- Writes \a len bytes to the socket from \a data and returns the
- number of bytes written. Returns -1 if an error occurred.
-
- This is used for \c TQSocketDevice::Datagram sockets. You must
- specify the \a host and \a port of the destination of the data.
-*/
-TQ_LONG TQSocketDevice::writeBlock( const char * data, TQ_ULONG len,
- const TQHostAddress & host, TQ_UINT16 port )
-{
- if ( t != Datagram ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::sendBlock: Not datagram" );
-#endif
- return -1; // for now - later we can do t/tcp
- }
-
- if ( data == 0 && len != 0 ) {
-#if defined(TQT_CHECK_NULL) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::sendBlock: Null pointer error" );
-#endif
- return -1;
- }
- if ( !isValid() ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::sendBlock: Invalid socket" );
-#endif
- return -1;
- }
- if ( !isOpen() ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::sendBlock: Device is not open" );
-#endif
- return -1;
- }
- if ( !isWritable() ) {
-#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
- qWarning( "TQSocketDevice::sendBlock: Write operation not permitted" );
-#endif
- return -1;
- }
- struct sockaddr_in a4;
- struct sockaddr *aa;
- TQT_SOCKLEN_T slen;
-#if !defined(TQT_NO_IPV6)
- struct sockaddr_in6 a6;
- if ( host.isIPv6Address() ) {
- memset( &a6, 0, sizeof(a6) );
- a6.sin6_family = AF_INET6;
- a6.sin6_port = htons( port );
-
- TQ_IPV6ADDR tmp = host.toIPv6Address();
- memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );
- slen = sizeof( a6 );
- aa = (struct sockaddr *)&a6;
- } else
-#endif
- if ( host.isIPv4Address() ) {
- memset( &a4, 0, sizeof(a4) );
- a4.sin_family = AF_INET;
- a4.sin_port = htons( port );
- a4.sin_addr.s_addr = htonl( host.toIPv4Address() );
- slen = sizeof(a4);
- aa = (struct sockaddr *)&a4;
- } else {
- e = Impossible;
- return -1;
- }
-
- // we'd use MSG_DONTWAIT + MSG_NOTQT_SIGNAL if Stevens were right.
- // but apparently Stevens and most implementors disagree
- bool done = FALSE;
- int r = 0;
- while ( !done ) {
- r = ::sendto( fd, data, len, 0, aa, slen);
- done = TRUE;
- if ( r < 0 && e == NoError &&
- errno != EAGAIN && errno != EWOULDBLOCK ) {
- switch( errno ) {
- case EINTR: // signal - call read() or whatever again
- done = FALSE;
- break;
- case ENOSPC:
- case EPIPE:
- case EIO:
- case EISDIR:
- case EBADF:
- case EINVAL:
- case EFAULT:
- case ENOTCONN:
- case ENOTSOCK:
- e = Impossible;
- break;
-#if defined(ENONET)
- case ENONET:
-#endif
- case EHOSTUNREACH:
- case ENETDOWN:
- case ENETUNREACH:
- case ETIMEDOUT:
- e = NetworkFailure;
- break;
- default:
- e = UnknownError;
- break;
- }
- }
- }
- return r;
-}
-
-
-/*!
- Fetches information about both ends of the connection: whatever is
- available.
-*/
-void TQSocketDevice::fetchConnectionParameters()
-{
- if ( !isValid() ) {
- p = 0;
- a = TQHostAddress();
- pp = 0;
- pa = TQHostAddress();
- return;
- }
-#if !defined(TQT_NO_IPV6)
- struct sockaddr_storage sa;
-#else
- struct sockaddr_in sa;
-#endif
- memset( &sa, 0, sizeof(sa) );
- TQT_SOCKLEN_T sz;
- sz = sizeof( sa );
- if ( !::getsockname( fd, (struct sockaddr *)(&sa), &sz ) )
- qt_socket_getportaddr( (struct sockaddr *)&sa, &p, &a );
-
- sz = sizeof( sa );
- if ( !::getpeername( fd, (struct sockaddr *)(&sa), &sz ) )
- qt_socket_getportaddr( (struct sockaddr *)&sa, &pp, &pa );
-}
-
-
-/*!
- Returns the port number of the port this socket tqdevice is
- connected to. This may be 0 for a while, but is set to something
- sensible as soon as a sensible value is available.
-
- Note that for Datagram sockets, this is the source port of the
- last packet received, and that it is in native byte order.
-*/
-TQ_UINT16 TQSocketDevice::peerPort() const
-{
- return pp;
-}
-
-
-/*!
- Returns the address of the port this socket tqdevice is connected
- to. This may be 0.0.0.0 for a while, but is set to something
- sensible as soon as a sensible value is available.
-
- Note that for Datagram sockets, this is the source port of the
- last packet received.
-*/
-TQHostAddress TQSocketDevice::peerAddress() const
-{
- return pa;
-}
-
-#endif //TQT_NO_NETWORK