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

KDECore

  • 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
64QMutex getXXbyYYmutex;
65#endif
66
67#ifdef __OpenBSD__
68#define USE_OPENBSD 1
69#endif
70
71using namespace KNetwork;
72using namespace KNetwork::Internal;
73
75// class KResolverEntry
76
77class KNetwork::KResolverEntryPrivate: public QSharedData
78{
79public:
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
92KResolverEntry::KResolverEntry() :
93 d(0L)
94{
95}
96
97// constructor with stuff
98KResolverEntry::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
110KResolverEntry::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
123KResolverEntry::KResolverEntry(const KResolverEntry& that) :
124 d(0L)
125{
126 *this = that;
127}
128
129// destructor
130KResolverEntry::~KResolverEntry()
131{
132}
133
134// returns the socket address
135KSocketAddress KResolverEntry::address() const
136{
137 return d->addr;
138}
139
140// returns the length
141quint16 KResolverEntry::length() const
142{
143 return d->addr.length();
144}
145
146// returns the family
147int KResolverEntry::family() const
148{
149 return d->addr.family();
150}
151
152// returns the canonical name
153QString KResolverEntry::canonicalName() const
154{
155 return d->canonName;
156}
157
158// returns the encoded name
159QByteArray KResolverEntry::encodedName() const
160{
161 return d->encodedName;
162}
163
164// returns the socket type
165int KResolverEntry::socketType() const
166{
167 return d->socktype;
168}
169
170// returns the protocol
171int KResolverEntry::protocol() const
172{
173 return d->protocol;
174}
175
176// assignment operator
177KResolverEntry& KResolverEntry::operator= (const KResolverEntry& that)
178{
179 d = that.d;
180 return *this;
181}
182
184// class KResolverResults
185
186class KNetwork::KResolverResultsPrivate: public QSharedData
187{
188public:
189 QString node, service;
190 int errorcode, syserror;
191
192 KResolverResultsPrivate() :
193 errorcode(0), syserror(0)
194 { }
195};
196
197// default constructor
198KResolverResults::KResolverResults()
199 : d(new KResolverResultsPrivate)
200{
201}
202
203// copy constructor
204KResolverResults::KResolverResults(const KResolverResults& other)
205 : QList<KResolverEntry>(other), d(new KResolverResultsPrivate)
206{
207 d = other.d;
208}
209
210// destructor
211KResolverResults::~KResolverResults()
212{
213}
214
215// assignment operator
216KResolverResults&
217KResolverResults::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
229int KResolverResults::error() const
230{
231 return d->errorcode;
232}
233
234// gets the system errno
235int KResolverResults::systemError() const
236{
237 return d->syserror;
238}
239
240// sets the error codes
241void KResolverResults::setError(int errorcode, int systemerror)
242{
243 d->errorcode = errorcode;
244 d->syserror = systemerror;
245}
246
247// gets the hostname
248QString KResolverResults::nodeName() const
249{
250 return d->node;
251}
252
253// gets the service name
254QString KResolverResults::serviceName() const
255{
256 return d->service;
257}
258
259// sets the address
260void KResolverResults::setAddress(const QString& node,
261 const QString& service)
262{
263 d->node = node;
264 d->service = service;
265}
266
267void KResolverResults::virtual_hook( int, void* )
268{ /*BASE::virtual_hook( id, data );*/ }
269
270
272// class KResolver
273
274// default constructor
275KResolver::KResolver(QObject *parent)
276 : QObject(parent), d(new KResolverPrivate(this))
277{
278}
279
280// constructor with host and service
281KResolver::KResolver(const QString& nodename, const QString& servicename,
282 QObject *parent)
283 : QObject(parent), d(new KResolverPrivate(this, nodename, servicename))
284{
285}
286
287// destructor
288KResolver::~KResolver()
289{
290 cancel(false);
291 delete d;
292}
293
294// get the status
295int KResolver::status() const
296{
297 return d->status;
298}
299
300// get the error code
301int KResolver::error() const
302{
303 return d->errorcode;
304}
305
306// get the errno
307int KResolver::systemError() const
308{
309 return d->syserror;
310}
311
312QString KResolver::errorString() const
313{
314 return errorString(error(), systemError());
315}
316
317// are we running?
318bool KResolver::isRunning() const
319{
320 return d->status > 0 && d->status < Success;
321}
322
323// get the hostname
324QString KResolver::nodeName() const
325{
326 return d->input.node;
327}
328
329// get the service
330QString KResolver::serviceName() const
331{
332 return d->input.service;
333}
334
335// sets the hostname
336void 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
348void 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
360void KResolver::setAddress(const QString& nodename, const QString& service)
361{
362 setNodeName(nodename);
363 setServiceName(service);
364}
365
366// get the flags
367int KResolver::flags() const
368{
369 return d->input.flags;
370}
371
372// sets the flags
373int 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
385void 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
395void 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
405void 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
426bool 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
445bool 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
496void KResolver::cancel(bool emitSignal)
497{
498 KResolverManager::manager()->dequeue(this);
499 if (emitSignal)
500 emitFinished();
501}
502
503KResolverResults
504KResolver::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
516bool 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
527void 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
540QString 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
581KResolverResults
582KResolver::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
594bool 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
608QList<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
668QList<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
728int 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
785int 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
841QList<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
901QList<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
961QString 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
1013static 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
1026QByteArray KResolver::domainToAscii(const QString& unicodeDomain)
1027{
1028 KResolver_initIdnDomains();
1029 return KUrl::toAce(unicodeDomain);
1030}
1031
1032QString KResolver::domainToUnicode(const QByteArray& asciiDomain)
1033{
1034 return domainToUnicode(QString::fromLatin1(asciiDomain));
1035}
1036
1037// implement the ToUnicode function, as described by IDN documents
1038QString KResolver::domainToUnicode(const QString& asciiDomain)
1039{
1040 if (asciiDomain.isEmpty())
1041 return asciiDomain;
1042 KResolver_initIdnDomains();
1043 return KUrl::fromAce(asciiDomain.toLatin1());
1044}
1045
1046QString KResolver::normalizeDomain(const QString& domain)
1047{
1048 return domainToUnicode(domainToAscii(domain));
1049}
1050
1051void 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"
KNetwork::Internal::KResolverManager::manager
static KResolverManager * manager() KDE_NO_EXPORT
Definition: k3resolvermanager.cpp:318
KNetwork::Internal::KResolverManager::notifyWaiters
QWaitCondition notifyWaiters
Definition: k3resolver_p.h:168
KNetwork::Internal::KResolverManager::enqueue
void enqueue(KNetwork::KResolver *obj, RequestData *requestor)
Definition: k3resolvermanager.cpp:650
KNetwork::Internal::KResolverManager::dequeue
void dequeue(KNetwork::KResolver *obj)
Definition: k3resolvermanager.cpp:827
KNetwork::Internal::KResolverManager::ResolutionCompleted
@ ResolutionCompleted
Definition: k3resolver_p.h:160
KNetwork::KResolverEntry
One resolution entry.
Definition: k3resolver.h:69
KNetwork::KResolverEntry::protocol
int protocol() const
Retrieves the protocol associated with this entry.
Definition: k3resolver.cpp:171
KNetwork::KResolverEntry::KResolverEntry
KResolverEntry()
Default constructor.
Definition: k3resolver.cpp:92
KNetwork::KResolverEntry::address
KSocketAddress address() const
Retrieves the socket address associated with this entry.
Definition: k3resolver.cpp:135
KNetwork::KResolverEntry::~KResolverEntry
~KResolverEntry()
Destructor.
Definition: k3resolver.cpp:130
KNetwork::KResolverEntry::socketType
int socketType() const
Retrieves the socket type associated with this entry.
Definition: k3resolver.cpp:165
KNetwork::KResolverEntry::length
quint16 length() const
Retrieves the length of the socket address structure.
Definition: k3resolver.cpp:141
KNetwork::KResolverEntry::family
int family() const
Retrieves the family associated with this socket address.
Definition: k3resolver.cpp:147
KNetwork::KResolverEntry::operator=
KResolverEntry & operator=(const KResolverEntry &other)
Assignment operator.
Definition: k3resolver.cpp:177
KNetwork::KResolverEntry::canonicalName
QString canonicalName() const
Retrieves the canonical name associated with this entry, if there is any.
Definition: k3resolver.cpp:153
KNetwork::KResolverEntry::encodedName
QByteArray encodedName() const
Retrieves the encoded domain name associated with this entry, if there is any.
Definition: k3resolver.cpp:159
KNetwork::KResolverPrivate
Definition: k3resolver_p.h:102
KNetwork::KResolverPrivate::status
volatile int status
Definition: k3resolver_p.h:110
KNetwork::KResolverPrivate::syserror
volatile int syserror
Definition: k3resolver_p.h:111
KNetwork::KResolverPrivate::results
KResolverResults results
Definition: k3resolver_p.h:120
KNetwork::KResolverPrivate::errorcode
volatile int errorcode
Definition: k3resolver_p.h:111
KNetwork::KResolverPrivate::deleteWhenDone
bool deleteWhenDone
Definition: k3resolver_p.h:106
KNetwork::KResolverPrivate::waiting
bool waiting
Definition: k3resolver_p.h:107
KNetwork::KResolverPrivate::input
Internal::InputData input
Definition: k3resolver_p.h:114
KNetwork::KResolverPrivate::mutex
QMutex mutex
Definition: k3resolver_p.h:117
KNetwork::KResolverResults
Name and service resolution results.
Definition: k3resolver.h:213
KNetwork::KResolverResults::KResolverResults
KResolverResults()
Default constructor.
Definition: k3resolver.cpp:198
KNetwork::KResolverResults::setAddress
void setAddress(const QString &host, const QString &service)
Sets the new nodename and service name.
Definition: k3resolver.cpp:260
KNetwork::KResolverResults::~KResolverResults
virtual ~KResolverResults()
Destructor.
Definition: k3resolver.cpp:211
KNetwork::KResolverResults::serviceName
QString serviceName() const
The service name to which the resolution was performed.
Definition: k3resolver.cpp:254
KNetwork::KResolverResults::systemError
int systemError() const
Retrieves the system error code, if any.
Definition: k3resolver.cpp:235
KNetwork::KResolverResults::error
int error() const
Retrieves the error code associated with this resolution.
Definition: k3resolver.cpp:229
KNetwork::KResolverResults::operator=
KResolverResults & operator=(const KResolverResults &other)
Assignment operator.
Definition: k3resolver.cpp:217
KNetwork::KResolverResults::setError
void setError(int errorcode, int systemerror=0)
Sets the error codes.
Definition: k3resolver.cpp:241
KNetwork::KResolverResults::virtual_hook
virtual void virtual_hook(int id, void *data)
Standard hack to add virtuals later.
Definition: k3resolver.cpp:267
KNetwork::KResolverResults::nodeName
QString nodeName() const
The nodename to which the resolution was performed.
Definition: k3resolver.cpp:248
KNetwork::KResolver
Name and service resolution class.
Definition: k3resolver.h:313
KNetwork::KResolver::cancel
void cancel(bool emitSignal=true)
Cancels a running request.
Definition: k3resolver.cpp:496
KNetwork::KResolver::setAddress
void setAddress(const QString &node, const QString &service)
Sets both the host and the service names.
Definition: k3resolver.cpp:360
KNetwork::KResolver::results
KResolverResults results() const
Retrieves the results of this resolution.
Definition: k3resolver.cpp:504
KNetwork::KResolver::nodeName
QString nodeName() const
The nodename to which the resolution was/is to be performed.
Definition: k3resolver.cpp:324
KNetwork::KResolver::serviceName
QString serviceName() const
The service name to which the resolution was/is to be performed.
Definition: k3resolver.cpp:330
KNetwork::KResolver::status
int status() const
Retrieve the current status of this object.
Definition: k3resolver.cpp:295
KNetwork::KResolver::error
int error() const
Retrieve the error code in this object.
Definition: k3resolver.cpp:301
KNetwork::KResolver::setProtocol
void setProtocol(int protonum, const char *name=0L)
Sets the protocol we want.
Definition: k3resolver.cpp:405
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::KResolver::event
virtual bool event(QEvent *)
Handles events.
Definition: k3resolver.cpp:516
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
KNetwork::KResolver::isRunning
bool isRunning() const
Returns true if this object is currently running.
Definition: k3resolver.cpp:318
KNetwork::KResolver::systemError
int systemError() const
Retrieve the associated system error code in this object.
Definition: k3resolver.cpp:307
KNetwork::KResolver::errorString
QString errorString() const
Returns the textual representation of the error in this object.
Definition: k3resolver.cpp:312
KNetwork::KResolver::setFamily
void setFamily(int families)
Sets the allowed socket families.
Definition: k3resolver.cpp:385
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::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::KResolver::CanonName
@ CanonName
Definition: k3resolver.h:370
KNetwork::KResolver::flags
int flags() const
Retrieves the flags set for the resolution.
Definition: k3resolver.cpp:367
KNetwork::KResolver::protocolNumber
static int protocolNumber(const char *protoname)
Resolves a protocol name to its number.
Definition: k3resolver.cpp:728
KNetwork::KResolver::localHostName
static QString localHostName()
Returns this machine's local hostname.
Definition: k3resolver.cpp:961
KNetwork::KResolver::SystemError
@ SystemError
Definition: k3resolver.h:411
KNetwork::KResolver::Canceled
@ Canceled
Definition: k3resolver.h:412
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
KNetwork::KResolver::~KResolver
virtual ~KResolver()
Destructor.
Definition: k3resolver.cpp:288
KNetwork::KResolver::wait
bool wait(int msec=0)
Waits for a request to finish resolving.
Definition: k3resolver.cpp:445
KNetwork::KResolver::setServiceName
void setServiceName(const QString &service)
Sets the service name to be resolved.
Definition: k3resolver.cpp:348
KNetwork::KResolver::Idle
@ Idle
Definition: k3resolver.h:437
KNetwork::KResolver::Success
@ Success
Definition: k3resolver.h:441
KNetwork::KResolver::protocolName
static QList< QByteArray > protocolName(int protonum)
Resolves a protocol number to its names.
Definition: k3resolver.cpp:608
KNetwork::KResolver::setFlags
int setFlags(int flags)
Sets the flags.
Definition: k3resolver.cpp:373
KNetwork::KResolver::setSocketType
void setSocketType(int type)
Sets the socket type we want.
Definition: k3resolver.cpp:395
KNetwork::KResolver::KResolver
KResolver(QObject *parent=0L)
Default constructor.
Definition: k3resolver.cpp:275
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::KResolver::start
bool start()
Starts the name resolution asynchronously.
Definition: k3resolver.cpp:426
KNetwork::KResolver::normalizeDomain
static QString normalizeDomain(const QString &domain)
Normalise a domain name.
Definition: k3resolver.cpp:1046
KNetwork::KResolver::setNodeName
void setNodeName(const QString &nodename)
Sets the nodename for the resolution.
Definition: k3resolver.cpp:336
KNetwork::KResolver::virtual_hook
virtual void virtual_hook(int id, void *data)
Standard hack to add virtuals later.
Definition: k3resolver.cpp:1051
KNetwork::KSocketAddress
A generic socket address.
Definition: k3socketaddress.h:415
QList
Definition: kaboutdata.h:33
QObject
QString
getXXbyYYmutex
QMutex getXXbyYYmutex
Definition: k3resolver.cpp:64
KResolver_initIdnDomains
static void KResolver_initIdnDomains()
Definition: k3resolver.cpp:1013
k3resolver.h
k3resolver_p.h
k3socketaddress.h
klocale.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
I18N_NOOP
#define I18N_NOOP(x)
I18N_NOOP marks a string to be translated without translating it.
Definition: klocalizedstring.h:51
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
kurl.h
KNetwork::Internal
Definition: k3resolver.h:48
KNetwork
A namespace to store all networking-related (socket) classes.
Definition: k3bufferedsocket.h:35
KNetwork::Internal::InputData::flags
int flags
Definition: k3resolver_p.h:94
KNetwork::Internal::InputData::socktype
int socktype
Definition: k3resolver_p.h:96
KNetwork::Internal::InputData::service
QString service
Definition: k3resolver_p.h:92
KNetwork::Internal::InputData::node
QString node
Definition: k3resolver_p.h:92
KNetwork::Internal::InputData::familyMask
int familyMask
Definition: k3resolver_p.h:95
KNetwork::Internal::InputData::protocol
int protocol
Definition: k3resolver_p.h:97
KNetwork::Internal::InputData::protocolName
QByteArray protocolName
Definition: k3resolver_p.h:93
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
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