• 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
netsupp.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2000,2001 Thiago Macieira <thiago.macieira@kdemail.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB. If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  **/
20 
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <netinet/in.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <arpa/inet.h>
30 
31 #include <QtCore/QBool>
32 
33 #include <kdebug.h>
34 
35 // This is so that, if addrinfo is defined, it doesn't clobber our definition
36 // It might be defined in the few cases in which we are replacing the system's
37 // broken getaddrinfo
38 #include <netdb.h>
39 
40 #include <config.h>
41 #include <config-network.h>
42 #include "klocale.h"
43 
44 #ifndef IN6_IS_ADDR_V4MAPPED
45 #define NEED_IN6_TESTS
46 #endif
47 #undef CLOBBER_IN6
48 #include "netsupp.h" //krazy:exclude=includes (netsupp.h not installed; KDE3 compat code)
49 
50 #if defined(__hpux) || defined(_HPUX_SOURCE)
51 extern int h_errno;
52 #endif
53 
54 #if !defined(kde_sockaddr_in6)
55 /*
56  * kde_sockaddr_in6 might have got defined even though we #undef'ed
57  * CLOBBER_IN6. This happens when we are compiling under --enable-final.
58  * However, in that case, if it was defined, that's because ksockaddr.cpp
59  * had it defined because sockaddr_in6 didn't exist, and so sockaddr_in6
60  * exists and is our kde_sockaddr_in6
61  */
62 # define sockaddr_in6 kde_sockaddr_in6
63 # define in6_addr kde_in6_addr
64 #endif
65 
66 #ifdef offsetof
67 #undef offsetof
68 #endif
69 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
70 
71 /*
72  * These constants tell the flags in KDE::resolverFlags
73  * The user could (but shouldn't) test the variable to know what kind of
74  * resolution is supported
75  */
76 #define KRF_KNOWS_AF_INET6 0x01 /* if present, the code knows about AF_INET6 */
77 #define KRF_USING_OWN_GETADDRINFO 0x02 /* if present, we are using our own getaddrinfo */
78 #define KRF_USING_OWN_INET_NTOP 0x04 /* if present, we are using our own inet_ntop */
79 #define KRF_USING_OWN_INET_PTON 0x08 /* if present, we are using our own inet_pton */
80 #define KRF_CAN_RESOLVE_UNIX 0x100 /* if present, the resolver can resolve Unix sockets */
81 #define KRF_CAN_RESOLVE_IPV4 0x200 /* if present, the resolver can resolve to IPv4 */
82 #define KRF_CAN_RESOLVE_IPV6 0x400 /* if present, the resolver can resolve to IPv6 */
83 
84 
85 static void dofreeaddrinfo(struct addrinfo *ai)
86 {
87  while (ai)
88  {
89  struct addrinfo *ai2 = ai;
90  if (ai->ai_canonname != NULL)
91  free(ai->ai_canonname);
92 
93  if (ai->ai_addr != NULL)
94  free(ai->ai_addr);
95 
96  ai = ai->ai_next;
97  free(ai2);
98  }
99 }
100 
101 void kde_freeaddrinfo(struct kde_addrinfo *ai)
102 {
103  if (ai->origin == KAI_LOCALUNIX)
104  {
105  struct addrinfo *p, *last = NULL;
106  /* We've added one AF_UNIX socket in here, to the
107  * tail of the linked list. We have to find it */
108  for (p = ai->data; p; p = p->ai_next)
109  {
110  if (p->ai_family == AF_UNIX)
111  {
112  if (last)
113  {
114  last->ai_next = NULL;
115  freeaddrinfo(ai->data);
116  }
117  dofreeaddrinfo(p);
118  break;
119  }
120  last = p;
121  }
122  }
123  else
124  freeaddrinfo(ai->data);
125 
126  free(ai);
127 }
128 
129 static struct addrinfo*
130 make_unix(const char *name, const char *serv)
131 {
132  const char *buf;
133  struct addrinfo *p;
134  struct sockaddr_un *_sun;
135  int len;
136 
137  p = (addrinfo*)malloc(sizeof(*p));
138  if (p == NULL)
139  return NULL;
140  memset(p, 0, sizeof(*p));
141 
142  if (name != NULL)
143  buf = name;
144  else
145  buf = serv;
146 
147  // Calculate length of the binary representation
148  len = strlen(buf) + offsetof(struct sockaddr_un, sun_path) + 1;
149  if (*buf != '/')
150  len += 5; // strlen("/tmp/");
151 
152  _sun = (sockaddr_un*)malloc(len);
153  if (_sun == NULL)
154  {
155  // Oops
156  free(p);
157  return NULL;
158  }
159 
160  _sun->sun_family = AF_UNIX;
161 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
162  _sun->sun_len = len;
163 # endif
164  if (*buf == '/')
165  *_sun->sun_path = '\0'; // empty it
166  else
167  strcpy(_sun->sun_path, "/tmp/");
168  strcat(_sun->sun_path, buf);
169 
170  // Set the addrinfo
171  p->ai_family = AF_UNIX;
172  p->ai_addrlen = len;
173  p->ai_addr = (sockaddr*)_sun;
174  p->ai_canonname = qstrdup(buf);
175 
176  return p;
177 }
178 
179 // Ugh. I hate #ifdefs
180 // Anyways, here's what this does:
181 // KDE_IPV6_LOOKUP_MODE != 1, this function doesn't exist
182 // AF_INET6 not defined, we say there is no IPv6 stack
183 // otherwise, we try to create a socket.
184 // returns: 1 for IPv6 stack available, 2 for not available
185 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
186 static int check_ipv6_stack()
187 {
188 # ifndef AF_INET6
189  return 2; // how can we check?
190 # else
191  if (!qgetenv("KDE_NO_IPV6").isEmpty())
192  return 2;
193  int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
194  if (fd == -1)
195  return 2;
196 
197  ::close(fd);
198  return 1;
199 # endif
200 }
201 #endif
202 
203 
204 /*
205  * Reason for using this function: kde_getaddrinfo
206  *
207  * I decided to add this wrapper function for getaddrinfo
208  * and have this be called by KExtendedSocket instead of
209  * the real getaddrinfo so that we can make sure that the
210  * behavior is the desired one.
211  *
212  * Currently, the only "undesired" behavior is getaddrinfo
213  * not returning PF_UNIX sockets in some implementations.
214  *
215  * getaddrinfo and family are defined in POSIX 1003.1g
216  * (Protocol Independent Interfaces) and in RFC 2553
217  * (Basic Socket Interface for IPv6). Whereas the RFC is ambiguosly
218  * vague whether this family of functions should return Internet
219  * sockets only or not, the name of the POSIX draft says
220  * otherwise: it should be independent of protocol.
221  *
222  * So, my interpretation is that they should return every
223  * kind of socket available and known and that's how I
224  * designed KExtendedSocket on top of it.
225  *
226  * That's why there's this wrapper, to make sure PF_UNIX
227  * sockets are returned when expected.
228  */
229 
230 int kde_getaddrinfo(const char *name, const char *service,
231  const struct addrinfo* hint,
232  struct kde_addrinfo** result)
233 {
234  struct kde_addrinfo* res;
235  struct addrinfo* p;
236  int err = EAI_SERVICE;
237 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
238  // mode 1: do a check on whether we have an IPv6 stack
239  static int ipv6_stack = 0; // 0: unknown, 1: yes, 2: no
240 #endif
241 
242  // allocate memory for results
243  res = (kde_addrinfo*)malloc(sizeof(*res));
244  if (res == NULL)
245  return EAI_MEMORY;
246  res->data = NULL;
247  res->origin = KAI_SYSTEM; // at first, it'll be only system data
248 
249  struct addrinfo* last = NULL;
250 
251  // Skip the getaddrinfo call and the ipv6 check for a UNIX socket.
252  if (hint && (hint->ai_family == PF_UNIX))
253  {
254  if (service == NULL || *service == '\0')
255  goto out; // can't be Unix if no service was requested
256 
257  // Unix sockets must be localhost
258  // That is, either name is NULL or, if it's not, it must be empty,
259  // "*" or "localhost"
260  if (name != NULL && !(name[0] == '\0' || (name[0] == '*' && name[1] == '\0') ||
261  strcmp("localhost", name) == 0))
262  goto out; // isn't localhost
263 
264  goto do_unix;
265  }
266 
267 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 0
268 # if KDE_IPV6_LOOKUP_MODE == 1
269  // mode 1: do a check on whether we have an IPv6 stack
270  if (ipv6_stack == 0)
271  ipv6_stack = check_ipv6_stack();
272 
273  if (ipv6_stack == 2)
274  {
275 # endif
276  // here we have modes 1 and 2 (no lookups)
277  // this is shared code
278  struct addrinfo our_hint;
279  if (hint != NULL)
280  {
281  memcpy(&our_hint, hint, sizeof(our_hint));
282  if (our_hint.ai_family == AF_UNSPEC)
283  our_hint.ai_family = AF_INET;
284  }
285  else
286  {
287  memset(&our_hint, 0, sizeof(our_hint));
288  our_hint.ai_family = AF_INET;
289  }
290 
291  // do the actual resolution
292  err = getaddrinfo(name, service, &our_hint, &res->data);
293 # if KDE_IPV6_LOOKUP_MODE == 1
294  }
295  else
296 # endif
297 #endif
298 #if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 2
299  // do the IPV6 resolution
300  err = getaddrinfo(name, service, hint, &res->data);
301 #endif
302 
303  // Now we have to check whether the user could want a Unix socket
304 
305  if (service == NULL || *service == '\0')
306  goto out; // can't be Unix if no service was requested
307 
308  // Unix sockets must be localhost
309  // That is, either name is NULL or, if it's not, it must be empty,
310  // "*" or "localhost"
311  if (name != NULL && !(name[0] == '\0' || (name[0] == '*' && name[1] == '\0') ||
312  strcmp("localhost", name) == 0))
313  goto out; // isn't localhost
314 
315  // Unix sockets can only be returned if the user asked for a PF_UNSPEC
316  // or PF_UNIX socket type or gave us a NULL hint
317  if (hint != NULL && (hint->ai_family != PF_UNSPEC && hint->ai_family != PF_UNIX))
318  goto out; // user doesn't want Unix
319 
320  // If we got here, then it means that the user might be expecting Unix
321  // sockets. The user wants a local socket, with a non-null service and
322  // has told us that they accept PF_UNIX sockets
323  // Check whether the system implementation returned Unix
324  if (err == 0)
325  for (p = res->data; p; p = p->ai_next)
326  {
327  last = p; // we have to find out which one is last anyways
328  if (p->ai_family == AF_UNIX)
329  // there is an Unix node
330  goto out;
331  }
332 
333  do_unix:
334  // So, give the user a PF_UNIX socket
335  p = make_unix(NULL, service);
336  if (p == NULL)
337  {
338  err = EAI_MEMORY;
339  goto out;
340  }
341  if (hint != NULL)
342  p->ai_socktype = hint->ai_socktype;
343  if (p->ai_socktype == 0)
344  p->ai_socktype = SOCK_STREAM; // default
345 
346  if (last)
347  last->ai_next = p;
348  else
349  res->data = p;
350  res->origin = KAI_LOCALUNIX;
351  *result = res;
352  return 0;
353 
354  out:
355  if (res->data != NULL)
356  freeaddrinfo(res->data);
357  free(res);
358  return err;
359 }
360 
361 #if defined(HAVE_GETADDRINFO) && !defined(HAVE_BROKEN_GETADDRINFO)
362 
363 #define KRF_getaddrinfo 0
364 #define KRF_resolver 0
365 
366 #else // !defined(HAVE_GETADDRINFO) || defined(HAVE_BROKEN_GETADDRINFO)
367 
368 #define KRF_getaddrinfo KRF_USING_OWN_GETADDRINFO
369 #define KRF_resolver KRF_CAN_RESOLVE_UNIX | KRF_CAN_RESOLVE_IPV4
370 
371 /*
372  * No getaddrinfo() in this system.
373  * We shall provide our own
374  */
375 
379 static int inet_lookup(const char *name, int portnum, int protonum,
380  struct addrinfo *p, const struct addrinfo *hint,
381  struct addrinfo** result)
382 {
383  struct addrinfo *q;
384  struct hostent *h;
385  struct sockaddr **psa = NULL;
386  int len;
387 
388  // TODO
389  // Currently, this never resolves IPv6 (need gethostbyname2, etc.)
390 # ifdef AF_INET6
391  if (hint->ai_family == AF_INET6)
392  {
393  if (p != NULL)
394  {
395  *result = p;
396  return 0;
397  }
398  return EAI_FAIL;
399  }
400 # endif
401 
402  h = gethostbyname(name);
403  if (h == NULL)
404  {
405  if (p != NULL)
406  {
407  // There already is a suitable result
408  *result = p;
409  return 0;
410  }
411 
412  switch (h_errno)
413  {
414  case HOST_NOT_FOUND:
415  return EAI_NONAME;
416  case TRY_AGAIN:
417  return EAI_AGAIN;
418  case NO_RECOVERY:
419  return EAI_FAIL;
420  case NO_ADDRESS:
421  return EAI_NODATA;
422  default:
423  // EH!?
424  return EAI_FAIL;
425  }
426  }
427 
428  q = (addrinfo*)malloc(sizeof(*q));
429  if (q == NULL)
430  {
431  freeaddrinfo(p);
432  return EAI_MEMORY;
433  }
434 
435  // convert the hostent to addrinfo
436  if (h->h_addrtype == AF_INET && (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC))
437  len = sizeof(struct sockaddr_in);
438 # ifdef AF_INET6
439  else if (h->h_addrtype == AF_INET6 && (hint->ai_family == AF_INET6 ||
440  hint->ai_family == AF_UNSPEC))
441  len = sizeof(struct sockaddr_in6);
442 # endif
443  else
444  {
445  free(q);
446  // We don't know what to do with these addresses
447  // Or gethostbyname returned information we don't want
448  if (p != NULL)
449  {
450  *result = p;
451  return 0;
452  }
453  return EAI_NODATA;
454  }
455 
456  q->ai_flags = 0;
457  q->ai_family = h->h_addrtype;
458  q->ai_socktype = hint->ai_socktype;
459  q->ai_protocol = protonum;
460  q->ai_addrlen = len;
461 
462  q->ai_addr = (sockaddr*)malloc(len);
463  if (q->ai_addr == NULL)
464  {
465  free(q);
466  freeaddrinfo(p);
467  return EAI_MEMORY;
468  }
469  if (h->h_addrtype == AF_INET)
470  {
471  struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;
472  sin->sin_family = AF_INET;
473 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
474  sin->sin_len = sizeof(*sin);
475 # endif
476  sin->sin_port = portnum;
477  memcpy(&sin->sin_addr, h->h_addr, h->h_length);
478  }
479 # ifdef AF_INET6
480  else if (h->h_addrtype == AF_INET6)
481  {
482  struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;
483  sin6->sin6_family = AF_INET6;
484 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
485  sin6->sin6_len = sizeof(*sin6);
486 # endif
487  sin6->sin6_port = portnum;
488  sin6->sin6_flowinfo = 0;
489  memcpy(&sin6->sin6_addr, h->h_addr, h->h_length);
490  sin6->sin6_scope_id = 0;
491  }
492 # endif
493 
494  if (hint->ai_flags & AI_CANONNAME)
495  q->ai_canonname = qstrdup(h->h_name);
496  else
497  q->ai_canonname = NULL;
498 
499  q->ai_next = p;
500  p = q;
501 
502  // cycle through the rest of the hosts;
503  for (psa = (sockaddr**)h->h_addr_list + 1; *psa; psa++)
504  {
505  q = (addrinfo*)malloc(sizeof(*q));
506  if (q == NULL)
507  {
508  freeaddrinfo(p);
509  return EAI_MEMORY;
510  }
511  memcpy(q, p, sizeof(*q));
512 
513  q->ai_addr = (sockaddr*)malloc(h->h_length);
514  if (q->ai_addr == NULL)
515  {
516  freeaddrinfo(p);
517  free(q);
518  return EAI_MEMORY;
519  }
520  if (h->h_addrtype == AF_INET)
521  {
522  struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;
523  sin->sin_family = AF_INET;
524 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
525  sin->sin_len = sizeof(*sin);
526 # endif
527  sin->sin_port = portnum;
528  memcpy(&sin->sin_addr, *psa, h->h_length);
529  }
530 # ifdef AF_INET6
531  else if (h->h_addrtype == AF_INET6)
532  {
533  struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;
534  sin6->sin6_family = AF_INET6;
535 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
536  sin6->sin6_len = sizeof(*sin6);
537 # endif
538  sin6->sin6_port = portnum;
539  sin6->sin6_flowinfo = 0;
540  memcpy(&sin6->sin6_addr, *psa, h->h_length);
541  sin6->sin6_scope_id = 0;
542  }
543 # endif
544 
545  if (q->ai_canonname != NULL)
546  q->ai_canonname = qstrdup(q->ai_canonname);
547 
548  q->ai_next = p;
549  p = q;
550  }
551 
552  *result = p;
553  return 0; // Whew! Success!
554 }
555 
556 static int make_inet(const char *name, int portnum, int protonum, struct addrinfo *p,
557  const struct addrinfo *hint, struct addrinfo** result)
558 {
559  struct addrinfo *q;
560 
561  do
562  {
563  // This 'do' is here just so that we can 'break' out of it
564 
565  if (name != NULL)
566  {
567  // first, try to use inet_pton before resolving
568  // it will catch IP addresses given without having to go to lookup
569  struct sockaddr_in *sin;
570  struct in_addr in;
571 # ifdef AF_INET6
572  struct sockaddr_in6 *sin6;
573  struct in6_addr in6;
574 
575  if (hint->ai_family == AF_INET6 || (hint->ai_family == AF_UNSPEC &&
576  strchr(name, ':') != NULL))
577  {
578  // yes, this is IPv6
579  if (inet_pton(AF_INET6, name, &in6) != 1)
580  {
581  if (hint->ai_flags & AI_NUMERICHOST)
582  {
583  freeaddrinfo(p);
584  return EAI_FAIL;
585  }
586  break; // not a numeric host
587  }
588 
589  sin6 = (sockaddr_in6*)malloc(sizeof(*sin6));
590  if (sin6 == NULL)
591  {
592  freeaddrinfo(p);
593  return EAI_MEMORY;
594  }
595  memcpy(&sin6->sin6_addr, &in6, sizeof(in6));
596 
597  if (strchr(name, '%') != NULL)
598  {
599  errno = 0;
600  sin6->sin6_scope_id = strtoul(strchr(name, '%') + 1, NULL, 10);
601  if (errno != 0)
602  sin6->sin6_scope_id = 0; // no interface
603  }
604 
605  q = (addrinfo*)malloc(sizeof(*q));
606  if (q == NULL)
607  {
608  freeaddrinfo(p);
609  free(sin6);
610  return EAI_MEMORY;
611  }
612 
613  sin6->sin6_family = AF_INET6;
614 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
615  sin6->sin6_len = sizeof(*sin6);
616 # endif
617  sin6->sin6_port = portnum;
618  sin6->sin6_flowinfo = 0;
619 
620  q->ai_flags = 0;
621  q->ai_family = AF_INET6;
622  q->ai_socktype = hint->ai_socktype;
623  q->ai_protocol = protonum;
624  q->ai_addrlen = sizeof(*sin6);
625  q->ai_canonname = NULL;
626  q->ai_addr = (sockaddr*)sin6;
627  q->ai_next = p;
628 
629  *result = q;
630  return 0; // success!
631  }
632 # endif // AF_INET6
633 
634  if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)
635  {
636  // This has to be IPv4
637  if (inet_pton(AF_INET, name, &in) != 1)
638  {
639  if (hint->ai_flags & AI_NUMERICHOST)
640  {
641  freeaddrinfo(p);
642  return EAI_FAIL; // invalid, I guess
643  }
644  break; // not a numeric host, do lookup
645  }
646 
647  sin = (sockaddr_in*)malloc(sizeof(*sin));
648  if (sin == NULL)
649  {
650  freeaddrinfo(p);
651  return EAI_MEMORY;
652  }
653 
654  q = (addrinfo*)malloc(sizeof(*q));
655  if (q == NULL)
656  {
657  freeaddrinfo(p);
658  free(sin);
659  return EAI_MEMORY;
660  }
661 
662  sin->sin_family = AF_INET;
663 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
664  sin->sin_len = sizeof(*sin);
665 # endif
666  sin->sin_port = portnum;
667  sin->sin_addr = in;
668 
669  q->ai_flags = 0;
670  q->ai_family = AF_INET;
671  q->ai_socktype = hint->ai_socktype;
672  q->ai_protocol = protonum;
673  q->ai_addrlen = sizeof(*sin);
674  q->ai_canonname = NULL;
675  q->ai_addr = (sockaddr*)sin;
676  q->ai_next = p;
677  *result = q;
678  return 0;
679  }
680 
681  // Eh, what!?
682  // One of the two above has to have matched
683  kError() << "I wasn't supposed to get here!";
684  }
685  } while (false);
686 
687  // This means localhost
688  if (name == NULL)
689  {
690  struct sockaddr_in *sin = (sockaddr_in*)malloc(sizeof(*sin));
691 # ifdef AF_INET6
692  struct sockaddr_in6 *sin6;
693 # endif
694 
695  if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)
696  {
697  if (sin == NULL)
698  {
699  free(sin);
700  freeaddrinfo(p);
701  return EAI_MEMORY;
702  }
703 
704  // Do IPv4 first
705  q = (addrinfo*)malloc(sizeof(*q));
706  if (q == NULL)
707  {
708  free(sin);
709  freeaddrinfo(p);
710  return EAI_MEMORY;
711  }
712 
713  sin->sin_family = AF_INET;
714 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
715  sin->sin_len = sizeof(*sin);
716 # endif
717  sin->sin_port = portnum;
718  if (hint->ai_flags & AI_PASSIVE)
719  *(quint32*)&sin->sin_addr = INADDR_ANY;
720  else
721  *(quint32*)&sin->sin_addr = htonl(INADDR_LOOPBACK);
722  q->ai_flags = 0;
723  q->ai_family = AF_INET;
724  q->ai_socktype = hint->ai_socktype;
725  q->ai_protocol = protonum;
726  q->ai_addrlen = sizeof(*sin);
727  q->ai_canonname = NULL;
728  q->ai_addr = (sockaddr*)sin;
729  q->ai_next = p;
730  p = q;
731  }
732 
733 # ifdef AF_INET6
734  // Try now IPv6
735 
736  if (hint->ai_family == AF_INET6 || hint->ai_family == AF_UNSPEC)
737  {
738  sin6 = (sockaddr_in6*)malloc(sizeof(*sin6));
739  q = (addrinfo*)malloc(sizeof(*q));
740  if (q == NULL || sin6 == NULL)
741  {
742  free(sin);
743  free(sin6);
744  free(q);
745  freeaddrinfo(p);
746  return EAI_MEMORY;
747  }
748 
749  sin6->sin6_family = AF_INET6;
750 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
751  sin6->sin6_len = sizeof(*sin6);
752 # endif
753  sin6->sin6_port = portnum;
754  sin6->sin6_flowinfo = 0;
755  sin6->sin6_scope_id = 0;
756 
757  // We don't want to use in6addr_loopback and in6addr_any
758  memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));
759  if ((hint->ai_flags & AI_PASSIVE) == 0)
760  ((char*)&sin6->sin6_addr)[15] = 1;
761 
762  q->ai_flags = 0;
763  q->ai_family = AF_INET6;
764  q->ai_socktype = hint->ai_socktype;
765  q->ai_protocol = protonum;
766  q->ai_addrlen = sizeof(*sin6);
767  q->ai_canonname = NULL;
768  q->ai_addr = (sockaddr*)sin6;
769  q->ai_next = p;
770  p = q;
771  }
772 
773 # endif // AF_INET6
774 
775  *result = p;
776  free(sin);
777  return 0; // success!
778  }
779 
780  return inet_lookup(name, portnum, protonum, p, hint, result);
781 }
782 
783 
784 int getaddrinfo(const char *name, const char *serv,
785  const struct addrinfo* hint,
786  struct addrinfo** result)
787 {
788  unsigned short portnum; // remember to store in network byte order
789  int protonum = IPPROTO_TCP;
790  const char *proto = "tcp";
791  struct addrinfo *p = NULL;
792 
793  // Sanity checks:
794  if (hint == NULL || result == NULL)
795  return EAI_BADFLAGS;
796  if (hint->ai_family != AF_UNSPEC && hint->ai_family != AF_UNIX &&
797  hint->ai_family != AF_INET
798 # ifdef AF_INET6
799  && hint->ai_family != AF_INET6
800 # endif
801  )
802  return EAI_FAMILY;
803  if (hint->ai_socktype != 0 && hint->ai_socktype != SOCK_STREAM &&
804  hint->ai_socktype != SOCK_DGRAM)
805  return EAI_SOCKTYPE;
806 
807  // Treat hostname of "*" as NULL, which means localhost
808  if (name != NULL && ((*name == '*' && name[1] == '\0') || *name == '\0'))
809  name = NULL;
810  // Treat service of "*" as NULL, which I guess means no port (0)
811  if (serv != NULL && ((*serv == '*' && serv[1] == '\0') || *serv == '\0'))
812  serv = NULL;
813 
814  if (name == NULL && serv == NULL) // what the hell do you want?
815  return EAI_NONAME;
816 
817  // This is just to make it easier
818  if (name != NULL && strcmp(name, "localhost") == 0)
819  name = NULL;
820 
821  // First, check for a Unix socket
822  // family must be either AF_UNIX or AF_UNSPEC
823  // either of name or serv must be set, the other must be NULL or empty
824  if (hint->ai_family == AF_UNIX || hint->ai_family == AF_UNSPEC)
825  {
826  if (name != NULL && serv != NULL)
827  {
828  // This is not allowed
829  if (hint->ai_family == AF_UNIX)
830  return EAI_BADFLAGS;
831  }
832  else
833  {
834  p = make_unix(name, serv);
835  if (p == NULL)
836  return EAI_MEMORY;
837 
838  p->ai_socktype = hint->ai_socktype;
839  // If the name/service started with a slash, then this *IS*
840  // only a Unix socket. Return.
841  if (hint->ai_family == AF_UNIX || ((name != NULL && *name == '/') ||
842  (serv != NULL && *serv == '/')))
843  {
844  *result = p;
845  return 0; // successful lookup
846  }
847  }
848  }
849 
850  // Lookup the service name, if required
851  if (serv != NULL)
852  {
853  char *tail;
854  struct servent *sent;
855 
856  portnum = htons((unsigned)strtoul(serv, &tail, 10));
857  if (*tail != '\0')
858  {
859  // not a number. We have to do the lookup
860  if (hint->ai_socktype == SOCK_DGRAM)
861  {
862  proto = "udp";
863  protonum = IPPROTO_UDP;
864  }
865 
866  sent = getservbyname(serv, proto);
867  if (sent == NULL) // no service?
868  {
869  if (p == NULL)
870  return EAI_NONAME;
871  else
872  return 0; // a Unix socket available
873  }
874 
875  portnum = sent->s_port;
876  }
877  }
878  else
879  portnum = 0; // no port number
880 
881  return make_inet(name, portnum, protonum, p, hint, result);
882 }
883 
884 void freeaddrinfo(struct addrinfo *p)
885 {
886  dofreeaddrinfo(p);
887 }
888 
889 #ifndef HAVE_GAI_STRERROR_PROTO
890 char *gai_strerror(int errorcode)
891 {
892  static const char messages[] =
893  {
894  I18N_NOOP("no error")"\0" // 0
895  I18N_NOOP("address family for nodename not supported")"\0" // EAI_ADDRFAMILY
896  I18N_NOOP("temporary failure in name resolution")"\0" // EAI_AGAIN
897  I18N_NOOP("invalid value for 'ai_flags'")"\0" // EAI_BADFLAGS
898  I18N_NOOP("non-recoverable failure in name resolution")"\0" // EAI_FAIL
899  I18N_NOOP("'ai_family' not supported")"\0" // EAI_FAMILY
900  I18N_NOOP("memory allocation failure")"\0" // EAI_MEMORY
901  I18N_NOOP("no address associated with nodename")"\0" // EAI_NODATA
902  I18N_NOOP("name or service not known")"\0" // EAI_NONAME
903  I18N_NOOP("servname not supported for ai_socktype")"\0" // EAI_SERVICE
904  I18N_NOOP("'ai_socktype' not supported")"\0" // EAI_SOCKTYPE
905  I18N_NOOP("system error")"\0" // EAI_SYSTEM
906  "\0"
907  };
908 
909  static const int messages_indices[] =
910  {
911  0, 9, 51, 88, 117, 160, 186, 212,
912  248, 274, 313, 341, 0
913  };
914 
915  Q_ASSERT(sizeof(messages_indices)/sizeof(messages_indices[0]) >= EAI_SYSTEM);
916  if (errorcode > EAI_SYSTEM || errorcode < 0)
917  return NULL;
918 
919  static char buffer[200];
920  strcpy(buffer, i18n(messages + messages_indices[errorcode]).toLocal8Bit());
921  return buffer;
922 }
923 #endif
924 
925 static void findport(unsigned short port, char *serv, size_t servlen, int flags)
926 {
927  if (serv == NULL)
928  return;
929 
930  if ((flags & NI_NUMERICSERV) == 0)
931  {
932  struct servent *sent;
933  sent = getservbyport(ntohs(port), flags & NI_DGRAM ? "udp" : "tcp");
934  if (sent != NULL && servlen > strlen(sent->s_name))
935  {
936  strcpy(serv, sent->s_name);
937  return;
938  }
939  }
940 
941  qsnprintf(serv, servlen, "%u", ntohs(port));
942 }
943 
944 int getnameinfo(const struct sockaddr *sa, kde_socklen_t salen,
945  char *host, size_t hostlen, char *serv, size_t servlen,
946  int flags)
947 {
948  union
949  {
950  const sockaddr *sa;
951  const sockaddr_un *_sun;
952  const sockaddr_in *sin;
953  const sockaddr_in6 *sin6;
954  } s;
955 
956  if ((host == NULL || hostlen == 0) && (serv == NULL || servlen == 0))
957  return 1;
958 
959  s.sa = sa;
960  if (s.sa->sa_family == AF_UNIX)
961  {
962  if (salen < offsetof(struct sockaddr_un, sun_path) + strlen(s._sun->sun_path) + 1)
963  return 1; // invalid socket
964 
965  if (servlen && serv != NULL)
966  *serv = '\0';
967  if (host != NULL && hostlen > strlen(s._sun->sun_path))
968  strcpy(host, s._sun->sun_path);
969 
970  return 0;
971  }
972  else if (s.sa->sa_family == AF_INET)
973  {
974  if (salen < offsetof(struct sockaddr_in, sin_addr) + sizeof(s.sin->sin_addr))
975  return 1; // invalid socket
976 
977  if (flags & NI_NUMERICHOST)
978  inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
979  else
980  {
981  // have to do lookup
982  struct hostent *h = gethostbyaddr((const char*)&s.sin->sin_addr, sizeof(s.sin->sin_addr),
983  AF_INET);
984  if (h == NULL && flags & NI_NAMEREQD)
985  return 1;
986  else if (h == NULL)
987  inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
988  else if (host != NULL && hostlen > strlen(h->h_name))
989  strcpy(host, h->h_name);
990  else
991  return 1; // error
992  }
993 
994  findport(s.sin->sin_port, serv, servlen, flags);
995  }
996 # ifdef AF_INET6
997  else if (s.sa->sa_family == AF_INET6)
998  {
999  if (salen < offsetof(struct sockaddr_in6, sin6_addr) + sizeof(s.sin6->sin6_addr))
1000  return 1; // invalid socket
1001 
1002  if (flags & NI_NUMERICHOST)
1003  inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
1004  else
1005  {
1006  // have to do lookup
1007  struct hostent *h = gethostbyaddr((const char*)&s.sin->sin_addr, sizeof(s.sin->sin_addr),
1008  AF_INET6);
1009  if (h == NULL && flags & NI_NAMEREQD)
1010  return 1;
1011  else if (h == NULL)
1012  inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
1013  else if (host != NULL && hostlen > strlen(h->h_name))
1014  strcpy(host, h->h_name);
1015  else
1016  return 1; // error
1017  }
1018 
1019  findport(s.sin6->sin6_port, serv, servlen, flags);
1020  }
1021 # endif // AF_INET6
1022 
1023  return 1; // invalid family
1024 }
1025 
1026 #endif // HAVE_GETADDRINFO
1027 
1028 #ifndef HAVE_INET_NTOP
1029 
1030 #define KRF_inet_ntop KRF_USING_OWN_INET_NTOP
1031 
1032 static void add_dwords(char *buf, quint16 *dw, int count)
1033 {
1034  int i = 1;
1035  sprintf(buf + strlen(buf), "%x", ntohs(dw[0]));
1036  while (--count)
1037  sprintf(buf + strlen(buf), ":%x", ntohs(dw[i++]));
1038 }
1039 
1040 const char* inet_ntop(int af, const void *cp, char *buf, size_t len)
1041 {
1042  char buf2[sizeof "1234:5678:9abc:def0:1234:5678:255.255.255.255" + 1];
1043  quint8 *data = (quint8*)cp;
1044 
1045  if (af == AF_INET)
1046  {
1047  sprintf(buf2, "%u.%u.%u.%u", data[0], data[1], data[2], data[3]);
1048 
1049  if (len > strlen(buf2))
1050  {
1051  strcpy(buf, buf2);
1052  return buf;
1053  }
1054 
1055  errno = ENOSPC;
1056  return NULL; // failed
1057  }
1058 
1059 # ifdef AF_INET6
1060  if (af == AF_INET6)
1061  {
1062  quint16 *p = (quint16*)data;
1063  quint16 *longest = NULL, *cur = NULL;
1064  int longest_length = 0, cur_length;
1065  int i;
1066 
1067  if (KDE_IN6_IS_ADDR_V4MAPPED(p) || KDE_IN6_IS_ADDR_V4COMPAT(p))
1068  sprintf(buf2, "::%s%u.%u.%u.%u",
1069  KDE_IN6_IS_ADDR_V4MAPPED(p) ? "ffff:" : "",
1070  buf[12], buf[13], buf[14], buf[15]);
1071  else
1072  {
1073  // find the longest sequence of zeroes
1074  for (i = 0; i < 8; --i)
1075  if (cur == NULL && p[i] == 0)
1076  {
1077  // a zero, start the sequence
1078  cur = p + i;
1079  cur_length = 1;
1080  }
1081  else if (cur != NULL && p[i] == 0)
1082  // part of the sequence
1083  cur_length++;
1084  else if (cur != NULL && p[i] != 0)
1085  {
1086  // end of the sequence
1087  if (cur_length > longest_length)
1088  {
1089  longest_length = cur_length;
1090  longest = cur;
1091  }
1092  cur = NULL; // restart sequence
1093  }
1094  if (cur != NULL && cur_length > longest_length)
1095  {
1096  longest_length = cur_length;
1097  longest = cur;
1098  }
1099 
1100  if (longest_length > 1)
1101  {
1102  // We have a candidate
1103  buf2[0] = '\0';
1104  if (longest != p)
1105  add_dwords(buf2, p, longest - p);
1106  strcat(buf2, "::");
1107  if (longest + longest_length < p + 8)
1108  add_dwords(buf2, longest + longest_length, 8 - (longest - p) - longest_length);
1109  }
1110  else
1111  {
1112  // Nope, no candidate
1113  buf2[0] = '\0';
1114  add_dwords(buf2, p, 8);
1115  }
1116  }
1117 
1118  if (strlen(buf2) < len)
1119  {
1120  strcpy(buf, buf2);
1121  return buf;
1122  }
1123 
1124  errno = ENOSPC;
1125  return NULL;
1126  }
1127 # endif
1128 
1129  errno = EAFNOSUPPORT;
1130  return NULL; // a family we don't know about
1131 }
1132 
1133 #else // HAVE_INET_NTOP
1134 
1135 #define KRF_inet_ntop 0
1136 
1137 #endif // HAVE_INET_NTOP
1138 
1139 #ifndef HAVE_INET_PTON
1140 
1141 #define KRF_inet_pton KRF_USING_OWN_INET_PTON
1142 int inet_pton(int af, const char *cp, void *buf)
1143 {
1144  if (af == AF_INET)
1145  {
1146  // Piece of cake
1147  unsigned p[4];
1148  unsigned char *q = (unsigned char*)buf;
1149  if (sscanf(cp, "%u.%u.%u.%u", p, p + 1, p + 2, p + 3) != 4)
1150  return 0;
1151 
1152  if (p[0] > 0xff || p[1] > 0xff || p[2] > 0xff || p[3] > 0xff)
1153  return 0;
1154 
1155  q[0] = p[0];
1156  q[1] = p[1];
1157  q[2] = p[2];
1158  q[3] = p[3];
1159 
1160  return 1;
1161  }
1162 
1163 # ifdef AF_INET6
1164  else if (af == AF_INET6)
1165  {
1166  quint16 addr[8];
1167  const char *p = cp;
1168  int n = 0, start = 8;
1169  bool has_v4 = strchr(p, '.') != NULL;
1170 
1171  memset(addr, 0, sizeof(addr));
1172 
1173  if (*p == '\0' || p[1] == '\0')
1174  return 0; // less than 2 chars is not valid
1175 
1176  if (*p == ':' && p[1] == ':')
1177  {
1178  start = 0;
1179  p += 2;
1180  }
1181  while (*p)
1182  {
1183  if (has_v4 && inet_pton(AF_INET, p, addr + n) != 0)
1184  {
1185  // successful v4 convertion
1186  addr[n] = ntohs(addr[n]);
1187  n++;
1188  addr[n] = ntohs(addr[n]);
1189  n++;
1190  break;
1191  }
1192  if (sscanf(p, "%hx", addr + n++) != 1)
1193  return 0;
1194 
1195  while (*p && *p != ':')
1196  p++;
1197  if (!*p)
1198  break;
1199  p++;
1200 
1201  if (*p == ':') // another ':'?
1202  {
1203  if (start != 8)
1204  return 0; // two :: were found
1205  start = n;
1206  p++;
1207  }
1208  }
1209 
1210  // if start is not 8, then a "::" was found at word 'start'
1211  // n is the number of converted words
1212  // n == 8 means everything was converted and no moving is necessary
1213  // n < 8 means that we have to move n - start words 8 - n words to the right
1214  if (start == 8 && n != 8)
1215  return 0; // bad conversion
1216  memmove(addr + start + (8 - n), addr + start, (n - start) * sizeof(quint16));
1217  memset(addr + start, 0, (8 - n) * sizeof(quint16));
1218 
1219  // check the byte order
1220  // The compiler should optimize this out in big endian machines
1221  if (htons(0x1234) != 0x1234)
1222  for (n = 0; n < 8; ++n)
1223  addr[n] = htons(addr[n]);
1224 
1225  memcpy(buf, addr, sizeof(addr));
1226  return 1;
1227  }
1228 # endif
1229 
1230  errno = EAFNOSUPPORT;
1231  return -1; // unknown family
1232 }
1233 
1234 #else // HAVE_INET_PTON
1235 
1236 #define KRF_inet_pton 0
1237 
1238 #endif // HAVE_INET_PTON
1239 
1240 #ifdef AF_INET6
1241 # define KRF_afinet6 KRF_KNOWS_AF_INET6
1242 #else
1243 # define KRF_afinet6 0
1244 #endif
1245 
1246 namespace KDE
1247 {
1249  extern const int resolverFlags = KRF_getaddrinfo | KRF_resolver | KRF_afinet6 | KRF_inet_ntop | KRF_inet_pton;
1250 }
KDE::resolverFlags
const int resolverFlags
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
gai_strerror
char * gai_strerror(int errorcode)
Definition: netsupp.cpp:890
kdebug.h
EAI_MEMORY
#define EAI_MEMORY
Definition: netsupp.h:227
EAI_SOCKTYPE
#define EAI_SOCKTYPE
Definition: netsupp.h:239
EAI_NODATA
#define EAI_NODATA
Definition: netsupp.h:230
sockaddr_in6
#define sockaddr_in6
Definition: netsupp.cpp:62
add_dwords
static void add_dwords(char *buf, quint16 *dw, int count)
Definition: netsupp.cpp:1032
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Definition: kdebug.h:187
KDE_IN6_IS_ADDR_V4MAPPED
#define KDE_IN6_IS_ADDR_V4MAPPED(a)
Definition: netsupp.h:94
dofreeaddrinfo
static void dofreeaddrinfo(struct addrinfo *ai)
Definition: netsupp.cpp:85
quint32
KAI_LOCALUNIX
#define KAI_LOCALUNIX
Definition: netsupp.h:142
I18N_NOOP
#define I18N_NOOP(x)
I18N_NOOP marks a string to be translated without translating it.
Definition: klocalizedstring.h:51
EAI_FAMILY
#define EAI_FAMILY
Definition: netsupp.h:224
NI_NAMEREQD
#define NI_NAMEREQD
Definition: netsupp.h:264
klocale.h
in6_addr
#define in6_addr
Definition: netsupp.cpp:63
KRF_inet_pton
#define KRF_inet_pton
Definition: netsupp.cpp:1141
netsupp.h
AI_CANONNAME
#define AI_CANONNAME
Definition: netsupp.h:193
kde_freeaddrinfo
void kde_freeaddrinfo(struct kde_addrinfo *ai)
Definition: netsupp.cpp:101
AI_NUMERICHOST
#define AI_NUMERICHOST
Definition: netsupp.h:194
addrinfo::ai_canonname
char * ai_canonname
Definition: netsupp.h:180
inet_lookup
static int inet_lookup(const char *name, int portnum, int protonum, struct addrinfo *p, const struct addrinfo *hint, struct addrinfo **result)
TODO Try and use gethostbyname2_r before gethostbyname2 and gethostbyname.
Definition: netsupp.cpp:379
addrinfo::ai_addrlen
int ai_addrlen
Definition: netsupp.h:178
KAI_SYSTEM
#define KAI_SYSTEM
Definition: netsupp.h:141
NI_DGRAM
#define NI_DGRAM
Definition: netsupp.h:265
NI_NUMERICSERV
#define NI_NUMERICSERV
Definition: netsupp.h:262
getaddrinfo
int getaddrinfo(const char *name, const char *serv, const struct addrinfo *hint, struct addrinfo **result)
Definition: netsupp.cpp:784
kde_addrinfo::data
struct addrinfo * data
Definition: netsupp.h:157
inet_ntop
const char * inet_ntop(int af, const void *cp, char *buf, size_t len)
Definition: netsupp.cpp:1040
offsetof
#define offsetof(TYPE, MEMBER)
Definition: netsupp.cpp:69
EAI_FAIL
#define EAI_FAIL
Definition: netsupp.h:221
getnameinfo
int getnameinfo(const struct sockaddr *sa, kde_socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
Definition: netsupp.cpp:944
AI_PASSIVE
#define AI_PASSIVE
Definition: netsupp.h:192
findport
static void findport(unsigned short port, char *serv, size_t servlen, int flags)
Definition: netsupp.cpp:925
EAI_SERVICE
#define EAI_SERVICE
Definition: netsupp.h:236
EAI_SYSTEM
#define EAI_SYSTEM
Definition: netsupp.h:242
kde_getaddrinfo
int kde_getaddrinfo(const char *name, const char *service, const struct addrinfo *hint, struct kde_addrinfo **result)
Definition: netsupp.cpp:230
NI_NUMERICHOST
#define NI_NUMERICHOST
Definition: netsupp.h:261
EAI_AGAIN
#define EAI_AGAIN
Definition: netsupp.h:215
kde_addrinfo::origin
int origin
Definition: netsupp.h:158
addrinfo::ai_protocol
int ai_protocol
Definition: netsupp.h:177
EAI_BADFLAGS
#define EAI_BADFLAGS
Definition: netsupp.h:218
KRF_inet_ntop
#define KRF_inet_ntop
Definition: netsupp.cpp:1030
addrinfo::ai_socktype
int ai_socktype
Definition: netsupp.h:176
inet_pton
int inet_pton(int af, const char *cp, void *buf)
Definition: netsupp.cpp:1142
KRF_resolver
#define KRF_resolver
Definition: netsupp.cpp:369
KRF_getaddrinfo
#define KRF_getaddrinfo
Definition: netsupp.cpp:368
addrinfo::ai_next
struct addrinfo * ai_next
Definition: netsupp.h:181
EAI_NONAME
#define EAI_NONAME
Definition: netsupp.h:233
make_unix
static struct addrinfo * make_unix(const char *name, const char *serv)
Definition: netsupp.cpp:130
addrinfo
Definition: netsupp.h:172
addrinfo::ai_flags
int ai_flags
Definition: netsupp.h:174
KRF_afinet6
#define KRF_afinet6
Definition: netsupp.cpp:1243
kde_addrinfo
Definition: netsupp.h:155
addrinfo::ai_addr
struct sockaddr * ai_addr
Definition: netsupp.h:179
make_inet
static int make_inet(const char *name, int portnum, int protonum, struct addrinfo *p, const struct addrinfo *hint, struct addrinfo **result)
Definition: netsupp.cpp:556
KDE_IN6_IS_ADDR_V4COMPAT
#define KDE_IN6_IS_ADDR_V4COMPAT(a)
Definition: netsupp.h:98
freeaddrinfo
void freeaddrinfo(struct addrinfo *p)
Definition: netsupp.cpp:884
addrinfo::ai_family
int ai_family
Definition: netsupp.h:175
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:12 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