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 + -
显示快捷键?