Hello community, here is the log from the commit of package net-tools for openSUSE:Factory checked in at Tue Jul 20 21:00:47 CEST 2010. -------- --- net-tools/net-tools.changes 2010-01-26 22:35:40.000000000 +0100 +++ /mounts/work_src_done/STABLE/net-tools/net-tools.changes 2010-07-20 14:30:39.000000000 +0200 @@ -1,0 +2,5 @@ +Tue Jul 20 12:28:38 UTC 2010 - mt@suse.de + +- implemented ipv6 support in hostname -[aifsd] (bnc #577070) + +------------------------------------------------------------------- calling whatdependson for head-i586 New: ---- net-tools-1.60-hostname-ipv6.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ net-tools.spec ++++++ --- /var/tmp/diff_new_pack.kkdRBG/_old 2010-07-20 21:00:00.000000000 +0200 +++ /var/tmp/diff_new_pack.kkdRBG/_new 2010-07-20 21:00:00.000000000 +0200 @@ -27,7 +27,7 @@ Obsoletes: traceroute net_tool AutoReqProv: on Version: 1.60 -Release: 737 +Release: 738 Summary: Important Programs for Networking BuildRoot: %{_tmppath}/%{name}-%{version}-build Source: net-tools-%{version}.tar.bz2 @@ -78,6 +78,7 @@ Patch44: net-tools-1.60-netrom-fopen.diff Patch45: net-tools-1.60-doc.dif Patch46: net-tools-1.60-netstat_retval.diff +Patch47: net-tools-1.60-hostname-ipv6.patch %description This package contains essential programs for network administration and @@ -143,6 +144,7 @@ %patch44 %patch45 %patch46 +%patch47 %build make config ++++++ net-tools-1.60-hostname-ipv6.patch ++++++ --- hostname.c +++ hostname.c 2010/07/20 12:25:42 @@ -79,6 +79,7 @@ static void setnname(char *nname) fprintf(stderr, _("%s: name too long\n"), program_name); break; default: + break; } exit(1); } @@ -125,49 +126,171 @@ static void setdname(char *dname) }; } +struct alias_t { + char name[NI_MAXHOST]; + struct alias_t *next; +}; +struct aliases_t { + struct alias_t *head; + struct alias_t *tail; +}; + +static void aliases_add(struct aliases_t *aliases, char *alias) +{ + struct alias_t *a; + int f = 0; + + if( !aliases || !alias || !*alias) + return; + + for(a=aliases->head; !f && a; a=a->next) { + f = (strcasecmp(a->name, alias) == 0); + } + if(!f) { + a = calloc(1, sizeof(struct alias_t)); + if( a) { + strncat(a->name, alias, sizeof(a->name)-1); + if (aliases->tail) { + aliases->tail->next = a; + aliases->tail = a; + } else { + aliases->head = a; + aliases->tail = a; + } + } + } +} + static void showhname(char *hname, int c) { - struct hostent *hp; + struct addrinfo hints; + struct addrinfo *res=NULL, *rp; register char *p, **alias; - struct in_addr **ip; + int ret, retry=3; + size_t n; if (opt_v) fprintf(stderr, _("Resolving `%s' ...\n"), hname); - if (!(hp = gethostbyname(hname))) { - herror(program_name); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_CANONNAME | AI_CANONIDN; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = 0; + do { + ret = getaddrinfo(hname, NULL, &hints, &res); + } while(ret == EAI_AGAIN && retry-- > 0 + && usleep(50000) == 0); + + if (ret != 0 || res == NULL) { + fprintf(stderr, _("%s: %s\n"), + program_name, gai_strerror(ret)); exit(1); } + if (opt_v) { - fprintf(stderr, _("Result: h_name=`%s'\n"), - hp->h_name); + for(n=0, rp=res; rp; rp=rp->ai_next, n++) { + char buf[INET6_ADDRSTRLEN] = {'\0'}; + const char *str = NULL; + const char *typ = NULL; + const void *adr = NULL; + + if(rp->ai_canonname) + fprintf(stderr, _("Result: ai_canonname[%zd]=`%s'\n"), + n, rp->ai_canonname); + + switch(rp->ai_addr->sa_family) { + case AF_INET: + typ = "ipv4"; + adr = &(((struct sockaddr_in *)rp->ai_addr)->sin_addr); + break; + case AF_INET6: + typ = "ipv6"; + adr = &(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr); + break; + } + if( !adr) + continue; + + if(opt_v > 1) + fprintf(stderr, _("Result: ai_addrtype[%zd]=`%s'\n"), n, typ); - alias = hp->h_aliases; - while (alias[0]) - fprintf(stderr, _("Result: h_aliases=`%s'\n"), - *alias++); - - ip = (struct in_addr **) hp->h_addr_list; - while (ip[0]) - fprintf(stderr, _("Result: h_addr_list=`%s'\n"), - inet_ntoa(**ip++)); + str = inet_ntop(rp->ai_addr->sa_family, + adr, buf, sizeof(buf)); + if(str) + fprintf(stderr, _("Result: ai_addr[%zd]=`%s'\n"), n, str); + } } - if (!(p = strchr(hp->h_name, '.')) && (c == 'd')) + if (!(p = strchr(res->ai_canonname, '.')) && (c == 'd')) { + freeaddrinfo(res); return; + } switch (c) { - case 'a': - while (hp->h_aliases[0]) { - printf("%s", *hp->h_aliases++); - if (hp->h_aliases[0]) - printf(" "); + case 'a': { + /* + ** getaddrinfo / getnameinfo do not provide aliases, + ** so we have to fetch them using gethostbyaddr ... + */ + struct aliases_t aliases = { NULL, NULL }; + struct alias_t *a; + + for(n=0, rp=res; rp; rp=rp->ai_next, n++) { + struct hostent *hp; + const void *adr = NULL; + socklen_t len; + + switch(rp->ai_addr->sa_family) { + case AF_INET: + adr = &(((struct sockaddr_in *)rp->ai_addr)->sin_addr); + len = sizeof(struct in_addr); + break; + case AF_INET6: + adr = &(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr); + len = sizeof(struct in6_addr); + break; + } + if( !adr) + continue; + + hp = gethostbyaddr(adr, len, rp->ai_addr->sa_family); + if(hp) { + for(alias = hp->h_aliases; alias && *alias; alias++) { + if(opt_v) + fprintf(stderr, _("Result: h_aliases[%zd]=`%s'\n"), + n, *alias); + aliases_add(&aliases, *alias); + } + } + } + while( (a=aliases.head)) { + aliases.head = a->next; + printf("%s%s", a->name, (a->next ? " " : "")); + free(a); } printf("\n"); - break; + } break; case 'i': - while (hp->h_addr_list[0]) { - printf("%s", inet_ntoa(*(struct in_addr *) *hp->h_addr_list++)); - if (hp->h_addr_list[0]) - printf(" "); + for(n=0, rp=res; rp; rp=rp->ai_next, n++) { + char buf[INET6_ADDRSTRLEN] = {'\0'}; + const char *str = NULL; + const void *adr = NULL; + + switch(rp->ai_addr->sa_family) { + case AF_INET: + adr = &(((struct sockaddr_in *)rp->ai_addr)->sin_addr); + break; + case AF_INET6: + adr = &(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr); + break; + } + if( !adr) + continue; + + str = inet_ntop(rp->ai_addr->sa_family, + adr, buf, sizeof(buf)); + if(str) + printf("%s%s", str, (rp->ai_next ? " " : "")); } printf("\n"); break; @@ -175,16 +298,17 @@ static void showhname(char *hname, int c printf("%s\n", ++p); break; case 'f': - printf("%s\n", hp->h_name); + printf("%s\n", res->ai_canonname); break; case 's': if (p != NULL) *p = '\0'; - printf("%s\n", hp->h_name); + printf("%s\n", res->ai_canonname); break; default: - return; + break; } + freeaddrinfo(res); } static void setfilename(char *name, int what) @@ -336,11 +460,12 @@ int main(int argc, char **argv) break; case 'V': version(); + break; // not reached case '?': case 'h': default: usage(); - + break; // not reached }; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org