📄 q3dns.cpp
字号:
Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); Q3DnsRR * 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 QStringList list = myDns.hostNames(); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; } \endcode*/QStringList Q3Dns::hostNames() const{#if defined(Q3DNS_DEBUG) qDebug( "Q3Dns::hostNames (%s)", l.ascii() );#endif QStringList result; if ( t != Ptr ) return result; Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); Q3DnsRR * rr; while( (rr=cached->current()) != 0 ) { if ( rr->current && !rr->nxdomain ) { QString 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 QStringList list = myDns.texts(); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; } \endcode*/QStringList Q3Dns::texts() const{#if defined(Q3DNS_DEBUG) qDebug( "Q3Dns::texts (%s)", l.ascii() );#endif QStringList result; if ( t != Txt ) return result; Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( this ); Q3DnsRR * rr; while( (rr=cached->current()) != 0 ) { if ( rr->current && !rr->nxdomain ) { QString 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 Q3Dns is "trolltech.com", then the canonical name for all of "lillian", "l", "lillian.troll.no." and "l.trolltech.com" is "lillian.troll.no.".*/QString Q3Dns::canonicalName() const{ // the cname should work regardless of the recordType(), so set the record // type temporarily to cname when you look at the cache Q3Dns *that = (Q3Dns*) this; // mutable function RecordType oldType = t; that->t = Cname; Q3PtrList<Q3DnsRR> * cached = Q3DnsDomain::cached( that ); that->t = oldType; Q3DnsRR * rr; while( (rr=cached->current()) != 0 ) { if ( rr->current && !rr->nxdomain && rr->domain ) { delete cached; return rr->target; } cached->next(); } delete cached; return QString();}#if defined(Q_DNS_SYNCHRONOUS)/*! \reimp*/void Q3Dns::connectNotify( const char *signal ){ if ( d->noEventLoop && qstrcmp(signal,SIGNAL(resultsReady()) )==0 ) { doSynchronousLookup(); }}#endif#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)#if defined(Q_DNS_SYNCHRONOUS)void Q3Dns::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 256typedef 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;#endiftypedef DWORD (WINAPI *GNP)( PFIXED_INFO, PULONG );// ### FIXME: this code is duplicated in qfiledialog.cppstatic QString getWindowsRegString( HKEY key, const QString &subKey ){ QString s; QT_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 = QString::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 = QLatin1String(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 = QLatin1String(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 = QLatin1String(ptr); delete [] ptr; } } ); return s;}static bool getDnsParamsFromRegistry( const QString &path, QString *domainName, QString *nameServer, QString *searchList ){ HKEY k; int r; QT_WA( { r = RegOpenKeyEx( HKEY_LOCAL_MACHINE, (TCHAR*)path.ucs2(), 0, KEY_READ, &k ); } , { r = RegOpenKeyExA( HKEY_LOCAL_MACHINE, path.latin1(), 0, KEY_READ, &k ); } ); if ( r == ERROR_SUCCESS ) { *domainName = getWindowsRegString( k, QLatin1String("DhcpDomain") ); if ( domainName->isEmpty() ) *domainName = getWindowsRegString( k, QLatin1String("Domain") ); *nameServer = getWindowsRegString( k, QLatin1String("DhcpNameServer") ); if ( nameServer->isEmpty() ) *nameServer = getWindowsRegString( k, QLatin1String("NameServer") ); *searchList = getWindowsRegString( k, QLatin1String("SearchList") ); } RegCloseKey( k ); return r == ERROR_SUCCESS;}void Q3Dns::doResInit(){ char separator = 0; if ( ns ) delete ns; ns = new Q3PtrList<QHostAddress>; ns->setAutoDelete( true ); domains = new Q3StrList( true ); domains->setAutoDelete( true ); QString domainName, nameServer, searchList; bool gotNetworkParams = false; // try the API call GetNetworkParams() first and use registry lookup only // as a fallback#ifdef Q_OS_TEMP HINSTANCE hinstLib = LoadLibraryW( L"iphlpapi" );#else HINSTANCE hinstLib = LoadLibraryA( "iphlpapi" );#endif if ( hinstLib != 0 ) {#ifdef Q_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 = QLatin1String(finfo->DomainName); nameServer = QLatin1String(""); IP_ADDR_STRING *dnsServer = &finfo->DnsServerList; while ( dnsServer != 0 ) { nameServer += QLatin1String(dnsServer->IpAddress.String); dnsServer = dnsServer->Next; if ( dnsServer != 0 ) nameServer += QLatin1String(" "); } searchList = QLatin1String(""); separator = ' '; gotNetworkParams = true; } delete[] finfo; } } FreeLibrary( hinstLib ); } if ( !gotNetworkParams ) { if ( getDnsParamsFromRegistry( QString( QLatin1String("System\\CurrentControlSet\\Services\\Tcpip\\Parameters") ), &domainName, &nameServer, &searchList )) { // for NT separator = ' '; } else if ( getDnsParamsFromRegistry( QString( QLatin1String("System\\CurrentControlSet\\Services\\VxD\\MSTCP") ), &domainName, &nameServer, &searchList )) { // for Windows 98 separator = ','; } else { // Could not access the TCP/IP parameters domainName = QLatin1String(""); nameServer = QLatin1String("127.0.0.1"); searchList = QLatin1String(""); 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(); Q3Dns tmp( nameServer.mid( first, last-first ), Q3Dns::A ); Q3ValueList<QHostAddress> address = tmp.addresses(); Q_LONG i = address.count(); while( i ) ns->append( new QHostAddress(address[--i]) ); first = last+1; } while( first < (int)nameServer.length() ); } searchList = searchList + QLatin1String(" ") + domainName; searchList = searchList.simplifyWhiteSpace().lower(); first = 0; do { last = searchList.find( QLatin1Char(separator), first ); if ( last < 0 ) last = searchList.length(); domains->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 Q3Dns::doSynchronousLookup(){ if ( t!=None && !l.isEmpty() ) { Q3ValueListIterator<QString> it = n.begin(); Q3ValueListIterator<QString> end = n.end(); int type; switch( t ) { case Q3Dns::A: type = 1; break; case Q3Dns::Aaaa: type = 28; break; case Q3Dns::Mx: type = 15; break; case Q3Dns::Srv: type = 33; break; case Q3Dns::Cname: type = 5; break; case Q3Dns::Ptr: type = 12; break; case Q3Dns::Txt: type = 16; break; default: type = (char)255; // any break; } while( it != end ) { QString s = *it; it++; QByteArray ba( 512 ); int len = res_search( s.latin1(), 1, type, (uchar*)ba.data(), ba.size() ); if ( len > 0 ) { ba.resize( len ); Q3DnsQuery * query = new Q3DnsQuery; query->started = now(); query->id = ++::id; query->t = t; query->l = s; Q3DnsAnswer 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#endifvoid Q3Dns::doResInit(){ if ( ns ) return; ns = new Q3PtrList<QHostAddress>; ns->setAutoDelete( true ); domains = new Q3StrList( true ); domains->setAutoDelete( true ); // read resolv.conf manually. QFile resolvConf(QLatin1String("/etc/resolv.conf")); if (resolvConf.open(QIODevice::ReadOnly)) { QTextStream stream( &resolvConf ); QString line; while ( !stream.atEnd() ) { line = stream.readLine(); QStringList list = QStringList::split( QLatin1String(" "), line ); if( line.startsWith( QLatin1String("#") ) || list.size() < 2 ) continue; const QString type = list[0].lower(); if ( type == QLatin1String("nameserver") ) { QHostAddress *address = new QHostAddress(); if ( address->setAddress( QString(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 == QLatin1String("search") ) { QStringList srch = QStringList::split( QLatin1String(" "), list[1] ); for ( QStringList::Iterator i = srch.begin(); i != srch.end(); ++i ) domains->append( (*i).lower().local8Bit() ); } else if ( type == QLatin1String("domain") ) { domains->append( list[1].lower().local8Bit() ); } } } if (ns->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++ ) ns->append( new QHostAddress( 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( QString::fromLatin1( res.dnsrch[i] ).lower().local8Bit() ); else break; }# endif if ( *res.defdname ) domains->append( QString::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++ ) ns->append( new QHostAddress( 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( QString::fromLatin1( _res.dnsrch[i] ).lower().local8Bit() ); else break; }# endif if ( *_res.defdname ) domains->append( QString::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. ns->first(); while( ns->current() ) { if ( ns->current()->isNull() ) delete ns->take(); else ns->next(); } } QFile hosts( QString::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 ); QString line; while( !i.atEnd() ) { line = 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++; QString ip = line.left( n ); QHostAddress 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() )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -