| sniped from Fedora and made to not suck |
| |
| http://bugs.gentoo.org/218638 |
| |
| --- iputils-s20070202/Makefile |
| +++ iputils-s20070202/Makefile |
| @@ -22,6 +22,11 @@ |
| |
| all: $(TARGETS) |
| |
| +ifeq ($(IDN),yes) |
| +CPPFLAGS += -DIDN |
| +ping: LDLIBS += -lidn |
| +ping6: LDLIBS += -lidn |
| +endif |
| |
| tftpd: tftpd.o tftpsubs.o |
| ping: ping.o ping_common.o |
| --- iputils-s20070202/ping.c |
| +++ iputils-s20070202/ping.c |
| @@ -58,6 +58,11 @@ |
| * This program has to run SUID to ROOT to access the ICMP socket. |
| */ |
| |
| +#ifdef IDN |
| +#include <idna.h> |
| +#include <locale.h> |
| +#endif |
| + |
| #include "ping_common.h" |
| |
| #include <netinet/ip.h> |
| @@ -122,6 +128,12 @@ |
| char *target, hnamebuf[MAXHOSTNAMELEN]; |
| char rspace[3 + 4 * NROUTES + 1]; /* record route space */ |
| |
| +#ifdef IDN |
| + char *idn; |
| + int rc = 0; |
| + setlocale(LC_ALL, ""); |
| +#endif |
| + |
| icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); |
| socket_errno = errno; |
| |
| @@ -242,13 +254,35 @@ |
| if (argc == 1) |
| options |= F_NUMERIC; |
| } else { |
| +#ifdef IDN |
| + rc = idna_to_ascii_lz (target, &idn, 0); |
| + if (rc == IDNA_SUCCESS) |
| + hp = gethostbyname (idn); |
| + else { |
| + fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", target, rc); |
| + exit(2); |
| + } |
| + free(idn); |
| +#else |
| hp = gethostbyname(target); |
| +#endif |
| if (!hp) { |
| fprintf(stderr, "ping: unknown host %s\n", target); |
| exit(2); |
| } |
| memcpy(&whereto.sin_addr, hp->h_addr, 4); |
| +#ifdef IDN |
| + rc = idna_to_unicode_lzlz (hp->h_name, &idn, 0); |
| + if (rc == IDNA_SUCCESS) |
| + strncpy(hnamebuf, idn, sizeof(hnamebuf) - 1); |
| + else { |
| + fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", hp->h_name, rc); |
| + exit(2); |
| + } |
| + free(idn); |
| +#else |
| strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1); |
| +#endif |
| hnamebuf[sizeof(hnamebuf) - 1] = 0; |
| hostname = hnamebuf; |
| } |
| --- iputils-s20070202/ping6.c |
| +++ iputils-s20070202/ping6.c |
| @@ -66,6 +66,13 @@ |
| * More statistics could always be gathered. |
| * This program has to run SUID to ROOT to access the ICMP socket. |
| */ |
| +#ifdef IDN |
| +#ifndef _GNU_SOURCE |
| +#define _GNU_SOURCE |
| +#endif |
| +#include <locale.h> |
| +#endif |
| + |
| #include "ping_common.h" |
| |
| #include <linux/filter.h> |
| @@ -210,6 +216,10 @@ |
| int err, csum_offset, sz_opt; |
| static uint32_t scope_id = 0; |
| |
| +#ifdef IDN |
| + setlocale(LC_ALL, ""); |
| +#endif |
| + |
| icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); |
| socket_errno = errno; |
| |
| @@ -296,6 +306,9 @@ |
| |
| memset(&hints, 0, sizeof(hints)); |
| hints.ai_family = AF_INET6; |
| +#ifdef IDN |
| + hints.ai_flags = AI_IDN; |
| +#endif |
| gai = getaddrinfo(target, NULL, &hints, &ai); |
| if (gai) { |
| fprintf(stderr, "unknown host\n"); |
| @@ -328,6 +341,9 @@ |
| |
| memset(&hints, 0, sizeof(hints)); |
| hints.ai_family = AF_INET6; |
| +#ifdef IDN |
| + hints.ai_flags = AI_IDN; |
| +#endif |
| gai = getaddrinfo(target, NULL, &hints, &ai); |
| if (gai) { |
| fprintf(stderr, "unknown host\n"); |
| --- iputils-s20070202/ping_common.c |
| +++ iputils-s20070202/ping_common.c |
| @@ -1,3 +1,7 @@ |
| +#ifdef IDN |
| +#include <locale.h> |
| +#endif |
| + |
| #include "ping_common.h" |
| #include <ctype.h> |
| #include <sched.h> |
| @@ -97,6 +102,9 @@ |
| |
| void common_options(int ch) |
| { |
| +#ifdef IDN |
| + setlocale(LC_ALL, "C"); |
| +#endif |
| switch(ch) { |
| case 'a': |
| options |= F_AUDIBLE; |
| @@ -222,6 +230,9 @@ |
| default: |
| abort(); |
| } |
| +#ifdef IDN |
| + setlocale(LC_ALL, ""); |
| +#endif |
| } |
| |
| |