+++ /dev/null
-diff -urN cvs-1.11.9.org/src/client.c cvs-1.11.9/src/client.c
---- cvs-1.11.9.org/src/client.c 2003-10-15 19:28:25.000000000 +0200
-+++ cvs-1.11.9/src/client.c 2003-10-15 19:28:34.000000000 +0200
-@@ -80,7 +80,7 @@
- /* This is needed for GSSAPI encryption. */
- static gss_ctx_id_t gcontext;
-
--static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
-+static int connect_to_gserver PROTO((cvsroot_t *, int, char *));
-
- # endif /* HAVE_GSSAPI */
-
-@@ -131,7 +131,7 @@
- static size_t try_read_from_server PROTO ((char *, size_t));
-
- static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *,
-- int, int, struct hostent *));
-+ int, int, char *));
-
- /* We need to keep track of the list of directories we've sent to the
- server. This list, along with the current CVSROOT, will help us
-@@ -3487,30 +3487,6 @@
-
-
- #if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
--static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *,
-- unsigned int));
--
--static struct hostent *
--init_sockaddr (name, hostname, port)
-- struct sockaddr_in *name;
-- char *hostname;
-- unsigned int port;
--{
-- struct hostent *hostinfo;
-- unsigned short shortport = port;
--
-- memset (name, 0, sizeof (*name));
-- name->sin_family = AF_INET;
-- name->sin_port = htons (shortport);
-- hostinfo = gethostbyname (hostname);
-- if (hostinfo == NULL)
-- {
-- fprintf (stderr, "Unknown host %s.\n", hostname);
-- error_exit ();
-- }
-- name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
-- return hostinfo;
--}
-
-
-
-@@ -3685,34 +3661,59 @@
- int do_gssapi;
- {
- int sock;
-- int port_number;
-- struct sockaddr_in client_sai;
-- struct hostent *hostinfo;
-+ int gerr;
-+ struct addrinfo hints, *res, *res0;
-+ char pbuf[32];
- struct buffer *to_server, *from_server;
-
-- sock = socket (AF_INET, SOCK_STREAM, 0);
-- if (sock == -1)
-+ sprintf (pbuf, "%u", get_cvs_port_number (root));
-+ pbuf[sizeof(pbuf)-1] = '\0';
-+ memset (&hints, 0, sizeof (hints));
-+ hints.ai_family = af;
-+ hints.ai_socktype = SOCK_STREAM;
-+ gerr = getaddrinfo (root->hostname, pbuf, &hints, &res0);
-+ if (gerr)
- {
-- error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
-+ fprintf (stderr, "Unknown host %s.\n", root->hostname);
-+ error_exit ();
- }
-- port_number = get_cvs_port_number (root);
-- hostinfo = init_sockaddr (&client_sai, root->hostname, port_number);
-- if (trace)
-+
-+ /* Try connect to current_parsed_root->hostname using all available families */
-+ for (res = res0; res != NULL; res = res->ai_next)
- {
-- fprintf (stderr, " -> Connecting to %s(%s):%d\n",
-- root->hostname,
-- inet_ntoa (client_sai.sin_addr), port_number);
-- }
-- if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai))
-- < 0)
-- error (1, 0, "connect to %s(%s):%d failed: %s",
-- root->hostname,
-- inet_ntoa (client_sai.sin_addr),
-- port_number, SOCK_STRERROR (SOCK_ERRNO));
-+ sock = socket (res->ai_family, res->ai_socktype, 0);
-+ if (sock == -1) {
-+ if (res->ai_next)
-+ continue;
-+ else {
-+ char *sock_error = SOCK_STRERROR (SOCK_ERRNO);
-+ freeaddrinfo(res0);
-+ error (1, 0, "cannot create socket: %s", sock_error);
-+ }
-+ }
-+
-+ if (connect (sock, res->ai_addr, res->ai_addrlen) < 0)
-+ {
-+ if (res->ai_next)
-+ {
-+ close(sock);
-+ continue;
-+ }
-+ else
-+ {
-+ char *sock_error = SOCK_STRERROR (SOCK_ERRNO);
-+ freeaddrinfo(res0);
-+ error (1, 0, "connect to [%s]:%s failed: %s", root->hostname,
-+ pbuf, sock_error);
-+ }
-+ }
-+ /* success */
-+ break;
-+ }
-
- make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1);
-
-- auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo);
-+ auth_server (root, to_server, from_server, verify_only, do_gssapi, root->hostname);
-
- if (verify_only)
- {
-@@ -3746,13 +3747,13 @@
-
-
- static void
--auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
-+auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostname)
- cvsroot_t *root;
- struct buffer *lto_server;
- struct buffer *lfrom_server;
- int verify_only;
- int do_gssapi;
-- struct hostent *hostinfo;
-+ char *hostname;
- {
- char *username; /* the username we use to connect */
- char no_passwd = 0; /* gets set if no password found */
-@@ -3782,7 +3783,7 @@
- error (1, 0, "gserver currently only enabled for socket connections");
- }
-
-- if (! connect_to_gserver (root, fd, hostinfo))
-+ if (! connect_to_gserver (root, fd, hostname))
- {
- error (1, 0,
- "authorization failed: server %s rejected access to %s",
-@@ -3798,7 +3799,7 @@
- char *begin = NULL;
- char *password = NULL;
- char *end = NULL;
--
-+
- if (verify_only)
- {
- begin = "BEGIN VERIFICATION REQUEST";
-@@ -3979,36 +3980,75 @@
- int s;
- const char *portenv;
- int port;
-- struct hostent *hp;
-- struct sockaddr_in sin;
-+ int gerr;
-+ struct addrinfo hints, *res, *res0;
- char *hname;
--
-- s = socket (AF_INET, SOCK_STREAM, 0);
-- if (s < 0)
-- error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
-+ char pbuf[32], hbuf[1025];
-
- port = get_cvs_port_number (root);
-
-- hp = init_sockaddr (&sin, root->hostname, port);
--
-- hname = xstrdup (hp->h_name);
--
-- if (trace)
-+ sprintf (pbuf, "%u", port);
-+ pbuf[sizeof(pbuf)-1] = '\0';
-+ memset (&hints, 0, sizeof(hints));
-+ hints.ai_family = af;
-+ hints.ai_socktype = SOCK_STREAM;
-+ gerr = getaddrinfo (root->hostname, pbuf, &hints, &res0);
-+ if (gerr)
- {
-- fprintf (stderr, " -> Connecting to %s(%s):%d\n",
-- root->hostname,
-- inet_ntoa (sin.sin_addr), port);
-+ fprintf (stderr, "Unknown host %s.\n", root->hostname);
-+ error_exit ();
- }
-
-- if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0)
-- error (1, 0, "connect to %s(%s):%d failed: %s",
-- root->hostname,
-- inet_ntoa (sin.sin_addr),
-- port, SOCK_STRERROR (SOCK_ERRNO));
-+ /* Try connect to current_parsed_root->hostname using all available families */
-+ gerr = -1;
-+ for (res = res0; res != NULL; res = res->ai_next)
-+ {
-+ s = socket (res->ai_family, res->ai_socktype, 0);
-+ if (s < 0)
-+ {
-+ if (res->ai_next)
-+ continue;
-+ else
-+ {
-+ char *sock_error = SOCK_STRERROR (SOCK_ERRNO);
-+ freeaddrinfo(res0);
-+ error (1, 0, "cannot create socket: %s", sock_error);
-+ }
-+ }
-+ if (trace)
-+ {
-+ char hbuf[1025];
-+ getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
-+ NULL, 0, NI_NUMERICHOST);
-+ fprintf (stderr, " -> Connecting to %s(%s):%d\n",
-+ root->hostname, hbuf, port);
-+ }
-+
-+ if (connect (s, res->ai_addr, res->ai_addrlen) < 0)
-+ {
-+ if (res->ai_next)
-+ {
-+ close(s);
-+ continue;
-+ }
-+ else
-+ {
-+ char *sock_error = SOCK_STRERROR (SOCK_ERRNO);
-+ freeaddrinfo(res0);
-+ error (1, 0, "connect to [%s]:%s failed: %s",
-+ root->hostname, pbuf, sock_error);
-+ }
-+ }
-+ getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), NULL, 0, 0);
-+ hname = xstrdup (hbuf);
-+ /* success */
-+ break;
-+ }
-+ freeaddrinfo(res0);
-
- {
- const char *realm;
-- struct sockaddr_in laddr;
-+ struct sockaddr_storage laddr;
- int laddrlen;
- KTEXT_ST ticket;
- MSG_DAT msg_data;
-@@ -4084,10 +4124,10 @@
- */
- #define BUFSIZE 1024
- static int
--connect_to_gserver (root, sock, hostinfo)
-+connect_to_gserver (root, sock, hostname)
- cvsroot_t *root;
- int sock;
-- struct hostent *hostinfo;
-+ char *hostname;
- {
- char *str;
- char buf[BUFSIZE];
-@@ -4100,9 +4140,9 @@
- if (send (sock, str, strlen (str), 0) < 0)
- error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
-
-- if (strlen (hostinfo->h_name) > BUFSIZE - 5)
-+ if (strlen (hostname) > BUFSIZE - 5)
- error (1, 0, "Internal error: hostname exceeds length of buffer");
-- sprintf (buf, "cvs@%s", hostinfo->h_name);
-+ sprintf (buf, "cvs@%s", hostname);
- tok_in.length = strlen (buf);
- tok_in.value = buf;
- gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
-diff -urN cvs-1.11.9.org/src/cvs.h cvs-1.11.9/src/cvs.h
---- cvs-1.11.9.org/src/cvs.h 2003-10-15 19:28:25.000000000 +0200
-+++ cvs-1.11.9/src/cvs.h 2003-10-15 19:28:34.000000000 +0200
-@@ -366,6 +366,7 @@
- extern int really_quiet, quiet;
- extern int use_editor;
- extern int cvswrite;
-+extern int af;
- extern mode_t cvsumask;
-
-
-diff -urN cvs-1.11.9.org/src/main.c cvs-1.11.9/src/main.c
---- cvs-1.11.9.org/src/main.c 2003-10-15 19:28:25.000000000 +0200
-+++ cvs-1.11.9/src/main.c 2003-10-15 19:28:34.000000000 +0200
-@@ -13,6 +13,7 @@
- */
-
- #include <assert.h>
-+#include <sys/socket.h>
- #include "cvs.h"
-
- #ifdef HAVE_WINSOCK_H
-@@ -42,6 +43,7 @@
- int trace = 0;
- int noexec = 0;
- int logoff = 0;
-+int af = AF_UNSPEC;
-
- /* Set if we should be writing CVSADM directories at top level. At
- least for now we'll make the default be off (the CVS 1.9, not CVS
-@@ -162,7 +164,7 @@
- in --help as it is a rather different format from the rest. */
-
- "Usage: %s [cvs-options] command [command-options-and-arguments]\n",
-- " where cvs-options are -q, -n, etc.\n",
-+ " where cvs-options are -4, -6,-q, -n, etc.\n",
- " (specify --help-options for a list of options)\n",
- " where command is add, admin, etc.\n",
- " (specify --help-commands for a list of commands\n",
-@@ -406,7 +408,7 @@
- int help = 0; /* Has the user asked for help? This
- lets us support the `cvs -H cmd'
- convention to give help for cmd. */
-- static const char short_options[] = "+Qqrwtnvb:T:e:d:Hfz:s:xa";
-+ static const char short_options[] = "+46Qqrwtnvb:T:e:d:Hfz:s:xa";
- static struct option long_options[] =
- {
- {"help", 0, NULL, 'H'},
-@@ -519,6 +521,12 @@
- /* --allow-root */
- root_allow_add (optarg);
- break;
-+ case '4':
-+ af = AF_INET;
-+ break;
-+ case '6':
-+ af = AF_INET6;
-+ break;
- case 'Q':
- really_quiet = 1;
- /* FALL THROUGH */
-diff -urN cvs-1.11.9.org/src/server.c cvs-1.11.9/src/server.c
---- cvs-1.11.9.org/src/server.c 2003-10-15 19:28:25.000000000 +0200
-+++ cvs-1.11.9/src/server.c 2003-10-15 19:29:16.000000000 +0200
-@@ -5756,8 +5756,8 @@
- {
- int status;
- char instance[INST_SZ];
-- struct sockaddr_in peer;
-- struct sockaddr_in laddr;
-+ struct sockaddr_storage peer;
-+ struct sockaddr_storage laddr;
- int len;
- KTEXT_ST ticket;
- AUTH_DAT auth;
-@@ -5834,7 +5834,8 @@
- gserver_authenticate_connection ()
- {
- char hostname[MAXHOSTNAMELEN];
-- struct hostent *hp;
-+ char hbuf[1025];
-+ struct addrinfo hints, *res0;
- gss_buffer_desc tok_in, tok_out;
- char buf[1024];
- OM_uint32 stat_min, ret;
-@@ -5844,11 +5845,16 @@
- gss_OID mechid;
-
- gethostname (hostname, sizeof hostname);
-- hp = gethostbyname (hostname);
-- if (hp == NULL)
-+ hostname[sizeof(hostname)-1] = '\0';
-+ memset (&hints, 0, sizeof(hints));
-+ hints.ai_family = af;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_flags = AI_CANONNAME;
-+ if (getaddrinfo (hostname, NULL, &hints, &res0))
- error (1, 0, "can't get canonical hostname");
-
-- sprintf (buf, "cvs@%s", hp->h_name);
-+ sprintf (buf, "cvs@%s", res0->ai_canonname);
-+ freeaddrinfo (res0);
- tok_in.value = buf;
- tok_in.length = strlen (buf);
-