22#include <sys/socket.h>
24#include <netinet/in.h>
42#ifndef IN6_IS_ADDR_V4MAPPED
48#if defined(__hpux) || defined(_HPUX_SOURCE)
54#if !defined(kde_sockaddr_in6)
62# define sockaddr_in6 kde_sockaddr_in6
63# define in6_addr kde_in6_addr
69#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
76#define KRF_KNOWS_AF_INET6 0x01
77#define KRF_USING_OWN_GETADDRINFO 0x02
78#define KRF_USING_OWN_INET_NTOP 0x04
79#define KRF_USING_OWN_INET_PTON 0x08
80#define KRF_CAN_RESOLVE_UNIX 0x100
81#define KRF_CAN_RESOLVE_IPV4 0x200
82#define KRF_CAN_RESOLVE_IPV6 0x400
85static void dofreeaddrinfo(
struct addrinfo *ai)
89 struct addrinfo *ai2 = ai;
90 if (ai->ai_canonname != NULL)
91 free(ai->ai_canonname);
93 if (ai->ai_addr != NULL)
101void kde_freeaddrinfo(
struct kde_addrinfo *ai)
103 if (ai->origin == KAI_LOCALUNIX)
105 struct addrinfo *p, *last = NULL;
108 for (p = ai->data; p; p = p->ai_next)
110 if (p->ai_family == AF_UNIX)
114 last->ai_next = NULL;
115 freeaddrinfo(ai->data);
124 freeaddrinfo(ai->data);
129static struct addrinfo*
130make_unix(
const char *name,
const char *serv)
134 struct sockaddr_un *_sun;
137 p = (addrinfo*)malloc(
sizeof(*p));
140 memset(p, 0,
sizeof(*p));
148 len = strlen(buf) + offsetof(
struct sockaddr_un, sun_path) + 1;
152 _sun = (sockaddr_un*)malloc(len);
160 _sun->sun_family = AF_UNIX;
161# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
165 *_sun->sun_path =
'\0';
167 strcpy(_sun->sun_path,
"/tmp/");
168 strcat(_sun->sun_path, buf);
171 p->ai_family = AF_UNIX;
173 p->ai_addr = (sockaddr*)_sun;
174 p->ai_canonname = strdup(buf);
185#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
186static int check_ipv6_stack()
191 if (getenv(
"TDE_NO_IPV6"))
193 int fd = ::socket(AF_INET6, SOCK_STREAM, 0);
230int kde_getaddrinfo(
const char *name,
const char *service,
231 const struct addrinfo* hint,
232 struct kde_addrinfo** result)
234 struct kde_addrinfo* res;
236 int err = EAI_SERVICE;
237#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE == 1
239 static int ipv6_stack = 0;
243 res = (kde_addrinfo*)malloc(
sizeof(*res));
247 res->origin = KAI_SYSTEM;
249 struct addrinfo* last = NULL;
252 if (hint && (hint->ai_family == PF_UNIX))
254 if (service == NULL || *service ==
'\0')
260 if (name != NULL && !(name[0] ==
'\0' || (name[0] ==
'*' && name[1] ==
'\0') ||
261 strcmp(
"localhost", name) == 0))
267#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 0
268# if KDE_IPV6_LOOKUP_MODE == 1
271 ipv6_stack = check_ipv6_stack();
278 struct addrinfo our_hint;
281 memcpy(&our_hint, hint,
sizeof(our_hint));
282 if (our_hint.ai_family == AF_UNSPEC)
283 our_hint.ai_family = AF_INET;
287 memset(&our_hint, 0,
sizeof(our_hint));
288 our_hint.ai_family = AF_INET;
292 err = getaddrinfo(name, service, &our_hint, &res->data);
293# if KDE_IPV6_LOOKUP_MODE == 1
298#if defined(KDE_IPV6_LOOKUP_MODE) && KDE_IPV6_LOOKUP_MODE != 2
300 err = getaddrinfo(name, service, hint, &res->data);
305 if (service == NULL || *service ==
'\0')
311 if (name != NULL && !(name[0] ==
'\0' || (name[0] ==
'*' && name[1] ==
'\0') ||
312 strcmp(
"localhost", name) == 0))
317 if (hint != NULL && (hint->ai_family != PF_UNSPEC && hint->ai_family != PF_UNIX))
325 for (p = res->data; p; p = p->ai_next)
328 if (p->ai_family == AF_UNIX)
335 p = make_unix(NULL, service);
342 p->ai_socktype = hint->ai_socktype;
343 if (p->ai_socktype == 0)
344 p->ai_socktype = SOCK_STREAM;
350 res->origin = KAI_LOCALUNIX;
355 if (res->data != NULL)
356 freeaddrinfo(res->data);
361#if defined(HAVE_GETADDRINFO) && !defined(HAVE_BROKEN_GETADDRINFO)
363#define KRF_getaddrinfo 0
364#define KRF_resolver 0
368#define KRF_getaddrinfo KRF_USING_OWN_GETADDRINFO
369#define KRF_resolver KRF_CAN_RESOLVE_UNIX | KRF_CAN_RESOLVE_IPV4
379static int inet_lookup(
const char *name,
int portnum,
int protonum,
380 struct addrinfo *p,
const struct addrinfo *hint,
381 struct addrinfo** result)
385 struct sockaddr **psa = NULL;
391 if (hint->ai_family == AF_INET6)
402 q = (addrinfo*)malloc(
sizeof(*q));
409 h = gethostbyname(name);
436 if (h->h_addrtype == AF_INET && (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC))
437 len =
sizeof(
struct sockaddr_in);
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);
456 q->ai_family = h->h_addrtype;
457 q->ai_socktype = hint->ai_socktype;
458 q->ai_protocol = protonum;
461 q->ai_addr = (sockaddr*)malloc(len);
462 if (q->ai_addr == NULL)
468 if (h->h_addrtype == AF_INET)
470 struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;
471 sin->sin_family = AF_INET;
472# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
473 sin->sin_len =
sizeof(*sin);
475 sin->sin_port = portnum;
476 memcpy(&sin->sin_addr, h->h_addr, h->h_length);
479 else if (h->h_addrtype == AF_INET6)
481 struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;
482 sin6->sin6_family = AF_INET6;
483# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
484 sin6->sin6_len =
sizeof(*sin6);
486 sin6->sin6_port = portnum;
487 sin6->sin6_flowinfo = 0;
488 memcpy(&sin6->sin6_addr, h->h_addr, h->h_length);
489 sin6->sin6_scope_id = 0;
493 if (hint->ai_flags & AI_CANONNAME)
494 q->ai_canonname = strdup(h->h_name);
496 q->ai_canonname = NULL;
502 for (psa = (sockaddr**)h->h_addr_list + 1; *psa; psa++)
504 q = (addrinfo*)malloc(
sizeof(*q));
510 memcpy(q, p,
sizeof(*q));
512 q->ai_addr = (sockaddr*)malloc(h->h_length);
513 if (q->ai_addr == NULL)
519 if (h->h_addrtype == AF_INET)
521 struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;
522 sin->sin_family = AF_INET;
523# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
524 sin->sin_len =
sizeof(*sin);
526 sin->sin_port = portnum;
527 memcpy(&sin->sin_addr, *psa, h->h_length);
530 else if (h->h_addrtype == AF_INET6)
532 struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;
533 sin6->sin6_family = AF_INET6;
534# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
535 sin6->sin6_len =
sizeof(*sin6);
537 sin6->sin6_port = portnum;
538 sin6->sin6_flowinfo = 0;
539 memcpy(&sin6->sin6_addr, *psa, h->h_length);
540 sin6->sin6_scope_id = 0;
544 if (q->ai_canonname != NULL)
545 q->ai_canonname = strdup(q->ai_canonname);
555static int make_inet(
const char *name,
int portnum,
int protonum,
struct addrinfo *p,
556 const struct addrinfo *hint,
struct addrinfo** result)
568 struct sockaddr_in *sin;
571 struct sockaddr_in6 *sin6;
574 if (hint->ai_family == AF_INET6 || (hint->ai_family == AF_UNSPEC &&
575 strchr(name,
':') != NULL))
578 if (inet_pton(AF_INET6, name, &in6) != 1)
580 if (hint->ai_flags & AI_NUMERICHOST)
588 sin6 = (sockaddr_in6*)malloc(
sizeof(*sin6));
594 memcpy(&sin6->sin6_addr, &in6,
sizeof(in6));
596 if (strchr(name,
'%') != NULL)
599 sin6->sin6_scope_id = strtoul(strchr(name,
'%') + 1, NULL, 10);
601 sin6->sin6_scope_id = 0;
604 q = (addrinfo*)malloc(
sizeof(*q));
612 sin6->sin6_family = AF_INET6;
613# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
614 sin6->sin6_len =
sizeof(*sin6);
616 sin6->sin6_port = portnum;
617 sin6->sin6_flowinfo = 0;
620 q->ai_family = AF_INET6;
621 q->ai_socktype = hint->ai_socktype;
622 q->ai_protocol = protonum;
623 q->ai_addrlen =
sizeof(*sin6);
624 q->ai_canonname = NULL;
625 q->ai_addr = (sockaddr*)sin6;
633 if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)
636 if (inet_pton(AF_INET, name, &in) != 1)
638 if (hint->ai_flags & AI_NUMERICHOST)
646 sin = (sockaddr_in*)malloc(
sizeof(*sin));
653 q = (addrinfo*)malloc(
sizeof(*q));
661 sin->sin_family = AF_INET;
662# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
663 sin->sin_len =
sizeof(*sin);
665 sin->sin_port = portnum;
669 q->ai_family = AF_INET;
670 q->ai_socktype = hint->ai_socktype;
671 q->ai_protocol = protonum;
672 q->ai_addrlen =
sizeof(*sin);
673 q->ai_canonname = NULL;
674 q->ai_addr = (sockaddr*)sin;
682 kdError() <<
"I wasn't supposed to get here!";
689 struct sockaddr_in *sin = (sockaddr_in*)malloc(
sizeof(*sin));
691 struct sockaddr_in6 *sin6;
694 if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)
704 q = (addrinfo*)malloc(
sizeof(*q));
712 sin->sin_family = AF_INET;
713# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
714 sin->sin_len =
sizeof(*sin);
716 sin->sin_port = portnum;
717 if (hint->ai_flags & AI_PASSIVE)
718 *(TQ_UINT32*)&sin->sin_addr = INADDR_ANY;
720 *(TQ_UINT32*)&sin->sin_addr = htonl(INADDR_LOOPBACK);
722 q->ai_family = AF_INET;
723 q->ai_socktype = hint->ai_socktype;
724 q->ai_protocol = protonum;
725 q->ai_addrlen =
sizeof(*sin);
726 q->ai_canonname = NULL;
727 q->ai_addr = (sockaddr*)sin;
735 if (hint->ai_family == AF_INET6 || hint->ai_family == AF_UNSPEC)
737 sin6 = (sockaddr_in6*)malloc(
sizeof(*sin6));
738 q = (addrinfo*)malloc(
sizeof(*q));
739 if (q == NULL || sin6 == NULL)
747 sin6->sin6_family = AF_INET6;
748# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
749 sin6->sin6_len =
sizeof(*sin6);
751 sin6->sin6_port = portnum;
752 sin6->sin6_flowinfo = 0;
753 sin6->sin6_scope_id = 0;
756 memset(&sin6->sin6_addr, 0,
sizeof(sin6->sin6_addr));
757 if ((hint->ai_flags & AI_PASSIVE) == 0)
758 ((
char*)&sin6->sin6_addr)[15] = 1;
761 q->ai_family = AF_INET6;
762 q->ai_socktype = hint->ai_socktype;
763 q->ai_protocol = protonum;
764 q->ai_addrlen =
sizeof(*sin6);
765 q->ai_canonname = NULL;
766 q->ai_addr = (sockaddr*)sin6;
777 return inet_lookup(name, portnum, protonum, p, hint, result);
781int getaddrinfo(
const char *name,
const char *serv,
782 const struct addrinfo* hint,
783 struct addrinfo** result)
785 unsigned short portnum;
786 int protonum = IPPROTO_TCP;
787 const char *proto =
"tcp";
788 struct addrinfo *p = NULL;
791 if (hint == NULL || result == NULL)
793 if (hint->ai_family != AF_UNSPEC && hint->ai_family != AF_UNIX &&
794 hint->ai_family != AF_INET
796 && hint->ai_family != AF_INET6
800 if (hint->ai_socktype != 0 && hint->ai_socktype != SOCK_STREAM &&
801 hint->ai_socktype != SOCK_DGRAM)
805 if (name != NULL && ((*name ==
'*' && name[1] ==
'\0') || *name ==
'\0'))
808 if (serv != NULL && ((*serv ==
'*' && serv[1] ==
'\0') || *serv ==
'\0'))
811 if (name == NULL && serv == NULL)
815 if (name != NULL && strcmp(name,
"localhost") == 0)
821 if (hint->ai_family == AF_UNIX || hint->ai_family == AF_UNSPEC)
823 if (name != NULL && serv != NULL)
826 if (hint->ai_family == AF_UNIX)
831 p = make_unix(name, serv);
835 p->ai_socktype = hint->ai_socktype;
838 if (hint->ai_family == AF_UNIX || ((name != NULL && *name ==
'/') ||
839 (serv != NULL && *serv ==
'/')))
851 struct servent *sent;
853 portnum = htons((
unsigned)strtoul(serv, &tail, 10));
857 if (hint->ai_socktype == SOCK_DGRAM)
860 protonum = IPPROTO_UDP;
863 sent = getservbyname(serv, proto);
872 portnum = sent->s_port;
878 return make_inet(name, portnum, protonum, p, hint, result);
881void freeaddrinfo(
struct addrinfo *p)
886char *gai_strerror(
int errorcode)
888 static const char *
const messages[] =
891 I18N_NOOP(
"address family for nodename not supported"),
892 I18N_NOOP(
"temporary failure in name resolution"),
893 I18N_NOOP(
"invalid value for 'ai_flags'"),
894 I18N_NOOP(
"non-recoverable failure in name resolution"),
897 I18N_NOOP(
"no address associated with nodename"),
899 I18N_NOOP(
"servname not supported for ai_socktype"),
900 I18N_NOOP(
"'ai_socktype' not supported"),
904 if (errorcode > EAI_SYSTEM || errorcode < 0)
907 static char buffer[200];
908 strcpy(buffer,
i18n(messages[errorcode]).local8Bit());
912static void findport(
unsigned short port,
char *serv,
size_t servlen,
int flags)
917 if ((flags & NI_NUMERICSERV) == 0)
919 struct servent *sent;
920 sent = getservbyport(ntohs(port), flags & NI_DGRAM ?
"udp" :
"tcp");
921 if (sent != NULL && servlen > strlen(sent->s_name))
923 strcpy(serv, sent->s_name);
928 snprintf(serv, servlen,
"%u", ntohs(port));
931int getnameinfo(
const struct sockaddr *sa, ksocklen_t salen,
932 char *host,
size_t hostlen,
char *serv,
size_t servlen,
938 const sockaddr_un *_sun;
939 const sockaddr_in *sin;
940 const sockaddr_in6 *sin6;
943 if ((host == NULL || hostlen == 0) && (serv == NULL || servlen == 0))
947 if (s.sa->sa_family == AF_UNIX)
949 if (salen < offsetof(
struct sockaddr_un, sun_path) + strlen(s._sun->sun_path) + 1)
952 if (servlen && serv != NULL)
954 if (host != NULL && hostlen > strlen(s._sun->sun_path))
955 strcpy(host, s._sun->sun_path);
959 else if (s.sa->sa_family == AF_INET)
961 if (salen < offsetof(
struct sockaddr_in, sin_addr) +
sizeof(s.sin->sin_addr))
964 if (flags & NI_NUMERICHOST)
965 inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
969 struct hostent *h = gethostbyaddr((
const char*)&s.sin->sin_addr,
sizeof(s.sin->sin_addr),
971 if (h == NULL && flags & NI_NAMEREQD)
974 inet_ntop(AF_INET, &s.sin->sin_addr, host, hostlen);
975 else if (host != NULL && hostlen > strlen(h->h_name))
976 strcpy(host, h->h_name);
981 findport(s.sin->sin_port, serv, servlen, flags);
984 else if (s.sa->sa_family == AF_INET6)
986 if (salen < offsetof(
struct sockaddr_in6, sin6_addr) +
sizeof(s.sin6->sin6_addr))
989 if (flags & NI_NUMERICHOST)
990 inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
994 struct hostent *h = gethostbyaddr((
const char*)&s.sin->sin_addr,
sizeof(s.sin->sin_addr),
996 if (h == NULL && flags & NI_NAMEREQD)
999 inet_ntop(AF_INET6, &s.sin6->sin6_addr, host, hostlen);
1000 else if (host != NULL && hostlen > strlen(h->h_name))
1001 strcpy(host, h->h_name);
1006 findport(s.sin6->sin6_port, serv, servlen, flags);
1015#ifndef HAVE_INET_NTOP
1017#define KRF_inet_ntop KRF_USING_OWN_INET_NTOP
1019static void add_dwords(
char *buf, TQ_UINT16 *dw,
int count)
1022 sprintf(buf + strlen(buf),
"%x", ntohs(dw[0]));
1024 sprintf(buf + strlen(buf),
":%x", ntohs(dw[i++]));
1027const char* inet_ntop(
int af,
const void *cp,
char *buf,
size_t len)
1029 char buf2[
sizeof "1234:5678:9abc:def0:1234:5678:255.255.255.255" + 1];
1030 TQ_UINT8 *data = (TQ_UINT8*)cp;
1034 sprintf(buf2,
"%u.%u.%u.%u", data[0], data[1], data[2], data[3]);
1036 if (len > strlen(buf2))
1049 TQ_UINT16 *p = (TQ_UINT16*)data;
1050 TQ_UINT16 *longest = NULL, *cur = NULL;
1051 int longest_length = 0, cur_length;
1054 if (KDE_IN6_IS_ADDR_V4MAPPED(p) || KDE_IN6_IS_ADDR_V4COMPAT(p))
1055 sprintf(buf2,
"::%s%u.%u.%u.%u",
1056 KDE_IN6_IS_ADDR_V4MAPPED(p) ?
"ffff:" :
"",
1057 buf[12], buf[13], buf[14], buf[15]);
1061 for (i = 0; i < 8; i++)
1062 if (cur == NULL && p[i] == 0)
1068 else if (cur != NULL && p[i] == 0)
1071 else if (cur != NULL && p[i] != 0)
1074 if (cur_length > longest_length)
1076 longest_length = cur_length;
1081 if (cur != NULL && cur_length > longest_length)
1083 longest_length = cur_length;
1087 if (longest_length > 1)
1092 add_dwords(buf2, p, longest - p);
1094 if (longest + longest_length < p + 8)
1095 add_dwords(buf2, longest + longest_length, 8 - (longest - p) - longest_length);
1101 add_dwords(buf2, p, 8);
1105 if (strlen(buf2) < len)
1116 errno = EAFNOSUPPORT;
1122#define KRF_inet_ntop 0
1126#ifndef HAVE_INET_PTON
1128#define KRF_inet_pton KRF_USING_OWN_INET_PTON
1129int inet_pton(
int af,
const char *cp,
void *buf)
1135 unsigned char *q = (
unsigned char*)buf;
1136 if (sscanf(cp,
"%u.%u.%u.%u", p, p + 1, p + 2, p + 3) != 4)
1139 if (p[0] > 0xff || p[1] > 0xff || p[2] > 0xff || p[3] > 0xff)
1151 else if (af == AF_INET6)
1155 int n = 0, start = 8;
1156 bool has_v4 = strchr(p,
'.') != NULL;
1158 memset(addr, 0,
sizeof(addr));
1160 if (*p ==
'\0' || p[1] ==
'\0')
1163 if (*p ==
':' && p[1] ==
':')
1170 if (has_v4 && inet_pton(AF_INET, p, addr + n) != 0)
1173 addr[n] = ntohs(addr[n]);
1175 addr[n] = ntohs(addr[n]);
1179 if (sscanf(p,
"%hx", addr + n++) != 1)
1182 while (*p && *p !=
':')
1201 if (start == 8 && n != 8)
1203 memmove(addr + start + (8 - n), addr + start, (n - start) *
sizeof(TQ_UINT16));
1204 memset(addr + start, 0, (8 - n) *
sizeof(TQ_UINT16));
1208 if (htons(0x1234) != 0x1234)
1209 for (n = 0; n < 8; n++)
1210 addr[n] = htons(addr[n]);
1212 memcpy(buf, addr,
sizeof(addr));
1217 errno = EAFNOSUPPORT;
1223#define KRF_inet_pton 0
1228# define KRF_afinet6 KRF_KNOWS_AF_INET6
1230# define KRF_afinet6 0
1236 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)