kresolver.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,159 行 · 第 1/2 页
CPP
1,159 行
msg.arg(QString::fromLocal8Bit(strerror(syserror))); return msg;}KResolverResultsKResolver::resolve(const QString& host, const QString& service, int flags, int families){ KResolver qres(host, service, qApp, "synchronous KResolver"); qres.setFlags(flags); qres.setFamily(families); qres.start(); qres.wait(); return qres.results();}bool KResolver::resolveAsync(QObject* userObj, const char *userSlot, const QString& host, const QString& service, int flags, int families){ KResolver* qres = new KResolver(host, service, qApp, "asynchronous KResolver"); QObject::connect(qres, SIGNAL(finished(KResolverResults)), userObj, userSlot); qres->setFlags(flags); qres->setFamily(families); qres->d->deleteWhenDone = true; // this is the only difference from the example code return qres->start();}QStrList KResolver::protocolName(int protonum){ struct protoent *pe;#ifndef HAVE_GETPROTOBYNAME_R QMutexLocker locker(&getXXbyYYmutex); pe = getprotobynumber(protonum);#else size_t buflen = 1024; struct protoent protobuf; char *buf; do { buf = new char[buflen];# ifdef USE_SOLARIS // Solaris uses a 4 argument getprotobynumber_r which returns struct *protoent or NULL if ((pe = getprotobynumber_r(protonum, &protobuf, buf, buflen)) && (errno == ERANGE))# else if (getprotobynumber_r(protonum, &protobuf, buf, buflen, &pe) == ERANGE)# endif { buflen += 1024; delete [] buf; } else break; } while (pe == 0L);#endif // Do common processing QStrList lst(true); // use deep copies if (pe != NULL) { lst.append(pe->p_name); for (char **p = pe->p_aliases; *p; p++) lst.append(*p); }#ifdef HAVE_GETPROTOBYNAME_R delete [] buf;#endif return lst;}QStrList KResolver::protocolName(const char *protoname){ struct protoent *pe;#ifndef HAVE_GETPROTOBYNAME_R QMutexLocker locker(&getXXbyYYmutex); pe = getprotobyname(protoname);#else size_t buflen = 1024; struct protoent protobuf; char *buf; do { buf = new char[buflen];# ifdef USE_SOLARIS // Solaris uses a 4 argument getprotobyname_r which returns struct *protoent or NULL if ((pe = getprotobyname_r(protoname, &protobuf, buf, buflen)) && (errno == ERANGE))# else if (getprotobyname_r(protoname, &protobuf, buf, buflen, &pe) == ERANGE)# endif { buflen += 1024; delete [] buf; } else break; } while (pe == 0L);#endif // Do common processing QStrList lst(true); // use deep copies if (pe != NULL) { lst.append(pe->p_name); for (char **p = pe->p_aliases; *p; p++) lst.append(*p); }#ifdef HAVE_GETPROTOBYNAME_R delete [] buf;#endif return lst;}int KResolver::protocolNumber(const char *protoname){ struct protoent *pe;#ifndef HAVE_GETPROTOBYNAME_R QMutexLocker locker(&getXXbyYYmutex); pe = getprotobyname(protoname);#else size_t buflen = 1024; struct protoent protobuf; char *buf; do { buf = new char[buflen];# ifdef USE_SOLARIS // Solaris uses a 4 argument getprotobyname_r which returns struct *protoent or NULL if ((pe = getprotobyname_r(protoname, &protobuf, buf, buflen)) && (errno == ERANGE))# else if (getprotobyname_r(protoname, &protobuf, buf, buflen, &pe) == ERANGE)# endif { buflen += 1024; delete [] buf; } else break; } while (pe == 0L);#endif // Do common processing int protonum = -1; if (pe != NULL) protonum = pe->p_proto;#ifdef HAVE_GETPROTOBYNAME_R delete [] buf;#endif return protonum;}int KResolver::servicePort(const char *servname, const char *protoname){ struct servent *se;#ifndef HAVE_GETSERVBYNAME_R QMutexLocker locker(&getXXbyYYmutex); se = getservbyname(servname, protoname);#else size_t buflen = 1024; struct servent servbuf; char *buf; do { buf = new char[buflen];# ifdef USE_SOLARIS // Solaris uses a 5 argument getservbyname_r which returns struct *servent or NULL if ((se = getservbyname_r(servname, protoname, &servbuf, buf, buflen)) && (errno == ERANGE))# else if (getservbyname_r(servname, protoname, &servbuf, buf, buflen, &se) == ERANGE)# endif { buflen += 1024; delete [] buf; } else break; } while (se == 0L);#endif // Do common processing int servport = -1; if (se != NULL) servport = ntohs(se->s_port);#ifdef HAVE_GETSERVBYNAME_R delete [] buf;#endif return servport;}QStrList KResolver::serviceName(const char* servname, const char *protoname){ struct servent *se;#ifndef HAVE_GETSERVBYNAME_R QMutexLocker locker(&getXXbyYYmutex); se = getservbyname(servname, protoname);#else size_t buflen = 1024; struct servent servbuf; char *buf; do { buf = new char[buflen];# ifdef USE_SOLARIS // Solaris uses a 5 argument getservbyname_r which returns struct *servent or NULL if ((se = getservbyname_r(servname, protoname, &servbuf, buf, buflen)) && (errno == ERANGE))# else if (getservbyname_r(servname, protoname, &servbuf, buf, buflen, &se) == ERANGE)# endif { buflen += 1024; delete [] buf; } else break; } while (se == 0L);#endif // Do common processing QStrList lst(true); // use deep copies if (se != NULL) { lst.append(se->s_name); for (char **p = se->s_aliases; *p; p++) lst.append(*p); }#ifdef HAVE_GETSERVBYNAME_R delete [] buf;#endif return lst;}QStrList KResolver::serviceName(int port, const char *protoname){ struct servent *se;#ifndef HAVE_GETSERVBYPORT_R QMutexLocker locker(&getXXbyYYmutex); se = getservbyport(port, protoname);#else size_t buflen = 1024; struct servent servbuf; char *buf; do { buf = new char[buflen];# ifdef USE_SOLARIS // Solaris uses a 5 argument getservbyport_r which returns struct *servent or NULL if ((se = getservbyport_r(port, protoname, &servbuf, buf, buflen)) && (errno == ERANGE))# else if (getservbyport_r(port, protoname, &servbuf, buf, buflen, &se) == ERANGE)# endif { buflen += 1024; delete [] buf; } else break; } while (se == 0L);#endif // Do common processing QStrList lst(true); // use deep copies if (se != NULL) { lst.append(se->s_name); for (char **p = se->s_aliases; *p; p++) lst.append(*p); }#ifdef HAVE_GETSERVBYPORT_R delete [] buf;#endif return lst;}QString KResolver::localHostName(){ QCString name; int len;#ifdef MAXHOSTNAMELEN len = MAXHOSTNAMELEN;#else len = 256;#endif while (true) { name.resize(len); if (gethostname(name.data(), len - 1) == 0) { // Call succeeded, but it's not guaranteed to be NUL-terminated // Note that some systems return success even if they did truncation name[len - 1] = '\0'; break; } // Call failed if (errno == ENAMETOOLONG || errno == EINVAL) len += 256; else { // Oops! Unknown error! name = QCString(); } } if (name.isEmpty()) return QString::fromLatin1("localhost"); if (name.find('.') == -1) { // not fully qualified // must resolve KResolverResults results = resolve(name, "0", CanonName); if (results.isEmpty()) // cannot find a valid hostname! return QString::fromLatin1("localhost"); else return results.first().canonicalName(); } return domainToUnicode(name);}// forward declarationstatic QStringList splitLabels(const QString& unicodeDomain);static QCString ToASCII(const QString& label);static QString ToUnicode(const QString& label);static QStringList *KResolver_initIdnDomains(){ const char *kde_use_idn = getenv("KDE_USE_IDN"); if (!kde_use_idn) kde_use_idn = "ac:at:br:ch:cl:cn:de:dk:fi:hu:info:io:jp:kr:li:lt:museum:no:se:sh:th:tm:tw:vn"; return new QStringList(QStringList::split(':', QString::fromLatin1(kde_use_idn).lower()));}// implement the ToAscii function, as described by IDN documentsQCString KResolver::domainToAscii(const QString& unicodeDomain){ if (!idnDomains) idnDomains = KResolver_initIdnDomains(); QCString retval; // RFC 3490, section 4 describes the operation: // 1) this is a query, so don't allow unassigned // 2) split the domain into individual labels, without // separators. QStringList input = splitLabels(unicodeDomain); // Do we allow IDN names for this TLD? if (input.count() && !idnDomains->contains(input[input.count()-1].lower())) return input.join(".").lower().latin1(); // No IDN allowed for this TLD // 3) decide whether to enforce the STD3 rules for chars < 0x7F // we don't enforce // 4) for each label, apply ToASCII QStringList::Iterator it = input.begin(); const QStringList::Iterator end = input.end(); for ( ; it != end; ++it) { QCString cs = ToASCII(*it); if (cs.isNull()) return QCString(); // error! // no, all is Ok. if (!retval.isEmpty()) retval += '.'; retval += cs; } return retval;}QString KResolver::domainToUnicode(const QCString& asciiDomain){ return domainToUnicode(QString::fromLatin1(asciiDomain));}// implement the ToUnicode function, as described by IDN documentsQString KResolver::domainToUnicode(const QString& asciiDomain){ if (asciiDomain.isEmpty()) return asciiDomain; if (!idnDomains) idnDomains = KResolver_initIdnDomains(); QString retval; // draft-idn-idna-14.txt, section 4 describes the operation: // 1) this is a query, so don't allow unassigned // besides, input is ASCII // 2) split the domain into individual labels, without // separators. QStringList input = splitLabels(asciiDomain); // Do we allow IDN names for this TLD? if (input.count() && !idnDomains->contains(input[input.count()-1].lower())) return asciiDomain.lower(); // No TLDs allowed // 3) decide whether to enforce the STD3 rules for chars < 0x7F // we don't enforce // 4) for each label, apply ToUnicode QStringList::Iterator it; const QStringList::Iterator end = input.end(); for (it = input.begin(); it != end; ++it) { QString label = ToUnicode(*it).lower(); // ToUnicode can't fail if (!retval.isEmpty()) retval += '.'; retval += label; } return retval;}QString KResolver::normalizeDomain(const QString& domain){ return domainToUnicode(domainToAscii(domain));}void KResolver::virtual_hook( int, void* ){ /*BASE::virtual_hook( id, data );*/ }// here follows IDN functions// all IDN functions conform to the following documents:// RFC 3454 - Preparation of Internationalized Strings// RFC 3490 - Internationalizing Domain Names in Applications (IDNA)// RFC 3491 - Nameprep: A Stringprep Profile for// Internationalized Domain Names (IDN// RFC 3492 - Punycode: A Bootstring encoding of Unicode// for Internationalized Domain Names in Applications (IDNA)static QStringList splitLabels(const QString& unicodeDomain){ // From RFC 3490 section 3.1: // "Whenever dots are used as label separators, the following characters // MUST be recognized as dots: U+002E (full stop), U+3002 (ideographic full // stop), U+FF0E (fullwidth full stop), U+FF61 (halfwidth ideographic full // stop)." static const unsigned int separators[] = { 0x002E, 0x3002, 0xFF0E, 0xFF61 }; QStringList lst; int start = 0; uint i; for (i = 0; i < unicodeDomain.length(); i++) { unsigned int c = unicodeDomain[i].unicode(); if (c == separators[0] || c == separators[1] || c == separators[2] || c == separators[3]) { // found a separator! lst << unicodeDomain.mid(start, i - start); start = i + 1; } } if ((long)i >= start) // there is still one left lst << unicodeDomain.mid(start, i - start); return lst;}static QCString ToASCII(const QString& label){#ifdef HAVE_IDNA_H // We have idna.h, so we can use the idna_to_ascii // function :) if (label.length() > 64) return (char*)0L; // invalid label if (label.length() == 0) // this is allowed return QCString(""); // empty, not null QCString retval; char buf[65]; Q_UINT32* ucs4 = new Q_UINT32[label.length() + 1]; uint i; for (i = 0; i < label.length(); i++) ucs4[i] = (unsigned long)label[i].unicode(); ucs4[i] = 0; // terminate with NUL, just to be on the safe side if (idna_to_ascii_4i(ucs4, label.length(), buf, 0) == IDNA_SUCCESS) // success! retval = buf; delete [] ucs4; return retval;#else return label.latin1();#endif}static QString ToUnicode(const QString& label){#ifdef HAVE_IDNA_H // We have idna.h, so we can use the idna_to_unicode // function :) Q_UINT32 *ucs4_input, *ucs4_output; size_t outlen; ucs4_input = new Q_UINT32[label.length() + 1]; for (uint i = 0; i < label.length(); i++) ucs4_input[i] = (unsigned long)label[i].unicode(); // try the same length for output ucs4_output = new Q_UINT32[outlen = label.length()]; idna_to_unicode_44i(ucs4_input, label.length(), ucs4_output, &outlen, 0); if (outlen > label.length()) { // it must have failed delete [] ucs4_output; ucs4_output = new Q_UINT32[outlen]; idna_to_unicode_44i(ucs4_input, label.length(), ucs4_output, &outlen, 0); } // now set the answer QString result; result.setLength(outlen); for (uint i = 0; i < outlen; i++) result[i] = (unsigned int)ucs4_output[i]; delete [] ucs4_input; delete [] ucs4_output; return result;#else return label;#endif}#include "kresolver.moc"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?