You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.3 KiB
120 lines
3.3 KiB
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468454
|
|
|
|
Description: Implement IPv6 capability for the client Finger.
|
|
Author: Mats Erik Andersson <debian@gisladisker.se>
|
|
Forwarded: no
|
|
Last-Updated: 2010-02-09
|
|
|
|
--- a/finger/finger.c
|
|
+++ b/finger/finger.c
|
|
@@ -93,7 +93,7 @@
|
|
int main(int argc, char *argv[]) {
|
|
int ch;
|
|
int err = 0;
|
|
- struct sockaddr_in sin;
|
|
+ struct sockaddr_storage sin;
|
|
socklen_t slen = sizeof(sin);
|
|
|
|
while ((ch = getopt(argc, argv, "lmps")) != EOF) {
|
|
@@ -137,6 +137,8 @@ int main(int argc, char *argv[]) {
|
|
* Also check stdin for nofinger processing, because of older
|
|
* fingerds that make stdout a pipe for CRLF handling.
|
|
*/
|
|
+ slen = sizeof(slen); /* For safety: sockaddr_in and sockaddr_in6 */
|
|
+
|
|
if (getsockname(STDIN_FILENO, (struct sockaddr *)&sin, &slen)==0) {
|
|
enable_nofinger = 1;
|
|
}
|
|
--- a/finger/net.c
|
|
+++ b/finger/net.c
|
|
@@ -53,13 +53,12 @@
|
|
|
|
int netfinger(const char *name) {
|
|
register FILE *fp;
|
|
- struct in_addr defaddr;
|
|
register int c, sawret, ateol;
|
|
- struct hostent *hp, def;
|
|
+ struct addrinfo hints, *result, *resptr;
|
|
struct servent *sp;
|
|
- struct sockaddr_in sn;
|
|
- int s;
|
|
- char *alist[1], *host;
|
|
+ struct sockaddr_storage sn;
|
|
+ int s, status;
|
|
+ char *host;
|
|
|
|
host = strrchr(name, '@');
|
|
if (!host) return 1;
|
|
@@ -72,38 +71,46 @@ int netfinger(const char *name) {
|
|
eprintf("finger: tcp/finger: unknown service\n");
|
|
return 1;
|
|
}
|
|
- sn.sin_port = sp->s_port;
|
|
+ memset(&hints, 0, sizeof(hints));
|
|
+ hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
|
|
+ hints.ai_family = AF_UNSPEC;
|
|
+ hints.ai_socktype = SOCK_STREAM;
|
|
+ hints.ai_protocol = IPPROTO_TCP;
|
|
+
|
|
+ status = getaddrinfo(host, "finger", &hints, &result);
|
|
+ if (status != 0) {
|
|
+ eprintf("finger: unknown host: %s\n", host);
|
|
+ eprintf("getaddrinfo: %s\n", gai_strerror(status));
|
|
+ return 1;
|
|
+ }
|
|
|
|
- hp = gethostbyname(host);
|
|
- if (!hp) {
|
|
- if (!inet_aton(host, &defaddr)) {
|
|
- eprintf("finger: unknown host: %s\n", host);
|
|
- return 1;
|
|
+ for ( resptr = result; resptr; resptr = resptr->ai_next) {
|
|
+
|
|
+ if ((s = socket(resptr->ai_family, resptr->ai_socktype,
|
|
+ resptr->ai_protocol)) < 0)
|
|
+ continue;
|
|
+
|
|
+
|
|
+ /* print hostname before connecting, in case it takes a while */
|
|
+ /* This should probably be removed. */
|
|
+ /* xprintf("[%s]\n", result->ai_canonname); */
|
|
+
|
|
+ if (connect(s, resptr->ai_addr, resptr->ai_addrlen) < 0) {
|
|
+ close(s);
|
|
+ continue;
|
|
}
|
|
- def.h_name = host;
|
|
- def.h_addr_list = alist;
|
|
- def.h_addr = (char *)&defaddr;
|
|
- def.h_length = sizeof(struct in_addr);
|
|
- def.h_addrtype = AF_INET;
|
|
- def.h_aliases = 0;
|
|
- hp = &def;
|
|
- }
|
|
- sn.sin_family = hp->h_addrtype;
|
|
- if (hp->h_length > (int)sizeof(sn.sin_addr)) {
|
|
- hp->h_length = sizeof(sn.sin_addr);
|
|
- }
|
|
- memcpy(&sn.sin_addr, hp->h_addr, hp->h_length);
|
|
|
|
- if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
|
|
- eprintf("finger: socket: %s\n", strerror(errno));
|
|
- return 1;
|
|
+ /* Connection is now established.
|
|
+ /* Assemble the gained information. */
|
|
+ memcpy(&sn, resptr->ai_addr, resptr->ai_addrlen);
|
|
+ break;
|
|
}
|
|
|
|
- /* print hostname before connecting, in case it takes a while */
|
|
- xprintf("[%s]\n", hp->h_name);
|
|
- if (connect(s, (struct sockaddr *)&sn, sizeof(sn)) < 0) {
|
|
+ freeaddrinfo(result);
|
|
+
|
|
+ if ( resptr == NULL ) {
|
|
+ /* Last error is still providing the correct clue. */
|
|
eprintf("finger: connect: %s\n", strerror(errno));
|
|
- close(s);
|
|
return 1;
|
|
}
|
|
|
|
|