Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.1:Staging:C
net-tools
net-tools-1.60-hostname-ipv6.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File net-tools-1.60-hostname-ipv6.patch of Package net-tools
--- 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 };
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor