#include <q3dns.h>
Inheritance diagram for Q3Dns:


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.
Q3Dns 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 not straightforward to use (although it is much simpler than the native APIs); Q3Socket provides much easier to use TCP connection facilities. The aim of Q3Dns 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 Q3Dns 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.
Definition at line 43 of file q3dns.h.
Public Types | |
| enum | RecordType |
Signals | |
| void | resultsReady () |
Public Member Functions | |
| Q3Dns () | |
| Q3Dns (const QString &label, RecordType rr=A) | |
| Q3Dns (const QHostAddress &address, RecordType rr=Ptr) | |
| virtual | ~Q3Dns () |
| virtual void | setLabel (const QString &label) |
| virtual void | setLabel (const QHostAddress &address) |
| QString | label () const |
| virtual void | setRecordType (RecordType rr=A) |
| RecordType | recordType () const |
| bool | isWorking () const |
| Q3ValueList< QHostAddress > | addresses () const |
| Q3ValueList< MailServer > | mailServers () const |
| Q3ValueList< Server > | servers () const |
| QStringList | hostNames () const |
| QStringList | texts () const |
| QString | canonicalName () const |
| QStringList | qualifiedNames () const |
Private Slots | |
| void | startQuery () |
Private Member Functions | |
| void | setStartQueryTimer () |
Static Private Member Functions | |
| static void | doResInit () |
| static QString | toInAddrArpaDomain (const QHostAddress &address) |
Private Attributes | |
| QString | l |
| QStringList | n |
| RecordType | t |
| Q3DnsPrivate * | d |
Friends | |
| class | Q3DnsAnswer |
| class | Q3DnsManager |
Classes | |
| class | MailServer |
| The Q3Dns::MailServer class is described in Q3Dns::mailServers(). More... | |
| class | Server |
| The Q3Dns::Server class is described in Q3Dns::servers(). More... | |
| enum Q3Dns::RecordType |
This enum type defines the record types Q3Dns 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:
None No information. This exists only so that Q3Dns can have a default.
A IPv4 addresses. By far the most common type.
Aaaa IPv6 addresses. So far mostly unused.
Mx Mail eXchanger names. Used for mail delivery.
Srv SeRVer names. Generic record type for finding servers. So far mostly unused.
Cname Canonical names. Maps from nicknames to the true name (the canonical name) for a host.
Ptr name PoinTeRs. Maps from IPv4 or IPv6 addresses to hostnames.
Txt arbitrary TeXT for domains.
We expect that some support for the {http://www.rfc-editor.org/rfc/rfc2535.txt}{RFC 2535} extensions will be added in future versions.
Definition at line 46 of file q3dns.h.
| Q3Dns::Q3Dns | ( | ) |
| Q3Dns::Q3Dns | ( | const QString & | label, | |
| RecordType | rr = A | |||
| ) |
Constructs a DNS query object that will return record type rr information about 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.
rr defaults to A, IPv4 addresses.
Definition at line 1626 of file q3dns.cpp.
References d, label(), setLabel(), setStartQueryTimer(), and t.
01627 { 01628 d = new Q3DnsPrivate; 01629 t = rr; 01630 setLabel( label ); 01631 setStartQueryTimer(); // start query the next time we enter event loop 01632 }
Here is the call graph for this function:

| Q3Dns::Q3Dns | ( | const QHostAddress & | address, | |
| RecordType | rr = Ptr | |||
| ) |
Constructs a DNS query object that will return record type rr information about host address address. The label is set to the IN-ADDR.ARPA domain name. This is useful in combination with the 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.
rr defaults to Ptr, that maps addresses to hostnames.
Definition at line 1650 of file q3dns.cpp.
References d, setLabel(), setStartQueryTimer(), and t.
01651 { 01652 d = new Q3DnsPrivate; 01653 t = rr; 01654 setLabel( address ); 01655 setStartQueryTimer(); // start query the next time we enter event loop 01656 }
Here is the call graph for this function:

| Q3Dns::~Q3Dns | ( | ) | [virtual] |
Destroys the DNS query object and frees its allocated resources.
Definition at line 1665 of file q3dns.cpp.
References d, globalManager, and m.
01666 { 01667 if ( globalManager ) { 01668 uint q = 0; 01669 Q3DnsManager * m = globalManager; 01670 while( q < m->queries.size() ) { 01671 Q3DnsQuery * query=m->queries[q]; 01672 if ( query && query->dns ) 01673 (void)query->dns->take( (void*) this ); 01674 q++; 01675 } 01676 01677 } 01678 01679 delete d; 01680 d = 0; 01681 }
| void Q3Dns::setLabel | ( | const QString & | label | ) | [virtual] |
Sets this DNS query object to query for information about 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.
Definition at line 1698 of file q3dns.cpp.
References QList< T >::append(), QList< T >::clear(), QList< T >::count(), d, domains, i, int, l, label(), QString::left(), QString::length(), QUnicodeTables::lower(), Q3DnsManager::manager(), n, Q3DnsPrivate::noNames, Q3StrListIterator, qDebug(), and setStartQueryTimer().
Referenced by Q3Dns(), and setLabel().
01699 { 01700 l = label; 01701 d->noNames = false; 01702 01703 // construct a list of qualified names 01704 n.clear(); 01705 if ( l.length() > 1 && l[(int)l.length()-1] == '.' ) { 01706 n.append( l.left( l.length()-1 ).lower() ); 01707 } else { 01708 int i = l.length(); 01709 int dots = 0; 01710 const int maxDots = 2; 01711 while( i && dots < maxDots ) { 01712 if ( l[--i] == '.' ) 01713 dots++; 01714 } 01715 if ( dots < maxDots ) { 01716 (void)Q3DnsManager::manager(); // create a Q3DnsManager, if it is not already there 01717 Q3StrListIterator it( *domains ); 01718 const char * dom; 01719 while( (dom=it.current()) != 0 ) { 01720 ++it; 01721 n.append( l.lower() + "." + dom ); 01722 } 01723 } 01724 n.append( l.lower() ); 01725 } 01726 01727 #if defined(Q_DNS_SYNCHRONOUS) 01728 if ( d->noEventLoop ) { 01729 doSynchronousLookup(); 01730 } else { 01731 setStartQueryTimer(); // start query the next time we enter event loop 01732 } 01733 #else 01734 setStartQueryTimer(); // start query the next time we enter event loop 01735 #endif 01736 #if defined(Q3DNS_DEBUG) 01737 qDebug( "Q3Dns::setLabel: %d address(es) for %s", n.count(), l.ascii() ); 01738 int i = 0; 01739 for( i = 0; i < (int)n.count(); i++ ) 01740 qDebug( "Q3Dns::setLabel: %d: %s", i, n[i].ascii() ); 01741 #endif 01742 }
Here is the call graph for this function:

| void Q3Dns::setLabel | ( | const QHostAddress & | address | ) | [virtual] |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. Sets this DNS query object to query for information about the host address address. The label is set to the IN-ADDR.ARPA domain name. This is useful in combination with the Ptr record type (e.g. if you want to look up a hostname for a given address).
Definition at line 1754 of file q3dns.cpp.
References setLabel(), and toInAddrArpaDomain().
01755 { 01756 setLabel( toInAddrArpaDomain( address ) ); 01757 }
Here is the call graph for this function:

| QString Q3Dns::label | ( | ) | const [inline] |
Returns the domain name for which this object returns information.
Definition at line 63 of file q3dns.h.
References l.
Referenced by Q3DnsDomain::cached(), Q3DnsAnswer::notify(), Q3Dns(), setLabel(), and Q3DnsUgleHack::ugle().
00063 { return l; }
| void Q3Dns::setRecordType | ( | RecordType | rr = A |
) | [virtual] |
Sets this object to query for record type 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.
Definition at line 1829 of file q3dns.cpp.
References d, Q3DnsPrivate::noNames, setStartQueryTimer(), and t.
01830 { 01831 t = rr; 01832 d->noNames = false; 01833 setStartQueryTimer(); // start query the next time we enter event loop 01834 }
Here is the call graph for this function:

| Q3Dns::RecordType Q3Dns::recordType | ( | ) | const [inline] |
Returns the record type of this DNS query object.
Definition at line 66 of file q3dns.h.
References t.
Referenced by Q3DnsDomain::cached(), and Q3DnsUgleHack::ugle().
00066 { return t; }
| bool Q3Dns::isWorking | ( | ) | const |
Returns true if Q3Dns is doing a lookup for this object (i.e. if it does not already have the necessary information); otherwise returns false.
Q3Dns emits the resultsReady() signal when the status changes to false.
Definition at line 1924 of file q3dns.cpp.
References Q3DnsDomain::cached(), QList< T >::count(), Q3PtrList< type >::current(), d, l, n, Q3PtrList< type >::next(), Q3DnsPrivate::noNames, None, Q3DnsRR::nxdomain, qDebug(), and t.
Referenced by startQuery(), Q3Socket::tryConnecting(), and Q3DnsUgleHack::ugle().
01925 { 01926 #if defined(Q3DNS_DEBUG) 01927 qDebug( "Q3Dns::isWorking (%s, %d)", l.ascii(), t ); 01928 #endif 01929 if ( t == None ) 01930 return false; 01931 01932 #if defined(Q_DNS_SYNCHRONOUS) 01933 if ( d->noEventLoop ) 01934 return true; 01935 #endif 01936 01937 Q3PtrList<Q3DnsRR> * ll = Q3DnsDomain::cached( this ); 01938 Q_LONG queries = n.count(); 01939 while( ll->current() != 0 ) { 01940 if ( ll->current()->nxdomain ) { 01941 queries--; 01942 } else { 01943 delete ll; 01944 return false; 01945 } 01946 ll->next(); 01947 } 01948 delete ll; 01949 01950 if ( queries <= 0 ) 01951 return false; 01952 if ( d->noNames ) 01953 return false; 01954 return true; 01955 }
Here is the call graph for this function:

| Q3ValueList< QHostAddress > Q3Dns::addresses | ( | ) | const |
Returns a list of the addresses for this name if this Q3Dns object has a recordType() of Q3Dns::A or Q3Dns::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.
Q3ValueList<QHostAddress> list = myDns.addresses(); Q3ValueList<QHostAddress>::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 1979 of file q3dns.cpp.
References A, Aaaa, Q3DnsRR::address, Q3DnsDomain::cached(), cached(), Q3DnsRR::current, l, Q3DnsRR::nxdomain, qDebug(), and t.
Referenced by Q3Socket::tryConnecting().
01980 { 01981 #if defined(Q3DNS_DEBUG) 01982 qDebug( "Q3Dns::addresses (%s)", l.ascii() ); 01983 #endif 01984 Q3ValueList<QHostAddress> result; 01985 if ( t != A && t != Aaaa ) 01986 return result; 01987 01988 Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); 01989 01990 Q3DnsRR * rr; 01991 while( (rr=cached->current()) != 0 ) { 01992 if ( rr->current && !rr->nxdomain ) 01993 result.append( rr->address ); 01994 cached->next(); 01995 } 01996 delete cached; 01997 return result; 01998 }
Here is the call graph for this function:

| Q3ValueList< Q3Dns::MailServer > Q3Dns::mailServers | ( | ) | const |
Returns a list of mail servers if the record type is Mx. The class Q3Dns::MailServer contains the following public variables: QString Q3Dns::MailServer::name Q_UINT16 Q3Dns::MailServer::priority
Note that if you want to iterate over the list, you should iterate over a copy, e.g.
Q3ValueList<Q3Dns::MailServer> list = myDns.mailServers(); Q3ValueList<Q3Dns::MailServer>::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 2028 of file q3dns.cpp.
References Q3DnsDomain::cached(), cached(), Q3DnsRR::current, l, Mx, Q3DnsRR::nxdomain, Q3DnsRR::priority, qDebug(), t, and Q3DnsRR::target.
02029 { 02030 #if defined(Q3DNS_DEBUG) 02031 qDebug( "Q3Dns::mailServers (%s)", l.ascii() ); 02032 #endif 02033 Q3ValueList<Q3Dns::MailServer> result; 02034 if ( t != Mx ) 02035 return result; 02036 02037 Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); 02038 02039 Q3DnsRR * rr; 02040 while( (rr=cached->current()) != 0 ) { 02041 if ( rr->current && !rr->nxdomain ) { 02042 MailServer ms( rr->target, rr->priority ); 02043 result.append( ms ); 02044 } 02045 cached->next(); 02046 } 02047 delete cached; 02048 return result; 02049 }
Here is the call graph for this function:

| Q3ValueList< Q3Dns::Server > Q3Dns::servers | ( | ) | const |
Returns a list of servers if the record type is Srv. The class Q3Dns::Server contains the following public variables: QString Q3Dns::Server::name Q_UINT16 Q3Dns::Server::priority Q_UINT16 Q3Dns::Server::weight Q_UINT16 Q3Dns::Server::port
Note that if you want to iterate over the list, you should iterate over a copy, e.g.
Q3ValueList<Q3Dns::Server> list = myDns.servers(); Q3ValueList<Q3Dns::Server>::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 2080 of file q3dns.cpp.
References Q3DnsDomain::cached(), cached(), Q3DnsRR::current, l, Q3DnsRR::nxdomain, Q3DnsRR::port, Q3DnsRR::priority, qDebug(), s, Srv, t, Q3DnsRR::target, and Q3DnsRR::weight.
02081 { 02082 #if defined(Q3DNS_DEBUG) 02083 qDebug( "Q3Dns::servers (%s)", l.ascii() ); 02084 #endif 02085 Q3ValueList<Q3Dns::Server> result; 02086 if ( t != Srv ) 02087 return result; 02088 02089 Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); 02090 02091 Q3DnsRR * rr; 02092 while( (rr=cached->current()) != 0 ) { 02093 if ( rr->current && !rr->nxdomain ) { 02094 Server s( rr->target, rr->priority, rr->weight, rr->port ); 02095 result.append( s ); 02096 } 02097 cached->next(); 02098 } 02099 delete cached; 02100 return result; 02101 }
Here is the call graph for this function:

| QStringList Q3Dns::hostNames | ( | ) | const |
Returns a list of host names if the record type is Ptr.
Note that if you want to iterate over the list, you should iterate over a copy, e.g.
QStringList list = myDns.hostNames(); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 2119 of file q3dns.cpp.
References Q3DnsDomain::cached(), cached(), Q3DnsRR::current, l, Q3DnsRR::nxdomain, Ptr, qDebug(), t, and Q3DnsRR::target.
02120 { 02121 #if defined(Q3DNS_DEBUG) 02122 qDebug( "Q3Dns::hostNames (%s)", l.ascii() ); 02123 #endif 02124 QStringList result; 02125 if ( t != Ptr ) 02126 return result; 02127 02128 Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); 02129 02130 Q3DnsRR * rr; 02131 while( (rr=cached->current()) != 0 ) { 02132 if ( rr->current && !rr->nxdomain ) { 02133 QString str( rr->target ); 02134 result.append( str ); 02135 } 02136 cached->next(); 02137 } 02138 delete cached; 02139 return result; 02140 }
Here is the call graph for this function:

| QStringList Q3Dns::texts | ( | ) | const |
Returns a list of texts if the record type is Txt.
Note that if you want to iterate over the list, you should iterate over a copy, e.g.
QStringList list = myDns.texts(); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 2157 of file q3dns.cpp.
References Q3DnsDomain::cached(), cached(), Q3DnsRR::current, l, Q3DnsRR::nxdomain, qDebug(), t, Q3DnsRR::text, and Txt.
02158 { 02159 #if defined(Q3DNS_DEBUG) 02160 qDebug( "Q3Dns::texts (%s)", l.ascii() ); 02161 #endif 02162 QStringList result; 02163 if ( t != Txt ) 02164 return result; 02165 02166 Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); 02167 02168 Q3DnsRR * rr; 02169 while( (rr=cached->current()) != 0 ) { 02170 if ( rr->current && !rr->nxdomain ) { 02171 QString str( rr->text ); 02172 result.append( str ); 02173 } 02174 cached->next(); 02175 } 02176 delete cached; 02177 return result; 02178 }
Here is the call graph for this function:

| QString Q3Dns::canonicalName | ( | ) | const |
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 Q3Dns is "trolltech.com", then the canonical name for all of "lillian", "l", "lillian.troll.no." and "l.trolltech.com" is "lillian.troll.no.".
Definition at line 2196 of file q3dns.cpp.
References Q3DnsDomain::cached(), cached(), Cname, Q3DnsRR::current, Q3DnsRR::domain, Q3DnsRR::nxdomain, t, and Q3DnsRR::target.
02197 { 02198 // the cname should work regardless of the recordType(), so set the record 02199 // type temporarily to cname when you look at the cache 02200 Q3Dns *that = (Q3Dns*) this; // mutable function 02201 RecordType oldType = t; 02202 that->t = Cname; 02203 Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( that ); 02204 that->t = oldType; 02205 02206 Q3DnsRR * rr; 02207 while( (rr=cached->current()) != 0 ) { 02208 if ( rr->current && !rr->nxdomain && rr->domain ) { 02209 delete cached; 02210 return rr->target; 02211 } 02212 cached->next(); 02213 } 02214 delete cached; 02215 return QString(); 02216 }
Here is the call graph for this function:

| QStringList Q3Dns::qualifiedNames | ( | ) | const [inline] |
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.
QStringList list = myDns.qualifiedNames(); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 102 of file q3dns.h.
References n.
Referenced by Q3DnsDomain::cached().
00102 { return n; }
| void Q3Dns::resultsReady | ( | ) | [signal] |
This signal is emitted when results are available for one of the qualifiedNames().
Referenced by startQuery(), and Q3DnsUgleHack::ugle().
| void Q3Dns::startQuery | ( | ) | [private, slot] |
Definition at line 1841 of file q3dns.cpp.
References emit, isWorking(), and resultsReady().
Referenced by setStartQueryTimer().
01842 { 01843 // isWorking() starts the query (if necessary) 01844 if ( !isWorking() ) 01845 emit resultsReady(); 01846 }
| void Q3Dns::doResInit | ( | ) | [static, private] |
Definition at line 2495 of file q3dns.cpp.
References a, A, Aaaa, Q3DnsRR::address, Q3PtrList< type >::append(), QList< T >::begin(), Q3DnsRR::current, Q3DnsRR::deleteTime, domains, QList< T >::end(), Q3DnsRR::expireTime, QString::fromLatin1(), i, int, ipv6support, QUnicodeTables::isSpace(), QString::left(), QString::length(), QUnicodeTables::lower(), QString::mid(), n, ns, QFile::open(), Ptr, ptr, QIODevice::ReadOnly, res_init(), QHostAddress::setAddress(), Q3PtrCollection::setAutoDelete(), QList< T >::size(), QString::startsWith(), QTest::stream, Q3DnsRR::t, toInAddrArpaDomain(), QString::truncate(), and type.
Referenced by Q3DnsManager::Q3DnsManager(), and Q3DnsManager::transmitQuery().
02496 { 02497 if ( ns ) 02498 return; 02499 ns = new Q3PtrList<QHostAddress>; 02500 ns->setAutoDelete( true ); 02501 domains = new Q3StrList( true ); 02502 domains->setAutoDelete( true ); 02503 02504 // read resolv.conf manually. 02505 QFile resolvConf("/etc/resolv.conf"); 02506 if (resolvConf.open(QIODevice::ReadOnly)) { 02507 QTextStream stream( &resolvConf ); 02508 QString line; 02509 02510 while ( !stream.atEnd() ) { 02511 line = stream.readLine(); 02512 QStringList list = QStringList::split( " ", line ); 02513 if( line.startsWith( "#" ) || list.size() < 2 ) 02514 continue; 02515 const QString type = list[0].lower(); 02516 02517 if ( type == "nameserver" ) { 02518 QHostAddress *address = new QHostAddress(); 02519 if ( address->setAddress( QString(list[1]) ) ) { 02520 // only add ipv6 addresses from resolv.conf if 02521 // this host supports ipv6. 02522 if ( address->isIPv4Address() || ipv6support ) 02523 ns->append( address ); 02524 else 02525 delete address; 02526 } else { 02527 delete address; 02528 } 02529 } else if ( type == "search" ) { 02530 QStringList srch = QStringList::split( " ", list[1] ); 02531 for ( QStringList::Iterator i = srch.begin(); i != srch.end(); ++i ) 02532 domains->append( (*i).lower().local8Bit() ); 02533 02534 } else if ( type == "domain" ) { 02535 domains->append( list[1].lower().local8Bit() ); 02536 } 02537 } 02538 } 02539 02540 if (ns->isEmpty()) { 02541 #if defined(Q_MODERN_RES_API) 02542 struct __res_state res; 02543 res_ninit( &res ); 02544 int i; 02545 // find the name servers to use 02546 for( i=0; i < MAXNS && i < res.nscount; i++ ) 02547 ns->append( new QHostAddress( ntohl( res.nsaddr_list[i].sin_addr.s_addr ) ) ); 02548 # if defined(MAXDFLSRCH) 02549 for( i=0; i < MAXDFLSRCH; i++ ) { 02550 if ( res.dnsrch[i] && *(res.dnsrch[i]) ) 02551 domains->append( QString::fromLatin1( res.dnsrch[i] ).lower().local8Bit() ); 02552 else 02553 break; 02554 } 02555 # endif 02556 if ( *res.defdname ) 02557 domains->append( QString::fromLatin1( res.defdname ).lower().local8Bit() ); 02558 #else 02559 res_init(); 02560 int i; 02561 // find the name servers to use 02562 for( i=0; i < MAXNS && i < _res.nscount; i++ ) 02563 ns->append( new QHostAddress( ntohl( _res.nsaddr_list[i].sin_addr.s_addr ) ) ); 02564 # if defined(MAXDFLSRCH) 02565 for( i=0; i < MAXDFLSRCH; i++ ) { 02566 if ( _res.dnsrch[i] && *(_res.dnsrch[i]) ) 02567 domains->append( QString::fromLatin1( _res.dnsrch[i] ).lower().local8Bit() ); 02568 else 02569 break; 02570 } 02571 # endif 02572 if ( *_res.defdname ) 02573 domains->append( QString::fromLatin1( _res.defdname ).lower().local8Bit() ); 02574 #endif 02575 02576 // the code above adds "0.0.0.0" as a name server at the slightest 02577 // hint of trouble. so remove those again. 02578 ns->first(); 02579 while( ns->current() ) { 02580 if ( ns->current()->isNull() ) 02581 delete ns->take(); 02582 else 02583 ns->next(); 02584 } 02585 } 02586 02587 QFile hosts( QString::fromLatin1( "/etc/hosts" ) ); 02588 if ( hosts.open( QIODevice::ReadOnly ) ) { 02589 // read the /etc/hosts file, creating long-life A and PTR RRs 02590 // for the things we find. 02591 QTextStream i( &hosts ); 02592 QString line; 02593 while( !i.atEnd() ) { 02594 line = i.readLine().simplifyWhiteSpace().lower(); 02595 uint n = 0; 02596 while( (int) n < line.length() && line[(int)n] != '#' ) 02597 n++; 02598 line.truncate( n ); 02599 n = 0; 02600 while( (int) n < line.length() && !line[(int)n].isSpace() ) 02601 n++; 02602 QString ip = line.left( n ); 02603 QHostAddress a; 02604 a.setAddress( ip ); 02605 if ( ( a.isIPv4Address() || a.isIPv6Address() ) && !a.isNull() ) { 02606 bool first = true; 02607 line = line.mid( n+1 ); 02608 n = 0; 02609 while( (int) n < line.length() && !line[(int)n].isSpace() ) 02610 n++; 02611 QString hostname = line.left( n ); 02612 // ### in case of bad syntax, hostname is invalid. do we care? 02613 if ( n ) { 02614 Q3DnsRR * rr = new Q3DnsRR( hostname ); 02615 if ( a.isIPv4Address() ) 02616 rr->t = Q3Dns::A; 02617 else 02618 rr->t = Q3Dns::Aaaa; 02619 rr->address = a; 02620 rr->deleteTime = UINT_MAX; 02621 rr->expireTime = UINT_MAX; 02622 rr->current = true; 02623 if ( first ) { 02624 first = false; 02625 Q3DnsRR * ptr = new Q3DnsRR( Q3Dns::toInAddrArpaDomain( a ) ); 02626 ptr->t = Q3Dns::Ptr; 02627 ptr->target = hostname; 02628 ptr->deleteTime = UINT_MAX; 02629 ptr->expireTime = UINT_MAX; 02630 ptr->current = true; 02631 } 02632 } 02633 } 02634 } 02635 } 02636 }
Here is the call graph for this function:

| void Q3Dns::setStartQueryTimer | ( | ) | [private] |
The three functions Q3Dns::Q3Dns(QString, RecordType), Q3Dns::setLabel() and Q3Dns::setRecordType() may start a DNS lookup. This function handles setting up the single shot timer.
Definition at line 1853 of file q3dns.cpp.
References QObject::connect(), d, Q3DnsPrivate::queryTimer, SIGNAL, SLOT, QTimer::start(), and startQuery().
Referenced by Q3Dns(), setLabel(), and setRecordType().
01854 { 01855 #if defined(Q_DNS_SYNCHRONOUS) 01856 if ( !d->queryTimer && !d->noEventLoop ) 01857 #else 01858 if ( !d->queryTimer ) 01859 #endif 01860 { 01861 // start the query the next time we enter event loop 01862 d->queryTimer = new QTimer( this ); 01863 connect( d->queryTimer, SIGNAL(timeout()), 01864 this, SLOT(startQuery()) ); 01865 d->queryTimer->start( 0, true ); 01866 } 01867 }
Here is the call graph for this function:

| QString Q3Dns::toInAddrArpaDomain | ( | const QHostAddress & | address | ) | [static, private] |
Definition at line 1875 of file q3dns.cpp.
References b, i, QHostAddress::isNull(), QString::number(), s, and QHostAddress::toIPv6Address().
Referenced by doResInit(), and setLabel().
01876 { 01877 QString s; 01878 if ( address.isNull() ) { 01879 // if the address isn't valid, neither of the other two make 01880 // cases make sense. better to just return. 01881 } else if ( address.isIp4Addr() ) { 01882 Q_UINT32 i = address.ip4Addr(); 01883 s.sprintf( "%d.%d.%d.%d.IN-ADDR.ARPA", 01884 i & 0xff, (i >> 8) & 0xff, (i>>16) & 0xff, (i>>24) & 0xff ); 01885 } else { 01886 // RFC 3152. (1886 is deprecated, and clients no longer need to 01887 // support it, in practice). 01888 Q_IPV6ADDR i = address.toIPv6Address(); 01889 s = "ip6.arpa"; 01890 uint b = 0; 01891 while( b < 16 ) { 01892 s = QString::number( i.c[b]%16, 16 ) + "." + 01893 QString::number( i.c[b]/16, 16 ) + "." + s; 01894 b++; 01895 } 01896 } 01897 return s; 01898 }
Here is the call graph for this function:

friend class Q3DnsAnswer [friend] |
friend class Q3DnsManager [friend] |
Definition at line 123 of file q3dns.h.
Referenced by addresses(), hostNames(), isWorking(), mailServers(), servers(), setLabel(), and texts().
QStringList Q3Dns::n [private] |
RecordType Q3Dns::t [private] |
Definition at line 125 of file q3dns.h.
Referenced by addresses(), canonicalName(), hostNames(), isWorking(), mailServers(), Q3Dns(), servers(), setRecordType(), and texts().
Q3DnsPrivate* Q3Dns::d [private] |
Definition at line 126 of file q3dns.h.
Referenced by isWorking(), Q3Dns(), setLabel(), setRecordType(), setStartQueryTimer(), and ~Q3Dns().
1.5.1