22#include <sys/socket.h>
24#include <netinet/in.h>
42#ifndef IN6_IS_ADDR_V4MAPPED
50#if !defined(kde_sockaddr_in6)
58# define sockaddr_in6 kde_sockaddr_in6
59# define in6_addr kde_in6_addr
65#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
72#define KRF_KNOWS_AF_INET6 0x01
73#define KRF_USING_OWN_GETADDRINFO 0x02
74#define KRF_USING_OWN_INET_NTOP 0x04
75#define KRF_USING_OWN_INET_PTON 0x08
76#define KRF_CAN_RESOLVE_UNIX 0x100
77#define KRF_CAN_RESOLVE_IPV4 0x200
78#define KRF_CAN_RESOLVE_IPV6 0x400
81static void dofreeaddrinfo(
struct addrinfo *ai)
85 struct addrinfo *ai2 = ai;
86 if (ai->ai_canonname != NULL)
87 free(ai->ai_canonname);
89 if (ai->ai_addr != NULL)
97void kde_freeaddrinfo(
struct kde_addrinfo *ai)
99 if (ai->origin == KAI_LOCALUNIX)
101 struct addrinfo *p, *last = NULL;
104 for (p = ai->data; p; p = p->ai_next)
106 if (p->ai_family == AF_UNIX)
110 last->ai_next = NULL;
111 freeaddrinfo(ai->data);
120 freeaddrinfo(ai->data);
125static struct addrinfo*
126make_unix(
const char *name,
const char *serv)
130 struct sockaddr_un *_sun;
133 p = (addrinfo*)malloc(
sizeof(*p));
136 memset(p, 0,
sizeof(*p));
144 len = strlen(buf) + offsetof(
struct sockaddr_un, sun_path) + 1;
148 _sun = (sockaddr_un*)malloc(len);
156 _sun->sun_family = AF_UNIX;
157# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
161 *_sun->sun_path =
'\0';
163 strcpy(_sun->sun_path,
"/tmp/");
164 strcat(_sun->sun_path, buf);
167 p->ai_family = AF_UNIX;
169 p->ai_addr = (sockaddr*)_sun;
170 p->ai_canonname = strdup(buf);
181#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
182static int check_ipv6_stack()
187 if (getenv(
"TDE_NO_IPV6"))
189 int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
226int kde_getaddrinfo(
const char *name,
const char *service,
227 const struct addrinfo* hint,
228 struct kde_addrinfo** result)
230 struct kde_addrinfo* res;
232 int err = EAI_SERVICE;
233#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
235 static int ipv6_stack = 0;
239 res = (kde_addrinfo*)malloc(
sizeof(*res));
243 res->origin = KAI_SYSTEM;
245 struct addrinfo* last = NULL;
248 if (hint && (hint->ai_family == PF_UNIX))
250 if (service == NULL || *service ==
'\0')
256 if (name != NULL && !(name[0] ==
'\0' || (name[0] ==
'*' && name[1] ==
'\0') ||
257 strcmp(
"localhost", name) == 0))
263#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 0
264# if KDE_IPV6_LOOKUP_MODE == 1
267 ipv6_stack = check_ipv6_stack();
274 struct addrinfo our_hint;
277 memcpy(&our_hint, hint,
sizeof(our_hint));
278 if (our_hint.ai_family == AF_UNSPEC)
279 our_hint.ai_family = AF_INET;
283 memset(&our_hint, 0,
sizeof(our_hint));
284 our_hint.ai_family = AF_INET;
288 err = getaddrinfo(name, service, &our_hint, &res->data);
289# if KDE_IPV6_LOOKUP_MODE == 1
294#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 2
296 err = getaddrinfo(name, service, hint, &res->data);
301 if (service == NULL || *service ==
'\0')
307 if (name != NULL && !(name[0] ==
'\0' || (name[0] ==
'*' && name[1] ==
'\0') ||
308 strcmp(
"localhost", name) == 0))
313 if (hint != NULL && (hint->ai_family != PF_UNSPEC && hint->ai_family != PF_UNIX))
321 for (p = res->data; p; p = p->ai_next)
324 if (p->ai_family == AF_UNIX)
331 p = make_unix(NULL, service);
338 p->ai_socktype = hint->ai_socktype;
339 if (p->ai_socktype == 0)
340 p->ai_socktype = SOCK_STREAM;
346 res->origin = KAI_LOCALUNIX;
351 if (res->data != NULL)
352 freeaddrinfo(res->data);
357#if defined(HAVE_GETADDRINFO) && !defined(HAVE_BROKEN_GETADDRINFO)
359#define KRF_getaddrinfo 0
360#define KRF_resolver 0
364#define KRF_getaddrinfo KRF_USING_OWN_GETADDRINFO
365#define KRF_resolver KRF_CAN_RESOLVE_UNIX | KRF_CAN_RESOLVE_IPV4
375static int inet_lookup(
const char *name,
int portnum,
int protonum,
376 struct addrinfo *p,
const struct addrinfo *hint,
377 struct addrinfo** result)
381 struct sockaddr **psa = NULL;
387 if (hint->ai_family == AF_INET6)
398 q = (addrinfo*)malloc(
sizeof(*q));
405 h = gethostbyname(name);
432 if (h->h_addrtype == AF_INET && (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC))
433 len =
sizeof(
struct sockaddr_in);
435 else if (h->h_addrtype == AF_INET6 && (hint->ai_family == AF_INET6 ||
436 hint->ai_family == AF_UNSPEC))
437 len =
sizeof(
struct sockaddr_in6);
452 q->ai_family = h->h_addrtype;
453 q->ai_socktype = hint->ai_socktype;
454 q->ai_protocol = protonum;
457 q->ai_addr = (sockaddr*)malloc(len);
458 if (q->ai_addr == NULL)
464 if (h->h_addrtype == AF_INET)
466 struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;
467 sin->sin_family = AF_INET;
468# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
469 sin->sin_len =
sizeof(*sin);
471 sin->sin_port = portnum;
472 memcpy(&sin->sin_addr, h->h_addr, h->h_length);
475 else if (h->h_addrtype == AF_INET6)
477 struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;
478 sin6->sin6_family = AF_INET6;
479# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
480 sin6->sin6_len =
sizeof(*sin6);
482 sin6->sin6_port = portnum;
483 sin6->sin6_flowinfo = 0;
484 memcpy(&sin6->sin6_addr, h->h_addr, h->h_length);
485 sin6->sin6_scope_id = 0;
489 if (hint->ai_flags & AI_CANONNAME)
490 q->ai_canonname = strdup(h->h_name);
492 q->ai_canonname = NULL;
498 for (psa = (sockaddr**)h->h_addr_list + 1; *psa; psa++)
500 q = (addrinfo*)malloc(
sizeof(*q));
506 memcpy(q, p,
sizeof(*q));
508 q->ai_addr = (sockaddr*)malloc(h->h_length);
509 if (q->ai_addr == NULL)
515 if (h->h_addrtype == AF_INET)
517 struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;
518 sin->sin_family = AF_INET;
519# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
520 sin->sin_len =
sizeof(*sin);
522 sin->sin_port = portnum;
523 memcpy(&sin->sin_addr, *psa, h->h_length);
526 else if (h->h_addrtype == AF_INET6)
528 struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;
529 sin6->sin6_family = AF_INET6;
530# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
531 sin6->sin6_len =
sizeof(*sin6);
533 sin6->sin6_port = portnum;
534 sin6->sin6_flowinfo = 0;
535 memcpy(&sin6->sin6_addr, *psa, h->h_length);
536 sin6->sin6_scope_id = 0;
540 if (q->ai_canonname != NULL)
541 q->ai_canonname = strdup(q->ai_canonname);
551static int make_inet(
const char *name,
int portnum,
int protonum,
struct addrinfo *p,
552 const struct addrinfo *hint,
struct addrinfo** result)
564 struct sockaddr_in *sin;
567 struct sockaddr_in6 *sin6;
570 if (hint->ai_family == AF_INET6 || (hint->ai_family == AF_UNSPEC &&
571 strchr(name,
':') != NULL))
574 if (inet_pton(AF_INET6, name, &in6) != 1)
576 if (hint->ai_flags & AI_NUMERICHOST)
584 sin6 = (sockaddr_in6*)malloc(
sizeof(*sin6));
590 memcpy(&sin6->sin6_addr, &in6,
sizeof(in6));
592 if (strchr(name,
'%') != NULL)
595 sin6->sin6_scope_id = strtoul(strchr(name,
'%') + 1, NULL, 10);
597 sin6->sin6_scope_id = 0;
600 q = (addrinfo*)malloc(
sizeof(*q));
608 sin6->sin6_family = AF_INET6;
609# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
610 sin6->sin6_len =
sizeof(*sin6);
612 sin6->sin6_port = portnum;
613 sin6->sin6_flowinfo = 0;
616 q->ai_family = AF_INET6;
617 q->ai_socktype = hint->ai_socktype;
618 q->ai_protocol = protonum;
619 q->ai_addrlen =
sizeof(*sin6);
620 q->ai_canonname = NULL;
621 q->ai_addr = (sockaddr*)sin6;
629 if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)
632 if (inet_pton(AF_INET, name, &in) != 1)
634 if (hint->ai_flags & AI_NUMERICHOST)
642 sin = (sockaddr_in*)malloc(
sizeof(*sin));
649 q = (addrinfo*)malloc(
sizeof(*q));
657 sin->sin_family = AF_INET;
658# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
659 sin->sin_len =
sizeof(*sin);
661 sin->sin_port = portnum;
665 q->ai_family = AF_INET;
666 q->ai_socktype = hint->ai_socktype;
667 q->ai_protocol = protonum;
668 q->ai_addrlen =
sizeof(*sin);
669 q->ai_canonname = NULL;
670 q->ai_addr = (sockaddr*)sin;
678 kdError() <<
"I wasn't supposed to get here!";
685 struct sockaddr_in *sin = (sockaddr_in*)malloc(
sizeof(*sin));
687 struct sockaddr_in6 *sin6;
690 if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)
700 q = (addrinfo*)malloc(
sizeof(*q));
708 sin->sin_family = AF_INET;
709# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
710 sin->sin_len =
sizeof(*sin);
712 sin->sin_port = portnum;
713 if (hint->ai_flags & AI_PASSIVE)
714 *(TQ_UINT32*)&sin->sin_addr = INADDR_ANY;
716 *(TQ_UINT32*)&sin->sin_addr = htonl(INADDR_LOOPBACK);
718 q->ai_family = AF_INET;
719 q->ai_socktype = hint->ai_socktype;
720 q->ai_protocol = protonum;
721 q->ai_addrlen =
sizeof(*sin);
722 q->ai_canonname = NULL;
723 q->ai_addr = (sockaddr*)sin;
731 if (hint->ai_family == AF_INET6 || hint->ai_family == AF_UNSPEC)
733 sin6 = (sockaddr_in6*)malloc(
sizeof(*sin6));
734 q = (addrinfo*)malloc(
sizeof(*q));
735 if (q == NULL || sin6 == NULL)
743 sin6->sin6_family = AF_INET6;
744# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
745 sin6->sin6_len =
sizeof(*sin6);
747 sin6->sin6_port = portnum;
748 sin6->sin6_flowinfo = 0;
749 sin6->sin6_scope_id = 0;
752 memset(&sin6->sin6_addr, 0,
sizeof(sin6->sin6_addr));
753 if ((hint->ai_flags & AI_PASSIVE) == 0)
754 ((
char*)&sin6->sin6_addr)[15] = 1;
757 q->ai_family = AF_INET6;
758 q->ai_socktype = hint->ai_socktype;
759 q->ai_protocol = protonum;
760 q->ai_addrlen =
sizeof(*sin6);
761 q->ai_canonname = NULL;
762 q->ai_addr = (sockaddr*)sin6;
773 return inet_lookup(name, portnum, protonum, p, hint, result);
777int getaddrinfo(
const char *name,
const char *serv,
778 const struct addrinfo* hint,
779 struct addrinfo** result)
781 unsigned short portnum;
782 int protonum = IPPROTO_TCP;
783 const char *proto =
"tcp";
784 struct addrinfo *p = NULL;
787 if (hint == NULL || result == NULL)
789 if (hint->ai_family != AF_UNSPEC && hint->ai_family != AF_UNIX &&
790 hint->ai_family != AF_INET
792 && hint->ai_family != AF_INET6
796 if (hint->ai_socktype != 0 && hint->ai_socktype != SOCK_STREAM &&
797 hint->ai_socktype != SOCK_DGRAM)
801 if (name != NULL && ((*name ==
'*' && name[1] ==
'\0') || *name ==
'\0'))
804 if (serv != NULL && ((*serv ==
'*' && serv[1] ==
'\0') || *serv ==
'\0'))
807 if (name == NULL && serv == NULL)
811 if (name != NULL && strcmp(name,
"localhost") == 0)
817 if (hint->ai_family == AF_UNIX || hint->ai_family == AF_UNSPEC)
819 if (name != NULL && serv != NULL)
822 if (hint->ai_family == AF_UNIX)
827 p = make_unix(name, serv);
831 p->ai_socktype = hint->ai_socktype;
834 if (hint->ai_family == AF_UNIX || ((name != NULL && *name ==
'/') ||
835 (serv != NULL && *serv ==
'/')))
847 struct servent *sent;
849 portnum = htons((
unsigned)strtoul(serv, &tail, 10));
853 if (hint->ai_socktype == SOCK_DGRAM)
856 protonum = IPPROTO_UDP;
859 sent = getservbyname(serv, proto);
868 portnum = sent->s_port;
874 return make_inet(name, portnum, protonum, p, hint, result);
877void freeaddrinfo(
struct addrinfo *p)
882char *gai_strerror(
int errorcode)
884 static const char *
const messages[] =
887 I18N_NOOP(
"address family for nodename not supported"),
888 I18N_NOOP(
"temporary failure in name resolution"),
889 I18N_NOOP(
"invalid value for 'ai_flags'"),
890 I18N_NOOP(
"non-recoverable failure in name resolution"),
893 I18N_NOOP(
"no address associated with nodename"),
895 I18N_NOOP(
"servname not supported for ai_socktype"),
896 I18N_NOOP(
"'ai_socktype' not supported"),
900 if (errorcode > EAI_SYSTEM || errorcode < 0)
903 static char buffer[200];
904 strcpy(buffer,
i18n(messages[errorcode]).local8Bit());
908static void findport(
unsigned short port,
char *serv,
size_t servlen,
int flags)
913 if ((flags & NI_NUMERICSERV) == 0)
915 struct servent *sent;
916 sent = getservbyport(ntohs(port), flags & NI_DGRAM ?
"udp" :
"tcp");
917 if (sent != NULL && servlen > strlen(sent->s_name))
919 strcpy(serv, sent->s_name);
924 snprintf(serv, servlen,
"%u", ntohs(port));
927int getnameinfo(
const struct sockaddr *sa, ksocklen_t salen,
928 char *host,
size_t hostlen,
char *serv,
size_t servlen,
934 const sockaddr_un *_sun;
935 const sockaddr_in *sin;
936 const sockaddr_in6 *sin6;
939 if ((host == NULL || hostlen == 0) && (serv == NULL || servlen == 0))
943 if (s.sa->sa_family == AF_UNIX)
945 if (salen < offsetof(
struct sockaddr_un, sun_path) + strlen(s._sun->sun_path) + 1)
948 if (servlen && serv != NULL)
950 if (host != NULL && hostlen > strlen(s._sun->sun_path))
951 strcpy(host, s._sun->sun_path);
955 else if (s.sa->sa_family == AF_INET)
957 if (salen < offsetof(
struct sockaddr_in, sin_addr) +
sizeof(s.sin->sin_addr))
960 if (flags & NI_NUMERICHOST)
961 inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
965 struct hostent *h = gethostbyaddr((
const char*)&s.sin->sin_addr,
sizeof(s.sin->sin_addr),
967 if (h == NULL && flags & NI_NAMEREQD)
970 inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
971 else if (host != NULL && hostlen > strlen(h->h_name))
972 strcpy(host, h->h_name);
977 findport(s.sin->sin_port, serv, servlen, flags);
980 else if (s.sa->sa_family == AF_INET6)
982 if (salen < offsetof(
struct sockaddr_in6, sin6_addr) +
sizeof(s.sin6->sin6_addr))
985 if (flags & NI_NUMERICHOST)
986 inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
990 struct hostent *h = gethostbyaddr((
const char*)&s.sin->sin_addr,
sizeof(s.sin->sin_addr),
992 if (h == NULL && flags & NI_NAMEREQD)
995 inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
996 else if (host != NULL && hostlen > strlen(h->h_name))
997 strcpy(host, h->h_name);
1002 findport(s.sin6->sin6_port, serv, servlen, flags);
1011#ifndef HAVE_INET_NTOP
1013#define KRF_inet_ntop KRF_USING_OWN_INET_NTOP
1015static void add_dwords(
char *buf, TQ_UINT16 *dw,
int count)
1018 sprintf(buf + strlen(buf),
"%x", ntohs(dw[0]));
1020 sprintf(buf + strlen(buf),
":%x", ntohs(dw[i++]));
1023const char* inet_ntop(
int af,
const void *cp,
char *buf,
size_t len)
1025 char buf2[
sizeof "1234:5678:9abc:def0:1234:5678:255.255.255.255" + 1];
1026 TQ_UINT8 *data = (TQ_UINT8*)cp;
1030 sprintf(buf2,
"%u.%u.%u.%u", data[0], data[1], data[2], data[3]);
1032 if (len > strlen(buf2))
1045 TQ_UINT16 *p = (TQ_UINT16*)data;
1046 TQ_UINT16 *longest = NULL, *cur = NULL;
1047 int longest_length = 0, cur_length;
1050 if (KDE_IN6_IS_ADDR_V4MAPPED(p) || KDE_IN6_IS_ADDR_V4COMPAT(p))
1051 sprintf(buf2,
"::%s%u.%u.%u.%u",
1052 KDE_IN6_IS_ADDR_V4MAPPED(p) ?
"ffff:" :
"",
1053 buf[12], buf[13], buf[14], buf[15]);
1057 for (i = 0; i < 8; i++)
1058 if (cur == NULL && p[i] == 0)
1064 else if (cur != NULL && p[i] == 0)
1067 else if (cur != NULL && p[i] != 0)
1070 if (cur_length > longest_length)
1072 longest_length = cur_length;
1077 if (cur != NULL && cur_length > longest_length)
1079 longest_length = cur_length;
1083 if (longest_length > 1)
1088 add_dwords(buf2, p, longest - p);
1090 if (longest + longest_length < p + 8)
1091 add_dwords(buf2, longest + longest_length, 8 - (longest - p) - longest_length);
1097 add_dwords(buf2, p, 8);
1101 if (strlen(buf2) < len)
1112 errno = EAFNOSUPPORT;
1118#define KRF_inet_ntop 0
1122#ifndef HAVE_INET_PTON
1124#define KRF_inet_pton KRF_USING_OWN_INET_PTON
1125int inet_pton(
int af,
const char *cp,
void *buf)
1131 unsigned char *q = (
unsigned char*)buf;
1132 if (sscanf(cp,
"%u.%u.%u.%u", p, p + 1, p + 2, p + 3) != 4)
1135 if (p[0] > 0xff || p[1] > 0xff || p[2] > 0xff || p[3] > 0xff)
1147 else if (af == AF_INET6)
1151 int n = 0, start = 8;
1152 bool has_v4 = strchr(p,
'.') != NULL;
1154 memset(addr, 0,
sizeof(addr));
1156 if (*p ==
'\0' || p[1] ==
'\0')
1159 if (*p ==
':' && p[1] ==
':')
1166 if (has_v4 && inet_pton(AF_INET, p, addr + n) != 0)
1169 addr[n] = ntohs(addr[n]);
1171 addr[n] = ntohs(addr[n]);
1175 if (sscanf(p,
"%hx", addr + n++) != 1)
1178 while (*p && *p !=
':')
1197 if (start == 8 && n != 8)
1199 memmove(addr + start + (8 - n), addr + start, (n - start) *
sizeof(TQ_UINT16));
1200 memset(addr + start, 0, (8 - n) *
sizeof(TQ_UINT16));
1204 if (htons(0x1234) != 0x1234)
1205 for (n = 0; n < 8; n++)
1206 addr[n] = htons(addr[n]);
1208 memcpy(buf, addr,
sizeof(addr));
1213 errno = EAFNOSUPPORT;
1219#define KRF_inet_pton 0
1224# define KRF_afinet6 KRF_KNOWS_AF_INET6
1226# define KRF_afinet6 0
1232 extern const int TDE_EXPORT resolverFlags = KRF_getaddrinfo | KRF_resolver | KRF_afinet6 | KRF_inet_ntop | KRF_inet_pton;
TQString i18n(const char *text)
i18n is the function that does everything you need to translate a string.
#define I18N_NOOP(x)
I18N_NOOP marks a string to be translated without translating it.
kdbgstream kdError(int area=0)
Returns an error stream.
Namespace for general KDE functions.
const char * name(StdAction id)