• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • network
k3resolver.cpp
Go to the documentation of this file.
1 /* -*- C++ -*-
2  * Copyright (C) 2003-2005 Thiago Macieira <thiago@kde.org>
3  *
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include "k3resolver.h"
26 #include "k3resolver_p.h"
27 
28 #include <config.h>
29 #include <config-network.h>
30 
31 // System includes
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/param.h>
35 #include <errno.h>
36 #include <netdb.h>
37 #include <time.h>
38 #include <arpa/inet.h>
39 #include <netinet/in.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 
43 // Qt includes
44 #include <QCoreApplication>
45 #include <QPointer>
46 #include <QSet>
47 
48 #include <QStringList>
49 #include <QSharedData>
50 #include <QTime>
51 #include <QTimer>
52 
53 // KDE
54 #include <klocale.h>
55 #include <kurl.h>
56 
57 // Us
58 #include "k3socketaddress.h"
59 
60 #ifdef NEED_MUTEX
61 #ifdef __GNUC__
62 #warning "mutex"
63 #endif
64 QMutex getXXbyYYmutex;
65 #endif
66 
67 #ifdef __OpenBSD__
68 #define USE_OPENBSD 1
69 #endif
70 
71 using namespace KNetwork;
72 using namespace KNetwork::Internal;
73 
75 // class KResolverEntry
76 
77 class KNetwork::KResolverEntryPrivate: public QSharedData
78 {
79 public:
80  KSocketAddress addr;
81  int socktype;
82  int protocol;
83  QString canonName;
84  QByteArray encodedName;
85 
86  inline KResolverEntryPrivate() :
87  socktype(0), protocol(0)
88  { }
89 };
90 
91 // default constructor
92 KResolverEntry::KResolverEntry() :
93  d(0L)
94 {
95 }
96 
97 // constructor with stuff
98 KResolverEntry::KResolverEntry(const KSocketAddress& addr, int socktype, int protocol,
99  const QString& canonName, const QByteArray& encodedName) :
100  d(new KResolverEntryPrivate)
101 {
102  d->addr = addr;
103  d->socktype = socktype;
104  d->protocol = protocol;
105  d->canonName = canonName;
106  d->encodedName = encodedName;
107 }
108 
109 // constructor with even more stuff
110 KResolverEntry::KResolverEntry(const struct sockaddr* sa, quint16 salen, int socktype,
111  int protocol, const QString& canonName,
112  const QByteArray& encodedName) :
113  d(new KResolverEntryPrivate)
114 {
115  d->addr = KSocketAddress(sa, salen);
116  d->socktype = socktype;
117  d->protocol = protocol;
118  d->canonName = canonName;
119  d->encodedName = encodedName;
120 }
121 
122 // copy constructor
123 KResolverEntry::KResolverEntry(const KResolverEntry& that) :
124  d(0L)
125 {
126  *this = that;
127 }
128 
129 // destructor
130 KResolverEntry::~KResolverEntry()
131 {
132 }
133 
134 // returns the socket address
135 KSocketAddress KResolverEntry::address() const
136 {
137  return d->addr;
138 }
139 
140 // returns the length
141 quint16 KResolverEntry::length() const
142 {
143  return d->addr.length();
144 }
145 
146 // returns the family
147 int KResolverEntry::family() const
148 {
149  return d->addr.family();
150 }
151 
152 // returns the canonical name
153 QString KResolverEntry::canonicalName() const
154 {
155  return d->canonName;
156 }
157 
158 // returns the encoded name
159 QByteArray KResolverEntry::encodedName() const
160 {
161  return d->encodedName;
162 }
163 
164 // returns the socket type
165 int KResolverEntry::socketType() const
166 {
167  return d->socktype;
168 }
169 
170 // returns the protocol
171 int KResolverEntry::protocol() const
172 {
173  return d->protocol;
174 }
175 
176 // assignment operator
177 KResolverEntry& KResolverEntry::operator= (const KResolverEntry& that)
178 {
179  d = that.d;
180  return *this;
181 }
182 
184 // class KResolverResults
185 
186 class KNetwork::KResolverResultsPrivate: public QSharedData
187 {
188 public:
189  QString node, service;
190  int errorcode, syserror;
191 
192  KResolverResultsPrivate() :
193  errorcode(0), syserror(0)
194  { }
195 };
196 
197 // default constructor
198 KResolverResults::KResolverResults()
199  : d(new KResolverResultsPrivate)
200 {
201 }
202 
203 // copy constructor
204 KResolverResults::KResolverResults(const KResolverResults& other)
205  : QList<KResolverEntry>(other), d(new KResolverResultsPrivate)
206 {
207  d = other.d;
208 }
209 
210 // destructor
211 KResolverResults::~KResolverResults()
212 {
213 }
214 
215 // assignment operator
216 KResolverResults&
217 KResolverResults::operator= (const KResolverResults& other)
218 {
219  // copy over the other data
220  d = other.d;
221 
222  // now let QList do the rest of the work
223  QList<KResolverEntry>::operator =(other);
224 
225  return *this;
226 }
227 
228 // gets the error code
229 int KResolverResults::error() const
230 {
231  return d->errorcode;
232 }
233 
234 // gets the system errno
235 int KResolverResults::systemError() const
236 {
237  return d->syserror;
238 }
239 
240 // sets the error codes
241 void KResolverResults::setError(int errorcode, int systemerror)
242 {
243  d->errorcode = errorcode;
244  d->syserror = systemerror;
245 }
246 
247 // gets the hostname
248 QString KResolverResults::nodeName() const
249 {
250  return d->node;
251 }
252 
253 // gets the service name
254 QString KResolverResults::serviceName() const
255 {
256  return d->service;
257 }
258 
259 // sets the address
260 void KResolverResults::setAddress(const QString& node,
261  const QString& service)
262 {
263  d->node = node;
264  d->service = service;
265 }
266 
267 void KResolverResults::virtual_hook( int, void* )
268 { /*BASE::virtual_hook( id, data );*/ }
269 
270 
272 // class KResolver
273 
274 // default constructor
275 KResolver::KResolver(QObject *parent)
276  : QObject(parent), d(new KResolverPrivate(this))
277 {
278 }
279 
280 // constructor with host and service
281 KResolver::KResolver(const QString& nodename, const QString& servicename,
282  QObject *parent)
283  : QObject(parent), d(new KResolverPrivate(this, nodename, servicename))
284 {
285 }
286 
287 // destructor
288 KResolver::~KResolver()
289 {
290  cancel(false);
291  delete d;
292 }
293 
294 // get the status
295 int KResolver::status() const
296 {
297  return d->status;
298 }
299 
300 // get the error code
301 int KResolver::error() const
302 {
303  return d->errorcode;
304 }
305 
306 // get the errno
307 int KResolver::systemError() const
308 {
309  return d->syserror;
310 }
311 
312 QString KResolver::errorString() const
313 {
314  return errorString(error(), systemError());
315 }
316 
317 // are we running?
318 bool KResolver::isRunning() const
319 {
320  return d->status > 0 && d->status < Success;
321 }
322 
323 // get the hostname
324 QString KResolver::nodeName() const
325 {
326  return d->input.node;
327 }
328 
329 // get the service
330 QString KResolver::serviceName() const
331 {
332  return d->input.service;
333 }
334 
335 // sets the hostname
336 void KResolver::setNodeName(const QString& nodename)
337 {
338  // don't touch those values if we're working!
339  if (!isRunning())
340  {
341  d->input.node = nodename;
342  d->status = Idle;
343  d->results.setAddress(nodename, d->input.service);
344  }
345 }
346 
347 // sets the service
348 void KResolver::setServiceName(const QString& service)
349 {
350  // don't change if running
351  if (!isRunning())
352  {
353  d->input.service = service;
354  d->status = Idle;
355  d->results.setAddress(d->input.node, service);
356  }
357 }
358 
359 // sets the address
360 void KResolver::setAddress(const QString& nodename, const QString& service)
361 {
362  setNodeName(nodename);
363  setServiceName(service);
364 }
365 
366 // get the flags
367 int KResolver::flags() const
368 {
369  return d->input.flags;
370 }
371 
372 // sets the flags
373 int KResolver::setFlags(int flags)
374 {
375  int oldflags = d->input.flags;
376  if (!isRunning())
377  {
378  d->input.flags = flags;
379  d->status = Idle;
380  }
381  return oldflags;
382 }
383 
384 // sets the family mask
385 void KResolver::setFamily(int families)
386 {
387  if (!isRunning())
388  {
389  d->input.familyMask = families;
390  d->status = Idle;
391  }
392 }
393 
394 // sets the socket type
395 void KResolver::setSocketType(int type)
396 {
397  if (!isRunning())
398  {
399  d->input.socktype = type;
400  d->status = Idle;
401  }
402 }
403 
404 // sets the protocol
405 void KResolver::setProtocol(int protonum, const char *name)
406 {
407  if (isRunning())
408  return; // can't change now
409 
410  // we copy the given protocol name. If it isn't an empty string
411  // and the protocol number was 0, we will look it up in /etc/protocols
412  // we also leave the error reporting to the actual lookup routines, in
413  // case the given protocol name doesn't exist
414 
415  d->input.protocolName = name;
416  if (protonum == 0 && name != 0L && *name != '\0')
417  {
418  // must look up the protocol number
419  d->input.protocol = KResolver::protocolNumber(name);
420  }
421  else
422  d->input.protocol = protonum;
423  d->status = Idle;
424 }
425 
426 bool KResolver::start()
427 {
428  if (!isRunning())
429  {
430  d->results.empty();
431 
432  // is there anything to be queued?
433  if (d->input.node.isEmpty() && d->input.service.isEmpty())
434  {
435  d->status = KResolver::Success;
436  emitFinished();
437  }
438  else
439  KResolverManager::manager()->enqueue(this, 0L);
440  }
441 
442  return true;
443 }
444 
445 bool KResolver::wait(int msec)
446 {
447  if (!isRunning())
448  {
449  emitFinished();
450  return true;
451  }
452 
453  QMutexLocker locker(&d->mutex);
454 
455  if (!isRunning())
456  {
457  // it was running and no longer is?
458  // That means the manager has finished its processing and has posted
459  // an event for the signal to be emitted already. This means the signal
460  // will be emitted twice!
461 
462  emitFinished();
463  return true;
464  }
465  else
466  {
467  QTime t;
468  t.start();
469 
470  while (!msec || t.elapsed() < msec)
471  {
472  // wait on the manager to broadcast completion
473  d->waiting = true;
474  if (msec)
475  KResolverManager::manager()->notifyWaiters.wait(&d->mutex, msec - t.elapsed());
476  else
477  KResolverManager::manager()->notifyWaiters.wait(&d->mutex);
478 
479  // the manager has processed
480  // see if this object is done
481  if (!isRunning())
482  {
483  // it's done
484  d->waiting = false;
485  emitFinished();
486  return true;
487  }
488  }
489 
490  // if we've got here, we've timed out
491  d->waiting = false;
492  return false;
493  }
494 }
495 
496 void KResolver::cancel(bool emitSignal)
497 {
498  KResolverManager::manager()->dequeue(this);
499  if (emitSignal)
500  emitFinished();
501 }
502 
503 KResolverResults
504 KResolver::results() const
505 {
506  if (!isRunning())
507  return d->results;
508 
509  // return a dummy, empty result
510  KResolverResults r;
511  r.setAddress(d->input.node, d->input.service);
512  r.setError(d->errorcode, d->syserror);
513  return r;
514 }
515 
516 bool KResolver::event(QEvent* e)
517 {
518  if (static_cast<int>(e->type()) == KResolverManager::ResolutionCompleted)
519  {
520  emitFinished();
521  return true;
522  }
523 
524  return QObject::event(e);
525 }
526 
527 void KResolver::emitFinished()
528 {
529  if (isRunning())
530  d->status = KResolver::Success;
531 
532  QPointer<QObject> p = this; // guard against deletion
533 
534  emit finished(d->results);
535 
536  if (p && d->deleteWhenDone)
537  deleteLater(); // in QObject
538 }
539 
540 QString KResolver::errorString(int errorcode, int syserror)
541 {
542  // no i18n now...
543  static const char messages[] =
544  {
545  I18N_NOOP("no error")"\0" // NoError
546  I18N_NOOP("requested family not supported for this host name")"\0" // AddrFamily
547  I18N_NOOP("temporary failure in name resolution")"\0" // TryAgain
548  I18N_NOOP("non-recoverable failure in name resolution")"\0" // NonRecoverable
549  I18N_NOOP("invalid flags")"\0" // BadFlags
550  I18N_NOOP("memory allocation failure")"\0" // Memory
551  I18N_NOOP("name or service not known")"\0" // NoName
552  I18N_NOOP("requested family not supported")"\0" // UnsupportedFamily
553  I18N_NOOP("requested service not supported for this socket type")"\0" // UnsupportedService
554  I18N_NOOP("requested socket type not supported")"\0" // UnsupportedSocketType
555  I18N_NOOP("unknown error")"\0" // UnknownError
556  I18N_NOOP2("1: the i18n'ed system error code, from errno",
557  "system error: %1")"\0" // SystemError
558  "\0"
559  };
560  // index table generated by generate_string_table.pl
561  static const int messages_indices[] = {
562  0, 9, 59, 96, 139, 153, 179, 205,
563  236, 289, 325, 0
564  };
565 
566  // handle the special value
567  if (errorcode == Canceled)
568  return i18n("request was canceled");
569 
570  Q_ASSERT(int(SystemError) <= -(int)(sizeof(messages_indices)/sizeof(messages_indices[0])));
571  if (errorcode > 0 || errorcode < SystemError)
572  return QString();
573 
574  QString msg = i18n(messages + messages_indices[-errorcode]);
575  if (errorcode == SystemError)
576  msg.arg(QString::fromLocal8Bit(strerror(syserror)));
577 
578  return msg;
579 }
580 
581 KResolverResults
582 KResolver::resolve(const QString& host, const QString& service, int flags,
583  int families)
584 {
585  KResolver qres(host, service, QCoreApplication::instance());
586  qres.setObjectName(QString::fromLatin1("synchronous KResolver"));
587  qres.setFlags(flags);
588  qres.setFamily(families);
589  qres.start();
590  qres.wait();
591  return qres.results();
592 }
593 
594 bool KResolver::resolveAsync(QObject* userObj, const char *userSlot,
595  const QString& host, const QString& service,
596  int flags, int families)
597 {
598  KResolver* qres = new KResolver(host, service, QCoreApplication::instance());
599  QObject::connect(qres, SIGNAL(finished(KNetwork::KResolverResults)),
600  userObj, userSlot);
601  qres->setObjectName(QString::fromLatin1("asynchronous KResolver"));
602  qres->setFlags(flags);
603  qres->setFamily(families);
604  qres->d->deleteWhenDone = true; // this is the only difference from the example code
605  return qres->start();
606 }
607 
608 QList<QByteArray> KResolver::protocolName(int protonum)
609 {
610  struct protoent *pe;
611 #ifndef HAVE_GETPROTOBYNAME_R
612  QMutexLocker locker(&getXXbyYYmutex);
613 
614  pe = getprotobynumber(protonum);
615 
616 #else
617 # ifdef USE_OPENBSD // OpenBSD uses an HP/IBM/DEC API
618  struct protoent protobuf;
619  struct protoent_data pdata;
620  ::memset(&pdata, 0, sizeof pdata);
621 
622  if (getprotobynumber_r(protonum, &protobuf, &pdata) == 0)
623  pe = &protobuf;
624  else
625  pe = 0;
626 
627 # else
628  size_t buflen = 1024;
629  struct protoent protobuf;
630  char *buf;
631  do
632  {
633  buf = new char[buflen];
634 # ifdef Q_OS_SOLARIS // Solaris uses a 4 argument getprotobynumber_r which returns struct *protoent or NULL
635  if ((pe = getprotobynumber_r(protonum, &protobuf, buf, buflen)) && (errno == ERANGE))
636 # else
637  if (getprotobynumber_r(protonum, &protobuf, buf, buflen, &pe) == ERANGE)
638 # endif
639  {
640  buflen += 1024;
641  delete [] buf;
642  }
643  else
644  break;
645  }
646  while (pe == 0L);
647 # endif
648 #endif
649 
650  // Do common processing
651  QList<QByteArray> lst;
652  if (pe != NULL)
653  {
654  lst.append(pe->p_name);
655  for (char **p = pe->p_aliases; *p; p++)
656  lst.append(*p);
657  }
658 
659 #ifdef HAVE_GETPROTOBYNAME_R
660 # ifndef USE_OPENBSD
661  delete [] buf;
662 # endif
663 #endif
664 
665  return lst;
666 }
667 
668 QList<QByteArray> KResolver::protocolName(const char *protoname)
669 {
670  struct protoent *pe = 0L;
671 #ifndef HAVE_GETPROTOBYNAME_R
672  QMutexLocker locker(&getXXbyYYmutex);
673 
674  pe = getprotobyname(protoname);
675 
676 #else
677 # ifdef USE_OPENBSD // OpenBSD uses an HP/IBM/DEC API
678  struct protoent protobuf;
679  struct protoent_data pdata;
680  ::memset(&pdata, 0, sizeof pdata);
681 
682  if (getprotobyname_r(protoname, &protobuf, &pdata) == 0)
683  pe = &protobuf;
684  else
685  pe = 0;
686 # else
687  size_t buflen = 1024;
688  struct protoent protobuf;
689  char *buf;
690  do
691  {
692  buf = new char[buflen];
693 # ifdef Q_OS_SOLARIS // Solaris uses a 4 argument getprotobyname_r which returns struct *protoent or NULL
694  if ((pe = getprotobyname_r(protoname, &protobuf, buf, buflen)) && (errno == ERANGE))
695 # else
696  if (getprotobyname_r(protoname, &protobuf, buf, buflen, &pe) == ERANGE)
697 # endif
698  {
699  pe = 0L;
700  buflen += 1024;
701  delete [] buf;
702  }
703  else
704  break;
705  }
706  while (pe == 0L);
707 # endif
708 #endif
709 
710  // Do common processing
711  QList<QByteArray> lst;
712  if (pe != NULL)
713  {
714  lst.append(pe->p_name);
715  for (char **p = pe->p_aliases; *p; p++)
716  lst.append(*p);
717  }
718 
719 #ifdef HAVE_GETPROTOBYNAME_R
720 # ifndef USE_OPENBSD
721  delete [] buf;
722 # endif
723 #endif
724 
725  return lst;
726 }
727 
728 int KResolver::protocolNumber(const char *protoname)
729 {
730  struct protoent *pe = 0L;
731 #ifndef HAVE_GETPROTOBYNAME_R
732  QMutexLocker locker(&getXXbyYYmutex);
733 
734  pe = getprotobyname(protoname);
735 
736 #else
737 # ifdef USE_OPENBSD // OpenBSD uses an HP/IBM/DEC API
738  struct protoent protobuf;
739  struct protoent_data pdata;
740  ::memset(&pdata, 0, sizeof pdata);
741 
742  if (getprotobyname_r(protoname, &protobuf, &pdata) == 0)
743  pe = &protobuf;
744  else
745  pe = 0;
746 
747 # else
748  size_t buflen = 1024;
749  struct protoent protobuf;
750  char *buf;
751  do
752  {
753  buf = new char[buflen];
754 # ifdef Q_OS_SOLARIS // Solaris uses a 4 argument getprotobyname_r which returns struct *protoent or NULL
755  if ((pe = getprotobyname_r(protoname, &protobuf, buf, buflen)) && (errno == ERANGE))
756 # else
757  if (getprotobyname_r(protoname, &protobuf, buf, buflen, &pe) == ERANGE)
758 # endif
759  {
760  pe = 0L;
761  buflen += 1024;
762  delete [] buf;
763  }
764  else
765  break;
766  }
767  while (pe == 0L);
768 # endif
769 #endif
770 
771  // Do common processing
772  int protonum = -1;
773  if (pe != NULL)
774  protonum = pe->p_proto;
775 
776 #ifdef HAVE_GETPROTOBYNAME_R
777 # ifndef USE_OPENBSD
778  delete [] buf;
779 # endif
780 #endif
781 
782  return protonum;
783 }
784 
785 int KResolver::servicePort(const char *servname, const char *protoname)
786 {
787  struct servent *se = 0L;
788 #ifndef HAVE_GETSERVBYNAME_R
789  QMutexLocker locker(&getXXbyYYmutex);
790 
791  se = getservbyname(servname, protoname);
792 
793 #else
794 # ifdef USE_OPENBSD // OpenBSD uses an HP/IBM/DEC API
795  struct servent servbuf;
796  struct servent_data sdata;
797  ::memset(&sdata, 0, sizeof sdata);
798  if (getservbyname_r(servname, protoname, &servbuf, &sdata) == 0)
799  se = &servbuf;
800  else
801  se = 0;
802 
803 # else
804  size_t buflen = 1024;
805  struct servent servbuf;
806  char *buf;
807  do
808  {
809  buf = new char[buflen];
810 # ifdef Q_OS_SOLARIS // Solaris uses a 5 argument getservbyname_r which returns struct *servent or NULL
811  if ((se = getservbyname_r(servname, protoname, &servbuf, buf, buflen)) && (errno == ERANGE))
812 # else
813  if (getservbyname_r(servname, protoname, &servbuf, buf, buflen, &se) == ERANGE)
814 # endif
815  {
816  se = 0L;
817  buflen += 1024;
818  delete [] buf;
819  }
820  else
821  break;
822  }
823  while (se == 0L);
824 # endif
825 #endif
826 
827  // Do common processing
828  int servport = -1;
829  if (se != NULL)
830  servport = ntohs(se->s_port);
831 
832 #ifdef HAVE_GETSERVBYNAME_R
833 # ifndef USE_OPENBSD
834  delete [] buf;
835 # endif
836 #endif
837 
838  return servport;
839 }
840 
841 QList<QByteArray> KResolver::serviceName(const char* servname, const char *protoname)
842 {
843  struct servent *se = 0L;
844 #ifndef HAVE_GETSERVBYNAME_R
845  QMutexLocker locker(&getXXbyYYmutex);
846 
847  se = getservbyname(servname, protoname);
848 
849 #else
850 # ifdef USE_OPENBSD // OpenBSD uses an HP/IBM/DEC API
851  struct servent servbuf;
852  struct servent_data sdata;
853  ::memset(&sdata, 0, sizeof sdata);
854  if (getservbyname_r(servname, protoname, &servbuf, &sdata) == 0)
855  se = &servbuf;
856  else
857  se = 0;
858 
859 # else
860  size_t buflen = 1024;
861  struct servent servbuf;
862  char *buf;
863  do
864  {
865  buf = new char[buflen];
866 # ifdef Q_OS_SOLARIS // Solaris uses a 5 argument getservbyname_r which returns struct *servent or NULL
867  if ((se = getservbyname_r(servname, protoname, &servbuf, buf, buflen)) && (errno == ERANGE))
868 # else
869  if (getservbyname_r(servname, protoname, &servbuf, buf, buflen, &se) == ERANGE)
870 # endif
871  {
872  se = 0L;
873  buflen += 1024;
874  delete [] buf;
875  }
876  else
877  break;
878  }
879  while (se == 0L);
880 # endif
881 #endif
882 
883  // Do common processing
884  QList<QByteArray> lst;
885  if (se != NULL)
886  {
887  lst.append(se->s_name);
888  for (char **p = se->s_aliases; *p; p++)
889  lst.append(*p);
890  }
891 
892 #ifdef HAVE_GETSERVBYNAME_R
893 # ifndef USE_OPENBSD
894  delete [] buf;
895 # endif
896 #endif
897 
898  return lst;
899 }
900 
901 QList<QByteArray> KResolver::serviceName(int port, const char *protoname)
902 {
903  struct servent *se = 0L;
904 #ifndef HAVE_GETSERVBYPORT_R
905  QMutexLocker locker(&getXXbyYYmutex);
906 
907  se = getservbyport(port, protoname);
908 
909 #else
910 # ifdef USE_OPENBSD // OpenBSD uses an HP/IBM/DEC API
911  struct servent servbuf;
912  struct servent_data sdata;
913  ::memset(&sdata, 0, sizeof sdata);
914  if (getservbyport_r(port, protoname, &servbuf, &sdata) == 0)
915  se = &servbuf;
916  else
917  se = 0;
918 
919 # else
920  size_t buflen = 1024;
921  struct servent servbuf;
922  char *buf;
923  do
924  {
925  buf = new char[buflen];
926 # ifdef Q_OS_SOLARIS // Solaris uses a 5 argument getservbyport_r which returns struct *servent or NULL
927  if ((se = getservbyport_r(port, protoname, &servbuf, buf, buflen)) && (errno == ERANGE))
928 # else
929  if (getservbyport_r(port, protoname, &servbuf, buf, buflen, &se) == ERANGE)
930 # endif
931  {
932  se = 0L;
933  buflen += 1024;
934  delete [] buf;
935  }
936  else
937  break;
938  }
939  while (se == 0L);
940 # endif
941 #endif
942 
943  // Do common processing
944  QList<QByteArray> lst;
945  if (se != NULL)
946  {
947  lst.append(se->s_name);
948  for (char **p = se->s_aliases; *p; p++)
949  lst.append(*p);
950  }
951 
952 #ifdef HAVE_GETSERVBYPORT_R
953 # ifndef USE_OPENBSD
954  delete [] buf;
955 # endif
956 #endif
957 
958  return lst;
959 }
960 
961 QString KResolver::localHostName()
962 {
963  QByteArray name;
964  int len;
965 
966 #ifdef MAXHOSTNAMELEN
967  len = MAXHOSTNAMELEN;
968 #else
969  len = 256;
970 #endif
971 
972  while (true)
973  {
974  name.resize(len);
975 
976  if (gethostname(name.data(), len) == 0)
977  {
978  // Call succeeded, but it's not guaranteed to be NUL-terminated
979  // Fortunately, QByteArray is always NUL-terminated
980 
981  // Note that some systems return success even if they did truncation
982  break;
983  }
984 
985  // Call failed
986  if (errno == ENAMETOOLONG || errno == EINVAL)
987  len += 256;
988  else
989  {
990  // Oops! Unknown error!
991  name.clear();
992  }
993  }
994 
995  if (name.isEmpty())
996  return QLatin1String("localhost");
997 
998  if (name.indexOf('.') == -1)
999  {
1000  // not fully qualified
1001  // must resolve
1002  KResolverResults results = resolve(QString::fromLocal8Bit(name), QString::fromLatin1("0"), CanonName);
1003  if (results.isEmpty())
1004  // cannot find a valid hostname!
1005  return QLatin1String("localhost");
1006  else
1007  return results.first().canonicalName();
1008  }
1009 
1010  return domainToUnicode(name);
1011 }
1012 
1013 static void KResolver_initIdnDomains()
1014 {
1015  static bool init = false;
1016  if (!init)
1017  {
1018  QByteArray kde_use_idn = qgetenv("KDE_USE_IDN");
1019  if (!kde_use_idn.isEmpty())
1020  KUrl::setIdnWhitelist(QString::fromLatin1(kde_use_idn).toLower().split(QLatin1Char(':')));
1021  init = true;
1022  }
1023 }
1024 
1025 // implement the ToAscii function, as described by IDN documents
1026 QByteArray KResolver::domainToAscii(const QString& unicodeDomain)
1027 {
1028  KResolver_initIdnDomains();
1029  return KUrl::toAce(unicodeDomain);
1030 }
1031 
1032 QString KResolver::domainToUnicode(const QByteArray& asciiDomain)
1033 {
1034  return domainToUnicode(QString::fromLatin1(asciiDomain));
1035 }
1036 
1037 // implement the ToUnicode function, as described by IDN documents
1038 QString KResolver::domainToUnicode(const QString& asciiDomain)
1039 {
1040  if (asciiDomain.isEmpty())
1041  return asciiDomain;
1042  KResolver_initIdnDomains();
1043  return KUrl::fromAce(asciiDomain.toLatin1());
1044 }
1045 
1046 QString KResolver::normalizeDomain(const QString& domain)
1047 {
1048  return domainToUnicode(domainToAscii(domain));
1049 }
1050 
1051 void KResolver::virtual_hook( int, void* )
1052 { /*BASE::virtual_hook( id, data );*/ }
1053 
1054 // here follows IDN functions
1055 // all IDN functions conform to the following documents:
1056 // RFC 3454 - Preparation of Internationalized Strings
1057 // RFC 3490 - Internationalizing Domain Names in Applications (IDNA)
1058 // RFC 3491 - Nameprep: A Stringprep Profile for
1059 // Internationalized Domain Names (IDN
1060 // RFC 3492 - Punycode: A Bootstring encoding of Unicode
1061 // for Internationalized Domain Names in Applications (IDNA)
1062 
1063 #include "k3resolver.moc"
QList::operator=
QList< T > & operator=(const QList< T > &other)
k3socketaddress.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
KNetwork::KResolver::finished
void finished(const KNetwork::KResolverResults &results)
This signal is emitted whenever the resolution is finished, one way or another (success or failure)...
KNetwork::Internal::InputData::protocol
int protocol
Definition: k3resolver_p.h:97
KNetwork::KResolverEntry::canonicalName
QString canonicalName() const
Retrieves the canonical name associated with this entry, if there is any.
Definition: k3resolver.cpp:153
KNetwork::KResolverResults::operator=
KResolverResults & operator=(const KResolverResults &other)
Assignment operator.
Definition: k3resolver.cpp:217
QEvent
KNetwork::KResolver::serviceName
QString serviceName() const
The service name to which the resolution was/is to be performed.
Definition: k3resolver.cpp:330
QMutex
KNetwork::KResolverPrivate::waiting
bool waiting
Definition: k3resolver_p.h:107
QEvent::type
Type type() const
QUrl::fromAce
QString fromAce(const QByteArray &domain)
KNetwork::KResolverEntry::operator=
KResolverEntry & operator=(const KResolverEntry &other)
Assignment operator.
Definition: k3resolver.cpp:177
QByteArray::clear
void clear()
KNetwork::KResolver::KResolver
KResolver(QObject *parent=0L)
Default constructor.
Definition: k3resolver.cpp:275
KNetwork::KResolver::normalizeDomain
static QString normalizeDomain(const QString &domain)
Normalise a domain name.
Definition: k3resolver.cpp:1046
KNetwork::KResolver::SystemError
Definition: k3resolver.h:411
kurl.h
QByteArray
KNetwork::KResolver::flags
int flags() const
Retrieves the flags set for the resolution.
Definition: k3resolver.cpp:367
I18N_NOOP2
#define I18N_NOOP2(comment, x)
If the string is too ambiguous to be translated well to a non-english language, use this instead of I...
Definition: klocalizedstring.h:72
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
KNetwork::KResolverResults::~KResolverResults
virtual ~KResolverResults()
Destructor.
Definition: k3resolver.cpp:211
KNetwork::KResolverEntry
One resolution entry.
Definition: k3resolver.h:68
KNetwork::KResolver::error
int error() const
Retrieve the error code in this object.
Definition: k3resolver.cpp:301
KNetwork::KResolver::setFamily
void setFamily(int families)
Sets the allowed socket families.
Definition: k3resolver.cpp:385
QPointer
QByteArray::isEmpty
bool isEmpty() const
getXXbyYYmutex
QMutex getXXbyYYmutex
Definition: k3resolver.cpp:64
KNetwork::KResolver
Name and service resolution class.
Definition: k3resolver.h:312
KNetwork::KResolver::setProtocol
void setProtocol(int protonum, const char *name=0L)
Sets the protocol we want.
Definition: k3resolver.cpp:405
KNetwork::Internal::InputData::socktype
int socktype
Definition: k3resolver_p.h:96
KNetwork::Internal::InputData::node
QString node
Definition: k3resolver_p.h:92
KNetwork::KResolver::CanonName
Definition: k3resolver.h:370
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:414
KNetwork::KResolverEntry::encodedName
QByteArray encodedName() const
Retrieves the encoded domain name associated with this entry, if there is any.
Definition: k3resolver.cpp:159
I18N_NOOP
#define I18N_NOOP(x)
I18N_NOOP marks a string to be translated without translating it.
Definition: klocalizedstring.h:51
KNetwork::KResolver::resolve
static KResolverResults resolve(const QString &host, const QString &service, int flags=0, int families=KResolver::InternetFamily)
Resolve the nodename and service name synchronously.
Definition: k3resolver.cpp:582
klocale.h
KNetwork::KResolverResults
Name and service resolution results.
Definition: k3resolver.h:212
QTime
KNetwork::Internal::InputData::protocolName
QByteArray protocolName
Definition: k3resolver_p.h:93
KNetwork::KResolver::status
int status() const
Retrieve the current status of this object.
Definition: k3resolver.cpp:295
KNetwork::KResolverPrivate
Definition: k3resolver_p.h:101
KNetwork::KResolver::localHostName
static QString localHostName()
Returns this machine's local hostname.
Definition: k3resolver.cpp:961
KNetwork::KResolver::errorString
QString errorString() const
Returns the textual representation of the error in this object.
Definition: k3resolver.cpp:312
KNetwork::KResolverEntry::protocol
int protocol() const
Retrieves the protocol associated with this entry.
Definition: k3resolver.cpp:171
KNetwork::KResolver::setServiceName
void setServiceName(const QString &service)
Sets the service name to be resolved.
Definition: k3resolver.cpp:348
KNetwork::KResolver::results
KResolverResults results() const
Retrieves the results of this resolution.
Definition: k3resolver.cpp:504
QObject::event
virtual bool event(QEvent *e)
QByteArray::resize
void resize(int size)
QObject::name
const char * name() const
QByteArray::indexOf
int indexOf(char ch, int from) const
QTime::elapsed
int elapsed() const
KNetwork::KResolverPrivate::deleteWhenDone
bool deleteWhenDone
Definition: k3resolver_p.h:106
QSharedData
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
QList::append
void append(const T &value)
KNetwork::KResolverPrivate::status
volatile int status
Definition: k3resolver_p.h:110
QList::empty
bool empty() const
KNetwork::KResolver::wait
bool wait(int msec=0)
Waits for a request to finish resolving.
Definition: k3resolver.cpp:445
KNetwork::KResolver::systemError
int systemError() const
Retrieve the associated system error code in this object.
Definition: k3resolver.cpp:307
QObject
QUrl::toAce
QByteArray toAce(const QString &domain)
KNetwork::KResolverPrivate::results
KResolverResults results
Definition: k3resolver_p.h:120
KNetwork::KResolverPrivate::syserror
volatile int syserror
Definition: k3resolver_p.h:111
QList::isEmpty
bool isEmpty() const
KNetwork::KResolver::Idle
Definition: k3resolver.h:437
KNetwork::KResolverResults::systemError
int systemError() const
Retrieves the system error code, if any.
Definition: k3resolver.cpp:235
QObject::setObjectName
void setObjectName(const QString &name)
QString::isEmpty
bool isEmpty() const
KNetwork::Internal::InputData::service
QString service
Definition: k3resolver_p.h:92
QCoreApplication::instance
QCoreApplication * instance()
QObject::deleteLater
void deleteLater()
QList::first
T & first()
QString
QList
Definition: kaboutdata.h:33
KNetwork::KResolver::event
virtual bool event(QEvent *)
Handles events.
Definition: k3resolver.cpp:516
KNetwork::KResolverEntry::~KResolverEntry
~KResolverEntry()
Destructor.
Definition: k3resolver.cpp:130
KNetwork::KResolver::protocolName
static QList< QByteArray > protocolName(int protonum)
Resolves a protocol number to its names.
Definition: k3resolver.cpp:608
QString::toLower
QString toLower() const
k3resolver.h
KNetwork::KResolverEntry::address
KSocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: k3resolver.cpp:135
QLatin1Char
KNetwork::KResolver::virtual_hook
virtual void virtual_hook(int id, void *data)
Standard hack to add virtuals later.
Definition: k3resolver.cpp:1051
KNetwork::Internal::InputData::flags
int flags
Definition: k3resolver_p.h:94
KNetwork::KResolver::resolveAsync
static bool resolveAsync(QObject *userObj, const char *userSlot, const QString &host, const QString &service, int flags=0, int families=KResolver::InternetFamily)
Start an asynchronous name resolution.
Definition: k3resolver.cpp:594
KNetwork::KResolverEntry::length
quint16 length() const
Retrieves the length of the socket address structure.
Definition: k3resolver.cpp:141
KNetwork::KResolver::setNodeName
void setNodeName(const QString &nodename)
Sets the nodename for the resolution.
Definition: k3resolver.cpp:336
KNetwork::KResolverResults::virtual_hook
virtual void virtual_hook(int id, void *data)
Standard hack to add virtuals later.
Definition: k3resolver.cpp:267
KNetwork::Internal::InputData::familyMask
int familyMask
Definition: k3resolver_p.h:95
QString::toLatin1
QByteArray toLatin1() const
KNetwork::KResolverEntry::socketType
int socketType() const
Retrieves the socket type associated with this entry.
Definition: k3resolver.cpp:165
QLatin1String
KNetwork::KResolverPrivate::errorcode
volatile int errorcode
Definition: k3resolver_p.h:111
QMutexLocker
KNetwork::KResolverPrivate::mutex
QMutex mutex
Definition: k3resolver_p.h:117
KNetwork::KResolver::domainToUnicode
static QString domainToUnicode(const QByteArray &asciiDomain)
Does the inverse of domainToAscii() and return an Unicode domain name from the given ACE-encoded doma...
Definition: k3resolver.cpp:1032
KNetwork::KResolverPrivate::input
Internal::InputData input
Definition: k3resolver_p.h:114
KNetwork::KResolverResults::setAddress
void setAddress(const QString &host, const QString &service)
Sets the new nodename and service name.
Definition: k3resolver.cpp:260
QUrl::setIdnWhitelist
void setIdnWhitelist(const QStringList &list)
KNetwork::KResolverEntry::family
int family() const
Retrieves the family associated with this socket address.
Definition: k3resolver.cpp:147
KNetwork::KResolver::servicePort
static int servicePort(const char *servname, const char *protoname)
Resolves a service name to its port number.
Definition: k3resolver.cpp:785
KNetwork::KResolverEntry::KResolverEntry
KResolverEntry()
Default constructor.
Definition: k3resolver.cpp:92
KNetwork::KResolverResults::serviceName
QString serviceName() const
The service name to which the resolution was performed.
Definition: k3resolver.cpp:254
QByteArray::data
char * data()
KNetwork::KResolverResults::KResolverResults
KResolverResults()
Default constructor.
Definition: k3resolver.cpp:198
KNetwork::KResolver::setSocketType
void setSocketType(int type)
Sets the socket type we want.
Definition: k3resolver.cpp:395
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KNetwork::KResolver::~KResolver
virtual ~KResolver()
Destructor.
Definition: k3resolver.cpp:288
QTime::start
void start()
KNetwork::KResolver::nodeName
QString nodeName() const
The nodename to which the resolution was/is to be performed.
Definition: k3resolver.cpp:324
KNetwork::KResolver::Canceled
Definition: k3resolver.h:412
KNetwork::KResolverResults::setError
void setError(int errorcode, int systemerror=0)
Sets the error codes.
Definition: k3resolver.cpp:241
KNetwork::KResolver::cancel
void cancel(bool emitSignal=true)
Cancels a running request.
Definition: k3resolver.cpp:496
KNetwork::KResolver::isRunning
bool isRunning() const
Returns true if this object is currently running.
Definition: k3resolver.cpp:318
KNetwork::KResolver::setFlags
int setFlags(int flags)
Sets the flags.
Definition: k3resolver.cpp:373
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KNetwork::KResolverResults::nodeName
QString nodeName() const
The nodename to which the resolution was performed.
Definition: k3resolver.cpp:248
KNetwork::KResolver::protocolNumber
static int protocolNumber(const char *protoname)
Resolves a protocol name to its number.
Definition: k3resolver.cpp:728
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KNetwork::KResolverResults::error
int error() const
Retrieves the error code associated with this resolution.
Definition: k3resolver.cpp:229
KNetwork::KResolver::setAddress
void setAddress(const QString &node, const QString &service)
Sets both the host and the service names.
Definition: k3resolver.cpp:360
KResolver_initIdnDomains
static void KResolver_initIdnDomains()
Definition: k3resolver.cpp:1013
KNetwork::KResolver::start
bool start()
Starts the name resolution asynchronously.
Definition: k3resolver.cpp:426
KNetwork::KResolver::domainToAscii
static QByteArray domainToAscii(const QString &unicodeDomain)
Returns the domain name in an ASCII Compatible Encoding form, suitable for DNS lookups.
Definition: k3resolver.cpp:1026
k3resolver_p.h
KNetwork::KResolver::Success
Definition: k3resolver.h:441
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:10 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal