]> git.pld-linux.org Git - packages/inn.git/commitdiff
- updated v6 patch (not tested)
authorJakub Bogusz <qboosh@pld-linux.org>
Tue, 19 Jun 2001 16:14:37 +0000 (16:14 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    inn-ipv6.patch -> 1.1
    inn.spec -> 1.100

inn-ipv6.patch [new file with mode: 0644]
inn.spec

diff --git a/inn-ipv6.patch b/inn-ipv6.patch
new file mode 100644 (file)
index 0000000..d124c36
--- /dev/null
@@ -0,0 +1,2451 @@
+diff -Nur inn-2.3.2.orig/authprogs/auth_pass.c inn-2.3.2/authprogs/auth_pass.c
+--- inn-2.3.2.orig/authprogs/auth_pass.c       Thu May  3 22:27:32 2001
++++ inn-2.3.2/authprogs/auth_pass.c    Tue Jun 19 16:06:41 2001
+@@ -70,8 +70,11 @@
+     int                       length;
+     char              password[256];
+     char              peername[1024];
++#ifdef INET6
++    char              tmpname[1048];
++#endif        /* INET6 */
+     struct passwd *   pwd;
+-    struct sockaddr_in        sin;
++    struct sockaddr_storage   ss;
+     char              username[32];
+     /*
+@@ -105,22 +108,43 @@
+     /*
+      *  Get the hostname of the peer.
+      */
+-    length = sizeof(sin);
+-    if (getpeername(0, (struct sockaddr *)&sin, &length) < 0) {
++    length = sizeof(ss);
++    if (getpeername(0, (struct sockaddr *)&ss, &length) < 0) {
+         if (!isatty(0)) {
+             fprintf(stderr, "cant getpeername()::%s:+:!*\n", username);
+             exit(1);
+         }
+         (void)strcpy(peername, "stdin");
+-    } else if (sin.sin_family != AF_INET) {
++#ifdef INET6
++    } else if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
++#else
++    } else if (ss.ss_family != AF_INET) {
++#endif
+         fprintf(stderr, "Bad address family %ld::%s:+:!*\n",
+-                (long)sin.sin_family, username);
++                (long)ss.ss_family, username);
+         exit(1);
+-    } else if ((hp = gethostbyaddr((char *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET)) == NULL) {
+-        strcpy(peername, inet_ntoa(sin.sin_addr));
++#ifdef INET6
++    } else {
++#ifdef HAVE_SOCKADDR_LEN
++      getnameinfo((struct sockaddr *)&ss, ss.ss_len, peername, 
++                  sizeof(peername), NULL, 0, 0);
++#else
++      getnameifno((struct sockaddr *)&ss, SA_LEN((struct sockaddr *)&ss), 
++                  peername, sizeof(peername), NULL, 0, 0);
++#endif        /* HAVE_SOCKADDR_LEN */
++      if (strchr(peername, ':') != NULL) {
++          sprintf(tmpname, "[%s]", peername);
++          if (strlen(tmpname) < sizeof(peername))
++              strcpy(peername, tmpname);
++      } 
++    }
++#else         /* INET6 */
++    } else if ((hp = gethostbyaddr((char *)&((struct sockaddr_in *)&ss)-sin_addr, sizeof(struct in_addr), AF_INET)) == NULL) {
++        strcpy(peername, inet_ntoa(((struct sockaddr *)&ss)->sin_addr));
+     } else {
+         strncpy(peername, hp->h_name, sizeof(peername));
+     }
++#endif        /* INET6 */
+    
+     /*
+      *  Get the user name in the passwd file.
+diff -Nur inn-2.3.2.orig/configure.in inn-2.3.2/configure.in
+--- inn-2.3.2.orig/configure.in        Thu May  3 22:27:32 2001
++++ inn-2.3.2/configure.in     Tue Jun 19 16:06:41 2001
+@@ -380,6 +380,199 @@
+     fi
+ esac
+   
++dnl === part for IPv6 support ===
++AC_MSG_CHECKING([whether to enable ipv6])
++AC_ARG_ENABLE(ipv6,
++[  --enable-ipv6              Enable ipv6 (with ipv4) support
++  --disable-ipv6              Disable ipv6 support],
++[ case "$enableval" in
++  no)
++       AC_MSG_RESULT(no)
++       ipv6=no
++       ;;
++  *)   AC_MSG_RESULT(yes)
++       AC_DEFINE(ENABLE_IPV6)
++       ipv6=yes
++       ;;
++  esac ],
++
++  AC_TRY_RUN([ /* AF_INET6 avalable check */
++#include <sys/types.h>
++#include <sys/socket.h>
++main()
++{
++ if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
++   exit(1);
++ else
++   exit(0);
++}
++],
++  AC_MSG_RESULT(yes)
++  AC_DEFINE(ENABLE_IPV6)
++  ipv6=yes,
++  AC_MSG_RESULT(no)
++  ipv6=no,
++  AC_MSG_RESULT(no)
++  ipv6=no
++))
++
++ipv6type=unknown
++ipv6lib=none
++
++if test "$ipv6" = "yes"; then
++        AC_MSG_CHECKING([IPv6 stack type])
++        for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
++                case $i in
++                inria)
++                        dnl http://www.kame.net/
++                        AC_EGREP_CPP(%%%yes%%%, [dnl
++#include <netinet/in.h>
++#ifdef IPV6_INRIA_VERSION
++%%%yes%%%
++#endif],
++                                [ipv6type=$i;
++                                CFLAGS="-DINET6 $CFLAGS"])
++                        ;;
++                kame)
++                      dnl http://www.kame.net/
++                        AC_EGREP_CPP(%%%yes%%%, [dnl
++#include <netinet/in.h>
++#ifdef __KAME__
++%%%yes%%%
++#endif],
++                                [ipv6type=$i;
++                                CFLAGS="-DINET6 $CFLAGS"])
++                        ;;
++                linux-glibc)
++                        dnl http://www.v6.linux.or.jp/
++                        AC_EGREP_CPP(%%%yes%%%, [dnl
++#include <features.h>
++#if defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1
++%%%yes%%%
++#endif],
++                                [ipv6type=$i;
++                              CFLAGS="-DINET6 $CFLAGS"])
++                        ;;
++                linux-inet6)
++                        dnl http://www.v6.linux.or.jp/
++                        if test -d /usr/inet6; then
++                                ipv6type=$i
++                                ipv6lib=inet6
++                                ipv6libdir=/usr/inet6/lib
++                                CFLAGS="-DINET6 -I/usr/inet6/include $CFLAGS"
++                        fi
++                        ;;
++                toshiba)
++                        AC_EGREP_CPP(%%%yes%%%, [dnl
++#include <sys/param.h>
++#ifdef _TOSHIBA_INET6
++%%%yes%%%
++#endif],
++                                [ipv6type=$i;
++                                ipv6lib=inet6;
++                                ipv6libdir=/usr/local/v6/lib;
++                                CFLAGS="-DINET6 $CFLAGS"])
++                        ;;
++                v6d)
++                        AC_EGREP_CPP(%%%yes%%%, [dnl
++#include </usr/local/v6/include/sys/v6config.h>
++#ifdef __V6D__
++%%%yes%%%
++#endif],
++                                [ipv6type=$i;
++                                ipv6lib=v6;
++                                ipv6libdir=/usr/local/v6/lib;
++                              CFLAGS="-I/usr/local/v6/include $CFLAGS"])
++                        ;;
++                zeta)
++                        AC_EGREP_CPP(%%%yes%%%, [dnl
++#include <sys/param.h>
++#ifdef _ZETA_MINAMI_INET6
++yes
++#endif],
++                                [ipv6type=$i;
++                                ipv6lib=inet6;
++                                ipv6libdir=/usr/local/v6/lib;
++                                CFLAGS="-DINET6 $CFLAGS"])
++                        ;;
++                esac
++                if test "$ipv6type" != "unknown"; then
++                        break
++                fi
++        done
++        AC_MSG_RESULT($ipv6type)
++fi
++
++if test "$ipv6" = "yes"; then
++      if test -d /usr/local/v6/lib; then
++              ac_inet6_LDFLAGS="inet6"
++              ipv6libdir=/usr/local/v6/lib
++              LDFLAGS="$LDFLAGS -L/usr/local/v6/lib"
++              AC_CHECK_LIB(inet6, getaddrinfo, , ipv6lib="$ac_inet6_LDFLAGS")
++      else
++              AC_CHECK_FUNCS(getaddrinfo)
++      fi
++fi
++
++if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
++        if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then
++                LIBS="-L$ipv6libdir -l$ipv6lib $LIBS"
++      fi
++fi
++AC_SUBST(ipv6)
++
++dnl checking for sa_len;
++dnl  the following check says 'yes' if your system has __libc_sa_len
++dnl  AC_EGREP_HEADER(sa_len, sys/socket.h,
++dnl    [ AC_DEFINE(HAVE_SOCKADDR_LEN) AC_MSG_RESULT(yes)], AC_MSG_RESULT(no))
++AC_MSG_CHECKING([whether struct sockaddr has sa_len])
++AC_TRY_COMPILE([
++#include <sys/types.h>
++#include <sys/socket.h>
++],[
++struct sockaddr sa;
++int i = sa.sa_len;
++],
++[AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_SOCKADDR_LEN)],
++AC_MSG_RESULT(no))
++
++AC_MSG_CHECKING([whether sys/socket.h has SA_LEN])
++AC_TRY_RUN([
++#include <sys/types.h>
++#include <sys/socket.h>
++struct sockaddr sa;
++int main(){ int i = SA_LEN((struct sockaddr*)&sa); return 0;}
++],
++[AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_SA_LEN)],
++AC_MSG_RESULT(no),AC_MSG_RESULT(no))
++
++AC_MSG_CHECKING([whether sys/socket.h has struct sockaddr_storage])
++AC_TRY_COMPILE([
++#include <sys/types.h>
++#include <sys/socket.h>
++],[
++struct sockaddr_storage ss;
++],
++[AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_SOCKADDR_STORAGE)],
++AC_MSG_RESULT(no))
++
++AC_MSG_CHECKING([whether struct sockaddr_storage has __ss_family])
++AC_TRY_COMPILE([
++#include <sys/types.h>
++#include <sys/socket.h>
++],[
++struct sockaddr_storage ss;
++int i = ss.__ss_family;
++],
++[AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_2553_STYLE_SS_FAMILY)],
++AC_MSG_RESULT(no), AC_MSG_RESULT(no))
++
++dnl === end of part for IPv6 support ===
++
+ dnl Checks for pathnames.
+ dnl See if we have ctags; if so, set CTAGS to its full path plus the -t -w
+@@ -1061,7 +1254,7 @@
+ AC_CHECK_FUNCS(atexit fchmod fcntl gethostname getpagesize getrusage \
+                getspnam gettimeofday mkfifo setbuffer sigaction setsid \
+                socketpair statvfs strcspn strncasecmp strstr strtoul \
+-               symlink waitpid)
++               symlink waitpid inet_ntoa)
+ dnl We only care if we have setreuid() if we don't have seteuid().
+ AC_CHECK_FUNCS(seteuid setreuid, break)
+@@ -1095,7 +1288,7 @@
+ fi
+ dnl If we can't find any of the following, we have replacements for them.
+-AC_REPLACE_FUNCS(fseeko ftello getopt inet_aton inet_ntoa pread pwrite \
++AC_REPLACE_FUNCS(fseeko ftello getopt inet_aton pread pwrite \
+                  strcasecmp strdup strerror strspn setenv hstrerror)
+ dnl If replacing fseeko or ftello, see if we can use fsetpos/fgetpos.
+diff -Nur inn-2.3.2.orig/doc/man/inn.conf.5 inn-2.3.2/doc/man/inn.conf.5
+--- inn-2.3.2.orig/doc/man/inn.conf.5  Thu May  3 22:27:32 2001
++++ inn-2.3.2/doc/man/inn.conf.5       Tue Jun 19 16:06:41 2001
+@@ -1055,6 +1055,25 @@
+ directory).  It must be on the same partition as \fIpathincoming\fR for
+ \&\fIrnews\fR\|(1) to work correctly.  The default value is set at configure time
+ and defaults to \fIpathnews\fR/tmp.
++.Sh "IPv6 Configurations"
++.IX Subsection "IPv6 Configurations"
++If your system can use IPv6, the following parameters are available.
++.Ip "\fIlistenonipv6\fR" 4
++.IX Item "listenonipv6"
++If set to true, \fIinnd\fR\|(8) creates an IPv6 socket for waiting connections
++from IPv6 clients.
++.Ip "\fIbindipv6address\fR" 4
++.IX Item "bindipv6address"
++Which IPv6 address \fIinnd\fR\|(8) should bind itself to. This must be in
++numeric IPv6 address format. If set to \f(CW\*(C`all\*(C'\fR or not set, innd 
++defaults to listening on all interfaces. The default value is unset.
++.Ip "\fIsourceipv6address\fR" 4
++.IX Item "sourceipv6address"
++Which local IPv6 address to bind to outgoing NNTP sockets (used by 
++\fIinnxmit\fR\|(8) among other programs). This must be in numeric IPv6
++address format. If set to \f(CW\*(C`all\*(C'\fR or not set,
++the operating system will choose the source IPv6 address for outgoing 
++connections. The default value is unset.
+ .SH "EXAMPLE"
+ .IX Header "EXAMPLE"
+ Here is a very minimalist example that only sets those parameters that are
+diff -Nur inn-2.3.2.orig/include/clibrary.h inn-2.3.2/include/clibrary.h
+--- inn-2.3.2.orig/include/clibrary.h  Thu May  3 22:27:32 2001
++++ inn-2.3.2/include/clibrary.h       Tue Jun 19 16:06:41 2001
+@@ -102,9 +102,7 @@
+ #ifndef HAVE_PWRITE
+ extern ssize_t pwrite(int fd, void *buf, size_t nbyte, OFFSET_T offset);
+ #endif
+-#ifndef HAVE_INET_NTOA
+-extern char *inet_ntoa();
+-#endif
++extern char *Inet_NtoA();
+ #ifndef HAVE_STRDUP
+ extern char *strdup();
+ #endif
+diff -Nur inn-2.3.2.orig/include/config.h.in inn-2.3.2/include/config.h.in
+--- inn-2.3.2.orig/include/config.h.in Thu May  3 22:27:32 2001
++++ inn-2.3.2/include/config.h.in      Tue Jun 19 16:06:41 2001
+@@ -732,4 +732,26 @@
+ /* All incoming control commands (ctlinnd, etc). */
+ #define L_CC_CMD                LOG_INFO
++/* IPv6 support */
++
++/* sockaddr.sa_len */
++#undef HAVE_SOCKADDR_LEN
++
++/* SA_LEN() */
++#undef HAVE_SA_LEN
++
++/* struct sockaddr_storage */
++#undef HAVE_SOCKADDR_STORAGE
++
++/* getaddrinfo() */
++#undef HAVE_GETADDRINFO
++
++/* sockaddr_storage.__ss_family */
++#undef HAVE_2553_STYLE_SS_FAMILY
++
++#ifdef HAVE_2553_STYLE_SS_FAMILY
++#  define     ss_family       __ss_family
++#  define     ss_len          __ss_len
++#endif
++
+ #endif /* !__CONFIG_H__ */
+diff -Nur inn-2.3.2.orig/include/innconf.h inn-2.3.2/include/innconf.h
+--- inn-2.3.2.orig/include/innconf.h   Thu May  3 22:27:32 2001
++++ inn-2.3.2/include/innconf.h        Tue Jun 19 16:06:41 2001
+@@ -329,7 +329,16 @@
+     { _CONF_WIPCHECK,                         "",     2, 1 },
+ #define       _CONF_NNRPPYTHONAUTH                    "nnrppythonauth"
+ #define       CONF_VAR_NNRPPYTHONAUTH                 103
+-    { _CONF_NNRPPYTHONAUTH,                   "",     2, 1 }
++    { _CONF_NNRPPYTHONAUTH,                   "",     2, 1 },
++#define _CONF_LISTENONIPV6                    "listenonipv6"
++#define CONF_VAR_LISTENONIPV6                 104
++    { _CONF_LISTENONIPV6,                     "",     2, 0 },
++#define _CONF_BINDIPV6ADDRESS                 "bindipv6address"
++#define CONF_VAR_BINDIPV6ADDRESS              105
++    { _CONF_BINDIPV6ADDRESS,                  "",     1, 0 },
++#define _CONF_SOURCEIPV6ADDRESS                       "sourceipv6address"
++#define CONF_VAR_SOURCEIPV6ADDRESS            106
++    { _CONF_SOURCEIPV6ADDRESS,                        "",     1, 0 }
+ };
+-#define MAX_CONF_VAR 104
++#define MAX_CONF_VAR 106
+diff -Nur inn-2.3.2.orig/include/libinn.h inn-2.3.2/include/libinn.h
+--- inn-2.3.2.orig/include/libinn.h    Thu May  3 22:27:32 2001
++++ inn-2.3.2/include/libinn.h Tue Jun 19 16:06:41 2001
+@@ -101,6 +101,7 @@
+     /* Feed Configuration */
+     int artcutoff;              /* Max accepted article age */
+     char *bindaddress;          /* Which interface IP to bind to */
++    char *bindipv6address;    /* Which interface IP to bind to */
+     int hiscachesize;           /* Size of the history cache in kB */
+     int ignorenewsgroups;       /* Propagate cmsgs by affected group? */
+     int immediatecancel;        /* Immediately cancel timecaf messages? */
+@@ -112,11 +113,13 @@
+     int refusecybercancels;     /* Reject message IDs with "<cancel."? */
+     int remembertrash;          /* Put unwanted article IDs into history */
+     char *sourceaddress;        /* Source IP for outgoing NNTP connections */
++    char *sourceipv6address;  /* Source IP for outgoing NNTP connections */
+     int usecontrolchan;         /* Use a channel feed for control messages? */
+     int verifycancels;          /* Verify cancels against article author */
+     int wanttrash;              /* Put unwanted articles in junk */
+     int wipcheck;               /* How long to defer other copies of article */
+     int wipexpire;              /* How long to keep pending article record */
++    int listenonipv6;         /* Listen on IPv6 socket */
+     /* Article Storage */
+     long cnfscheckfudgesize;    /* Additional CNFS integrity checking */
+diff -Nur inn-2.3.2.orig/include/sa_len.h inn-2.3.2/include/sa_len.h
+--- inn-2.3.2.orig/include/sa_len.h    Thu Jan  1 01:00:00 1970
++++ inn-2.3.2/include/sa_len.h Tue Jun 19 16:06:41 2001
+@@ -0,0 +1,46 @@
++/* 
++ * sa_len.h : tiny version of SA_LEN 
++ *    (original written by <yoshfuji@ecei.tohoku.ac.jp>)
++ */
++
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <sys/un.h>
++
++#ifndef SIN6_LEN
++#ifndef SA_LEN
++#define SA_LEN(s_)    ap_sa_len((s_)->sa_family)
++
++static int ap_sa_len (int af)
++{
++  switch (af) {
++#if defined(AF_INET)
++  case AF_INET:
++    return (sizeof(struct sockaddr_in));
++#endif /* AF_INET */
++#if defined(INET6)
++  case AF_INET6:
++    return (sizeof(struct sockaddr_in6));
++#endif /* AF_INET6 */
++#if defined(AF_LOCAL)
++  case AF_LOCAL:
++#endif /* AF_LOCAL */
++#if defined(AF_UNIX) && !(AF_UNIX == AF_LOCAL)
++  case AF_UNIX:
++#endif /* AF_UNIX */
++#if defined(AF_FILE) && !(AF_FILE == AF_LOCAL)
++  case AF_FILE:
++#endif /* AF_FILE */
++#if defined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE)
++    return (sizeof(struct sockaddr_un));
++#endif /* fdefined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE) */
++  default:
++    return 0;
++  }
++  return 0;
++}
++
++#endif /* SA_LEN */
++#endif /* SIN6_LEN */
++
+diff -Nur inn-2.3.2.orig/include/sockaddr_storage.h inn-2.3.2/include/sockaddr_storage.h
+--- inn-2.3.2.orig/include/sockaddr_storage.h  Thu Jan  1 01:00:00 1970
++++ inn-2.3.2/include/sockaddr_storage.h       Tue Jun 19 16:06:41 2001
+@@ -0,0 +1,53 @@
++/*
++struct sockaddr_storage
++
++   RFC2553 proposes struct sockaddr_storage.
++   This is a placeholder for all sockaddr-variant structures. This is
++   implemented like follows:
++
++   You should use this structure to hold any of sockaddr-variant
++   structures.
++*/
++#ifndef HAVE_SOCKADDR_STORAGE
++
++struct sockaddr_storage {
++#ifdef HAVE_SOCKADDR_LEN
++        u_char ss_len;
++        u_char ss_family;
++#else
++        u_short ss_family;
++#endif
++        u_char __padding[128 - 2];
++};
++
++/*
++union sockunion
++
++   Alternatively, you may want to implement sockunion.h, with the
++   following content:
++
++   NOTE: For better portability, struct sockaddr_storage should be used.
++   union sockunion is okay, but is not really portable enough.
++*/
++union sockunion {
++        struct sockinet {
++#ifdef HAVE_SOCKADDR_LEN
++                u_char si_len;
++                u_char si_family;
++#else
++                u_short si_family;
++#endif
++                u_short si_port;
++        } su_si;
++        struct sockaddr_in  su_sin;
++#ifdef INET6
++        struct sockaddr_in6 su_sin6;
++#endif
++};
++#ifdef HAVE_SOCKADDR_LEN
++#define su_len          su_si.si_len
++#endif
++#define su_family       su_si.si_family
++#define su_port         su_si.si_port
++
++#endif /* HAVE_SOCKADDR_STORAGE */
+diff -Nur inn-2.3.2.orig/innd/chan.c inn-2.3.2/innd/chan.c
+--- inn-2.3.2.orig/innd/chan.c Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/chan.c      Tue Jun 19 16:06:41 2001
+@@ -36,8 +36,8 @@
+ #define PRIORITISE_REMCONN
+ #ifdef PRIORITISE_REMCONN
+-STATIC int    CHANrcfd;
+-STATIC CHANNEL        *CHANrc;
++STATIC int    CHANrcfd[2];
++STATIC CHANNEL        *CHANrc[2];
+ #endif /* PRIORITISE_REMCONN */
+ /*
+@@ -147,7 +147,7 @@
+     (void)memset((POINTER)CHANtable, 0,
+           (SIZE_T)(CHANtablesize * sizeof *CHANtable));
+     CHANnull.NextLog = innconf->chaninacttime;
+-    CHANnull.Address.s_addr = MyAddress.s_addr;
++    memcpy((POINTER)&CHANnull.Address, (POINTER)&MyAddress, sizeof MyAddress);
+     for (cp = CHANtable; --i >= 0; cp++)
+       *cp = CHANnull;
+ }
+@@ -239,8 +239,13 @@
+ #ifdef PRIORITISE_REMCONN
+     /* Note remconn channel, for efficiency */
+     if (Type == CTremconn) {
+-      CHANrc = cp;
+-      CHANrcfd = fd;
++        if (CHANrc[0] == NULL) {
++          CHANrc[0] = cp;
++          CHANrcfd[0] = fd;
++      } else {
++          CHANrc[1] = cp;
++          CHANrcfd[1] = fd;
++      }
+     }
+ #endif /* PRIORITISE_REMCONN */
+     return cp;
+@@ -261,7 +266,7 @@
+       syslog(L_NOTICE, "%s trace badwrites %d blockwrites %d badreads %d",
+           p, cp->BadWrites, cp->BlockedWrites, cp->BadReads);
+       syslog(L_NOTICE, "%s trace address %s lastactive %ld nextlog %ld",
+-          p, inet_ntoa(cp->Address), cp->LastActive, cp->NextLog);
++          p, Inet_NtoA(&cp->Address), cp->LastActive, cp->NextLog);
+       if (FD_ISSET(cp->fd, &SCHANmask))
+           syslog(L_NOTICE, "%s trace sleeping %ld 0x%x",
+               p, (long)cp->Waketime, cp->Waker);
+@@ -383,7 +388,7 @@
+       break;
+     case CTnntp:
+       (void)sprintf(buff, "%s:%d",
+-              cp->Address.s_addr == 0 ? "localhost" : RChostname(cp),
++              cp->Address.ss_family == 0 ? "localhost" : RChostname(cp),
+               cp->fd);
+       break;
+     case CTlocalconn:
+@@ -922,11 +927,14 @@
+ #ifdef PRIORITISE_REMCONN
+       /* Try the remconn channel next. */
+-      if (FD_ISSET(CHANrcfd, &RCHANmask) && FD_ISSET(CHANrcfd, &MyRead)) {
+-          count--;
+-          if (count > 3) count = 3; /* might be more requests */
+-          (*CHANrc->Reader)(CHANrc);
+-          FD_CLR(CHANrcfd, &MyRead);
++        for (i = 0; i < 2; i++) {
++          if (FD_ISSET(CHANrcfd[i], &RCHANmask) && 
++                FD_ISSET(CHANrcfd[i], &MyRead)) {
++              count--;
++              if (count > 3) count = 3; /* might be more requests */
++              (*CHANrc[i]->Reader)(CHANrc[i]);
++              FD_CLR(CHANrcfd[i], &MyRead);
++          }
+       }
+ #endif /* PRIORITISE_REMCONN */
+diff -Nur inn-2.3.2.orig/innd/innd.c inn-2.3.2/innd/innd.c
+--- inn-2.3.2.orig/innd/innd.c Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/innd.c      Tue Jun 19 16:06:41 2001
+@@ -558,7 +558,7 @@
+ {
+     static char               WHEN[] = "PID file";
+     int                       i;
+-    int                       fd;
++    int                       fd[2];
+     int                       logflags;
+     char              buff[SMBUF];
+     char              *p;
+@@ -599,7 +599,7 @@
+     ShouldRenumber = FALSE;
+     ShouldSyntaxCheck = FALSE;
+     logflags = L_OPENLOG_FLAGS | LOG_NOWAIT;
+-    fd = -1;
++    fd[0] = fd[1] = -1;
+ #if   defined(DO_FAST_RESOLV)
+     /* We only use FQDN's in the hosts.nntp file. */
+@@ -680,10 +680,12 @@
+       case 'p':
+           /* Silently ignore multiple -p flags, in case ctlinnd xexec
+            * called inndstart. */
+-          if (fd == -1) {
+-              fd = atoi(optarg);
++          if (fd[0] == -1) {
++              fd[0] = atoi(optarg);
+               AmRoot = FALSE;
+-          }
++          } else if (fd[1] == -1) {
++              fd[1] = atoi(optarg);
++          }   
+           break;
+       case 'P':
+           innconf->port = atoi(optarg);
+@@ -774,7 +776,7 @@
+       syslog(L_FATAL, "%s internal cant stat control directory %m", LogName);
+       exit(1);
+     }
+-    if (fd != -1 && setgid(NewsGID) < 0)
++    if (fd[0] != -1 && setgid(NewsGID) < 0)
+       syslog(L_ERROR, "%s cant setgid running as %d not %d %m",
+           LogName, (int)getgid(), (int)NewsGID);
+@@ -884,7 +886,11 @@
+     HISsetup();
+     CCsetup();
+     LCsetup();
+-    RCsetup(fd);
++    RCsetup(fd[0]);
++#ifdef INET6
++    if (innconf->listenonipv6 && fd[1] != -1)
++      RCsetup(fd[1]);
++#endif
+     WIPsetup();
+     NCsetup(i);
+     ARTsetup();
+diff -Nur inn-2.3.2.orig/innd/innd.h inn-2.3.2/innd/innd.h
+--- inn-2.3.2.orig/innd/innd.h Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/innd.h      Tue Jun 19 16:06:41 2001
+@@ -51,6 +51,7 @@
+ #include "nntp.h"
+ #include "paths.h"
+ #include "storage.h"
++#include "sockaddr_storage.h"
+ #if     defined(DO_TCL)
+ #include <tcl.h>
+@@ -66,7 +67,7 @@
+ /*
+ **  Some convenient shorthands.
+ */
+-typedef struct in_addr        INADDR;
++typedef struct sockaddr_storage       INADDR;
+ #ifndef u_long
+ #define u_long                unsigned long
+diff -Nur inn-2.3.2.orig/innd/inndstart.c inn-2.3.2/innd/inndstart.c
+--- inn-2.3.2.orig/innd/inndstart.c    Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/inndstart.c Tue Jun 19 16:06:41 2001
+@@ -145,6 +145,12 @@
+     unsigned long       address;
+     int                 s;
+     struct sockaddr_in  server;
++#ifdef INET6
++    int                       s6;
++    struct sockaddr_in6 server6;
++    char              p6flag[SMBUF];
++    int                       in6any;
++#endif
+     int                 i;
+     int                 j;
+     char *              p;
+@@ -299,6 +305,64 @@
+     /* Create a socket and name it.  innconf->bindaddress controls what
+        address we bind as, defaulting to INADDR_ANY. */
++#ifdef INET6
++    in6any = 1;
++    s6 = -1;
++    if (innconf->listenonipv6) {
++      s6 = socket(AF_INET6, SOCK_STREAM, 0);
++      if (s6 < 0) {
++          syslog(L_FATAL, "can't open inet6 socket: %m");
++          exit(1);
++      }
++#ifdef SO_REUSEADDR
++      i = 1;
++      if (setsockopt(s6, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof i) < 0)
++          syslog(L_ERROR, "can't setsockopt: %m");
++#endif
++      memset(&server6, 0, sizeof server6);
++      server6.sin6_port = htons(port);
++      server6.sin6_family = AF_INET6;
++      server6.sin6_addr = in6addr_any;
++      p = innconf->bindipv6address;
++      if (p && !EQ(p, "all") && !EQ(p, "any")) {
++          if (inet_pton(AF_INET6, p, &server6.sin6_addr) < 1) {
++              syslog(L_FATAL, "invalid bindipv6address in inn.conf (%s)", p);
++              exit(1);
++          }
++          in6any = 0;
++      }
++#ifdef HAVE_SOCKADDR_LEN
++      server6.sin6_len = sizeof server6;
++#endif
++      for (i = 1; i < argc; i++) {
++          if (EQn("-6", argv[i], 2)) {
++              if (strlen(argv[i]) > 2) {
++                  p = argv[i] + 2;
++              } else {
++                  i++;
++                  if (argv[i] == NULL) {
++                      syslog(L_FATAL, "missing address after -6");
++                      fprintf(stderr, "Missing address after -6\n");
++                      exit(1);
++                  }
++                  p = argv[i];
++              }
++              if (inet_pton(AF_INET6, p, &server6) < 1) {
++                  syslog(L_FATAL, "invalid ipv6 address %s", p);
++                  fprintf(stderr, "Invalid ipv6 address %s\n", p);
++                  exit(1);
++              }
++              in6any = 0;
++                  }
++      }
++      if (bind(s6, (struct sockaddr *)&server6, sizeof server6) < 0) {
++          syslog(L_FATAL, "can't bind: %m");
++          exit(1);
++      }
++    } 
++    if (!innconf->listenonipv6 || !in6any)
++#endif        /* INET6 */
++    {
+     s = socket(AF_INET, SOCK_STREAM, 0);
+     if (s < 0) {
+         syslog(L_FATAL, "can't open socket: %m");
+@@ -317,6 +381,8 @@
+         syslog(L_FATAL, "can't bind: %m");
+         exit(1);
+     }
++    }
++
+     /* Now, permanently drop privileges. */
+     if (setgid(news_gid) < 0 || getgid() != news_gid) {
+@@ -330,24 +396,47 @@
+     /* Build the argument vector for innd.  Pass -p<port> to innd to tell it
+        what port we just created and bound to for it. */
+-    innd_argv = NEW(char *, 1 + argc + 1);
++#ifdef INET6
++    if (innconf->listenonipv6 && !in6any)
++       innd_argv = NEW(char *, 1 + argc + 2);
++    else
++#endif
++       innd_argv = NEW(char *, 1 + argc + 1);
+     i = 0;
+ #ifdef DEBUGGER
+     innd_argv[i++] = DEBUGGER;
+     innd_argv[i++] = cpcatpath(innconf->pathbin, "innd");
+     innd_argv[i] = 0;
++#ifdef INET6
++    if (innconf->listenonipv6)
++        printf("When starting innd, use -d -p%d [-p%d]\n", s6, s);
++    else
++#endif        /* INET6 */
+     printf("When starting innd, use -dp%d\n", s);
+ #else /* DEBUGGER */
+-    sprintf(pflag, "-p%d", s);
+     innd_argv[i++] = cpcatpath(innconf->pathbin, "innd");
+-    innd_argv[i++] = pflag;
++#ifdef INET6
++    if (innconf->listenonipv6) {
++      sprintf(p6flag, "-p%d", s6);
++      innd_argv[i++] = p6flag;
++    }
++    if (innconf->listenonipv6 && in6any)
++    {
++        sprintf(pflag, "-p-1");
++        innd_argv[i++] = pflag;
++    } else
++#endif
++    {
++        sprintf(pflag, "-p%d", s);
++        innd_argv[i++] = pflag;
++    }
+-    /* Don't pass along -p, -P, or -I.  Check the length of the argument
++    /* Don't pass along -p, -P, -6, or -I.  Check the length of the argument
+        string, and if it's == 2 (meaning there's nothing after the -p or -P
+-       or -I), skip the next argument too, to support leaving a space
++       or -6 or -I), skip the next argument too, to support leaving a space
+        between the argument and the value. */
+     for (j = 1; j < argc; j++) {
+-        if (argv[j][0] == '-' && strchr("pPI", argv[j][1])) {
++        if (argv[j][0] == '-' && strchr("6pPI", argv[j][1])) {
+             if (strlen(argv[j]) == 2) j++;
+             continue;
+         } else {
+diff -Nur inn-2.3.2.orig/innd/lc.c inn-2.3.2/innd/lc.c
+--- inn-2.3.2.orig/innd/lc.c   Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/lc.c        Tue Jun 19 16:06:41 2001
+@@ -39,7 +39,7 @@
+       return;
+     }
+     if ((new = NCcreate(fd, FALSE, TRUE)) != NULL) {
+-      new->Address.s_addr = MyAddress.s_addr;
++      memcpy(&new->Address, &MyAddress, sizeof(MyAddress));
+       syslog(L_NOTICE, "%s connected %d", "localhost", new->fd);
+       NCwritereply(new, (char *)NCgreeting);
+     }
+diff -Nur inn-2.3.2.orig/innd/rc.c inn-2.3.2/innd/rc.c
+--- inn-2.3.2.orig/innd/rc.c   Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/rc.c        Tue Jun 19 16:06:41 2001
+@@ -19,9 +19,6 @@
+ # define INADDR_NONE 0xffffffff
+ #endif
+-#define COPYADDR(dest, src) \
+-          (void)memcpy((POINTER)dest, (POINTER)src, (SIZE_T)sizeof (INADDR))
+-
+ #define TEST_CONFIG(a, b) \
+     { \
+       b = ((peer_params.Keysetbit & (1 << a)) != 0) ? TRUE : FALSE; \
+@@ -66,7 +63,7 @@
+ STATIC char           *RCslaveflag;
+ STATIC char           *RCnnrpd = NULL;
+ STATIC char           *RCnntpd = NULL;
+-STATIC CHANNEL                *RCchan;
++STATIC CHANNEL                *RCchan[2];
+ STATIC REMOTEHOST_DATA        *RCpeerlistfile;
+ STATIC REMOTEHOST     *RCpeerlist;
+ STATIC int            RCnpeerlist;
+@@ -112,6 +109,68 @@
+ STATIC int            remotecount;
+ STATIC int            remotefirst;
++void
++COPYADDR(INADDR *dst, char *src)
++{
++    struct sockaddr_in        sin;
++
++    memset(&sin, 0, sizeof(sin));
++    sin.sin_family = AF_INET;
++#if   defined(HAVE_SOCKADDR_LEN)
++    sin.sin_len = sizeof(sin);
++#endif        /* defined(HAVE_SOCKADDR_LEN) */
++    (void)memcpy((POINTER)&sin.sin_addr, src, sizeof(sin.sin_addr));
++
++    (void)memcpy((POINTER)dst, (POINTER)&sin, sizeof(sin));
++}
++
++BOOL
++RCaddressmatch(INADDR *cp, INADDR *rp)
++{
++#ifdef INET6
++    struct sockaddr_in        *sin_cp, *sin_rp;
++    struct sockaddr_in6       *sin6_cp, *sin6_rp;
++
++    if (cp->ss_family == AF_INET6 && rp->ss_family == AF_INET) {
++      sin6_cp = (struct sockaddr_in6 *)cp;
++      sin_rp = (struct sockaddr_in *)rp;
++      if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr) &&
++          memcmp(&sin6_cp->sin6_addr.s6_addr[12], &sin_rp->sin_addr.s_addr,
++                  sizeof(struct in_addr)) == 0)
++          return TRUE;
++      else
++          return FALSE;
++    } else if (cp->ss_family == AF_INET && rp->ss_family == AF_INET6) {
++      sin_cp = (struct sockaddr_in *)cp;
++      sin6_rp = (struct sockaddr_in6 *)rp;
++      if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr) &&
++          memcmp(&sin6_rp->sin6_addr.s6_addr[12], &sin_cp->sin_addr.s_addr,
++                  sizeof(struct in_addr)) == 0)
++          return TRUE;
++      else
++          return FALSE;
++    }
++#endif /* INET6 */
++    if (cp->ss_family != rp->ss_family)
++      return FALSE;
++
++    switch (cp->ss_family) {
++    case AF_INET:
++      if (((struct sockaddr_in *)cp)->sin_addr.s_addr ==
++          ((struct sockaddr_in *)rp)->sin_addr.s_addr)
++          return TRUE;
++      return FALSE;
++#ifdef INET6
++    case AF_INET6:
++      if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)cp)->sin6_addr,
++                             &((struct sockaddr_in6 *)rp)->sin6_addr))
++          return TRUE;
++      return FALSE;
++#endif        /* INET6 */
++    }
++
++    return FALSE;
++}
+ /*
+  * Split text into comma-separated fields.  Return an allocated
+@@ -168,7 +227,7 @@
+ #endif
+ int
+-RCfix_options(int fd, struct sockaddr_in *remote)
++RCfix_options(int fd, INADDR *remote)
+ {
+ #if IP_OPTIONS
+     unsigned char optbuf[BUFSIZ / 3], *cp;
+@@ -177,10 +236,22 @@
+     int     ipproto;
+     struct protoent *ip;
+-    if ((ip = getprotobyname("ip")) != 0)
+-      ipproto = ip->p_proto;
+-    else
+-      ipproto = IPPROTO_IP;
++    switch (remote->ss_family) {
++    case AF_INET:
++        if ((ip = getprotobyname("ip")) != 0)
++          ipproto = ip->p_proto;
++      else
++          ipproto = IPPROTO_IP;
++      break;
++#if   defined(INET6)
++    case AF_INET6:
++      if ((ip = getprotobyname("ipv6")) != 0)
++          ipproto = ip->p_proto;
++      else
++          ipproto = IPPROTO_IPV6;
++      break;
++#endif        /* defined(INET6) */
++    } 
+     if (getsockopt(fd, ipproto, IP_OPTIONS, (char *) optbuf, &optsize) == 0
+       && optsize != 0) {
+@@ -189,7 +260,7 @@
+           sprintf(lp, " %2.2x", *cp);
+       syslog(LOG_NOTICE,
+              "connect from %s with IP options (ignored):%s",
+-             inet_ntoa(remote->sin_addr), lbuf);
++             Inet_NtoA(remote), lbuf);
+       if (setsockopt(fd, ipproto, IP_OPTIONS, (char *) 0, optsize) != 0) {
+           syslog(LOG_ERR, "setsockopt IP_OPTIONS NULL: %m");
+           return -1;
+@@ -210,17 +281,17 @@
+     register int      i;
+     for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
+-      if (cp->Address.s_addr == rp->Address.s_addr) {
++      if (RCaddressmatch(&cp->Address, &rp->Address)) {
+           if (rp->Password[0] == '\0' || EQ(pass, rp->Password))
+               return TRUE;
+           syslog(L_ERROR, "%s (%s) bad_auth", rp->Label,
+-                 inet_ntoa(cp->Address));
++                 Inet_NtoA(&cp->Address));
+           return FALSE;
+       }
+     if (!AnyIncoming)
+       /* Not found in our table; this can't happen. */
+-      syslog(L_ERROR, "%s not_found", inet_ntoa(cp->Address));
++      syslog(L_ERROR, "%s not_found", Inet_NtoA(&cp->Address));
+     /* Anonymous hosts should not authenticate. */
+     return FALSE;
+@@ -237,7 +308,7 @@
+     register int      i;
+     for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
+-      if (cp->Address.s_addr == rp->Address.s_addr)
++      if (RCaddressmatch(&cp->Address, &rp->Address))
+           if (rp->MaxCnx)
+               return FALSE;
+             else
+@@ -256,7 +327,7 @@
+     register int      i;
+     for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
+-      if (cp->Address.s_addr == rp->Address.s_addr)
++      if (RCaddressmatch(&cp->Address, &rp->Address))
+           return (rp->MaxCnx);
+     /* Not found in our table; this can't happen. */
+     return RemoteLimit;
+@@ -270,7 +341,7 @@
+ RCrejectreader(CHANNEL *cp)
+ {
+     syslog(L_ERROR, "%s internal RCrejectreader (%s)", LogName,
+-         inet_ntoa(cp->Address));
++         Inet_NtoA(&cp->Address));
+ }
+@@ -348,7 +419,7 @@
+ RCreader(CHANNEL *cp)
+ {
+     int                       fd;
+-    struct sockaddr_in        remote;
++    INADDR            remote;
+     ARGTYPE           size;
+     register int      i;
+     register REMOTEHOST       *rp;
+@@ -362,9 +433,9 @@
+     CHANNEL           tempchan;
+     char              buff[SMBUF];
+-    if (cp != RCchan) {
+-      syslog(L_ERROR, "%s internal RCreader wrong channel 0x%x not 0x%x",
+-          LogName, cp, RCchan);
++    if (cp != RCchan[0] && cp != RCchan[1]) {
++      syslog(L_ERROR, "%s internal RCreader wrong channel 0x%x",
++             LogName, cp);
+       return;
+     }
+@@ -425,7 +496,7 @@
+     ** Finally, if neither rejection happened, add the entry to the
+     ** table, and continue on as a normal connect.
+     */
+-    tempchan.Address.s_addr = remote.sin_addr.s_addr;
++    memcpy(&tempchan.Address, &remote, sizeof(remote));
+     reject_message = NULL;
+     if (RemoteTimer != 0) {
+       now = time(NULL);
+@@ -439,7 +510,7 @@
+               i = (i + 1) & (REMOTETABLESIZE - 1);
+               continue;
+           }
+-          if (remotetable[i].Address.s_addr == remote.sin_addr.s_addr)
++          if (RCaddressmatch(&remotetable[i].Address, &remote))
+               found++;
+           i = (i + 1) & (REMOTETABLESIZE - 1);
+       }
+@@ -453,7 +524,7 @@
+       }
+       else {
+           i = (remotefirst + remotecount) & (REMOTETABLESIZE - 1);
+-          remotetable[i].Address = remote.sin_addr;
++          memcpy(&remotetable[i].Address, &remote, sizeof(remote));
+           remotetable[i].Expires = now + RemoteTimer;
+           remotecount++;
+       }
+@@ -466,7 +537,7 @@
+     if (reject_message) {
+       new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
+           RCrejectwritedone);
+-      new->Address.s_addr = remote.sin_addr.s_addr;
++      memcpy(&new->Address, &remote, sizeof(remote));
+       new->Rejected = reject_val;
+       RCHANremove(new);
+       WCHANset(new, reject_message, (int)strlen(reject_message));
+@@ -477,7 +548,7 @@
+     /* See if it's one of our servers. */
+     for (name = NULL, rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
+-      if (rp->Address.s_addr == remote.sin_addr.s_addr) {
++      if (RCaddressmatch(&rp->Address, &remote)) {
+           name = rp->Name;
+           break;
+       }
+@@ -491,7 +562,7 @@
+             new->NoResendId = rp->NoResendId;
+             new->MaxCnx = rp->MaxCnx;
+             new->HoldTime = rp->HoldTime;
+-          new->Address.s_addr = remote.sin_addr.s_addr;
++          memcpy(&new->Address, &remote, sizeof(remote));
+           if (new->MaxCnx > 0 && new->HoldTime == 0) {
+               CHANsetActiveCnx(new);
+               if((new->ActiveCnx > new->MaxCnx) && (new->fd > 0)) {
+@@ -519,7 +590,7 @@
+       reject_message = NNTP_ACCESS;
+         new = CHANcreate(fd, CTreject, CSwritegoodbye, RCrejectreader,
+             RCrejectwritedone);
+-        new->Address.s_addr = remote.sin_addr.s_addr;
++      memcpy(&new->Address, &remote, sizeof(remote));
+         new->Rejected = reject_val;
+         RCHANremove(new);
+         WCHANset(new, reject_message, (int)strlen(reject_message));
+@@ -529,9 +600,9 @@
+     }
+     if (new != NULL) {
+-      new->Address.s_addr = remote.sin_addr.s_addr;
++      memcpy(&new->Address, &remote, sizeof(remote));
+       syslog(L_NOTICE, "%s connected %d streaming %s",
+-           name ? name : inet_ntoa(new->Address), new->fd,
++           name ? name : Inet_NtoA(&new->Address), new->fd,
+            (!StreamingOff && new->Streaming) ? "allowed" : "not allowed");
+     }
+ }
+@@ -681,7 +752,9 @@
+     register REMOTEHOST               peer_params;
+     register REMOTEHOST               default_params;
+     BOOL                      flag, bit, toolong;
+-
++#if   defined(HAVE_GETADDRINFO)
++    struct addrinfo           hints, *res, *res0;
++#endif        /* defined(HAVE_GETADDRINFO) */
+  
+     *RCbuff = '\0';
+     if (*list) {
+@@ -880,9 +953,51 @@
+           RENEW (*list, REMOTEHOST, *count);
+           rp = *list + j;
++#if   defined(HAVE_GETADDRINFO)
++          (void)memset((POINTER)&hints, 0, sizeof hints);
++          hints.ai_family = PF_UNSPEC;
++          hints.ai_socktype = SOCK_STREAM;
++          if (getaddrinfo(*q, NULL, &hints, &res0) != 0) {
++            syslog(L_ERROR, "%s cant getaddrinfo %s %m", LogName, *q);
++            /* decrement *count, since we never got to add this record. */
++            (*count)--;
++            continue;
++          }
++          /* Count the addresses and see if we have to grow the list */
++          i = 0;
++          for (res = res0; res != NULL; res = res->ai_next)
++            i++;
++          /* Grow the array */
++          j = rp - *list;
++          *count += i - 1;
++          RENEW(*list, REMOTEHOST, *count);
++          rp = *list + j;
++
++          /* Add all hosts */
++          for (res = res0; res != NULL; res = res->ai_next) {
++            (void)memcpy(&rp->Address, res->ai_addr, res->ai_addrlen);
++            rp->Name = COPY (*q);
++            rp->Label = COPY (peer_params.Label);
++            rp->Email = COPY(peer_params.Email);
++            rp->Comment = COPY(peer_params.Comment);
++            rp->Streaming = peer_params.Streaming;
++            rp->Skip = peer_params.Skip;
++            rp->NoResendId = peer_params.NoResendId;
++            rp->Password = COPY(peer_params.Password);
++            rp->Patterns = peer_params.Pattern != NULL ?
++              RCCommaSplit(COPY(peer_params.Pattern)) : NULL;
++            rp->MaxCnx = peer_params.MaxCnx;
++            rp->HoldTime = peer_params.HoldTime;
++            rp++;
++          }
++          freeaddrinfo(res0);
++#else /* defined(HAVE_GETADDRINFO) */
+           /* Was host specified as a dotted quad ? */
+-          if ((rp->Address.s_addr = inet_addr(*q)) != INADDR_NONE) {
++          if (inet_addr(*q) != INADDR_NONE) {
++            u_long    addr;
+             /* syslog(LOG_NOTICE, "think it's a dotquad: %s", *q); */
++            addr = inet_addr(*q);
++            COPYADDR(&rp->Address, (char *)&addr);
+             rp->Name = COPY (*q);
+             rp->Label = COPY (peer_params.Label);
+             rp->Password = COPY(peer_params.Password);
+@@ -920,7 +1035,9 @@
+             int    t = 0;
+             /* Strange DNS ? try this.. */
+             for (r = hp->h_aliases; *r != 0; r++) {
+-              if (inet_addr(*r) == INADDR_NONE) /* IP address ? */
++              u_long  addr;
++              addr = inet_addr(*r);
++              if (addr == INADDR_NONE) /* IP address ? */
+                 continue;
+               (*count)++;
+               /* Grow the array */
+@@ -928,7 +1045,7 @@
+               RENEW (*list, REMOTEHOST, *count);
+               rp = *list + j;
+-              rp->Address.s_addr = inet_addr(*r);
++              COPYADDR(&rp->Address, (char *)&addr);
+               rp->Name = COPY (*q);
+               rp->Label = COPY (peer_params.Label);
+               rp->Email = COPY(peer_params.Email);
+@@ -1003,6 +1120,7 @@
+           rp->HoldTime = peer_params.HoldTime;
+           rp++;
+ #endif            /* defined(h_addr) */
++#endif            /* defined(HAVE_GETADDRINFO) */
+         }
+         DISPOSE(r[0]);
+         DISPOSE(r);
+@@ -1496,9 +1614,9 @@
+     register int      i;
+     for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++)
+-      if (cp->Address.s_addr == rp->Address.s_addr)
++      if (RCaddressmatch(&cp->Address, &rp->Address))
+           return rp->Name;
+-    (void)strcpy(buff, inet_ntoa(cp->Address));
++    (void)strcpy(buff, Inet_NtoA(&cp->Address));
+     return buff;
+ }
+@@ -1511,7 +1629,7 @@
+     int               i;
+     for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
+-      if (cp->Address.s_addr == rp->Address.s_addr)
++      if (RCaddressmatch(&cp->Address, &rp->Address))
+           return rp->Label;
+     }
+     return NULL;
+@@ -1530,7 +1648,7 @@
+     int                       i;
+     for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
+-      if (cp->Address.s_addr != rp->Address.s_addr)
++      if (RCaddressmatch(&cp->Address, &rp->Address))
+           continue;
+       if (rp->Patterns == NULL)
+           break;
+@@ -1559,12 +1677,53 @@
+     register int      i;
+ {
+     struct sockaddr_in        server;
++#if   defined(INET6)
++    struct sockaddr_in6 server6;
++#endif        /* defined(INET6) */
+ #if   defined(SO_REUSEADDR)
+     int                       on;
+ #endif        /* defined(SO_REUSEADDR) */
++    int                       idx;
+     if (i < 0) {
+       /* Create a socket and name it. */
++#if   defined(INET6)
++      if (RCchan[0] != NULL && innconf->listenonipv6) {
++          if ((i = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
++              syslog(L_FATAL, "%s cant ipv6 socket RCreader %m", LogName);
++              exit(1);
++          }
++#if   defined(SO_REUSEADDR)
++          on = 1;
++          if (setsockopt(i, SOL_SOCKET, SO_REUSEADDR, (caddr_t)&on,
++                         sizeof on) < 0)
++              syslog(L_ERROR, "%s cant setsockopt RCreader %m", LogName);
++#endif        /* defined(SO_REUSEADDR) */
++          (void)memset((POINTER)&server6, 0, sizeof server6);
++          server6.sin6_port = htons(innconf->port);
++          server6.sin6_family = AF_INET6;
++          server6.sin6_addr = in6addr_any;
++#if   defined(HAVE_SOCKADDR_LEN)
++          server6.sin6_len = sizeof server6;
++#endif        /* defined(HAVE_SOCKADDR_LEN) */
++          if (innconf->bindipv6address) {
++              if (inet_pton(AF_INET6, innconf->bindipv6address, 
++                            &server6.sin6_addr) < 1) {
++                  syslog(L_FATAL, "unable to determine bind ipv6 (%s) %m",
++                         innconf->bindipv6address);
++                  exit(1);
++              }
++          }
++          if (bind(i, (struct sockaddr *)&server6, sizeof server6) < 0) {
++              syslog(L_FATAL, "%s cant bind RCreader %m", LogName);
++              exit(1);
++          }
++      } else if (RCchan[0] != NULL) {
++          /* If "listenonipv6" not set, and one socket has already been 
++               created, no need to create more socket */
++          return;
++      }
++#endif        /* defined(INET6) */ 
+       if ((i = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+           syslog(L_FATAL, "%s cant socket RCreader %m", LogName);
+           exit(1);
+@@ -1599,9 +1758,15 @@
+       syslog(L_FATAL, "%s cant listen RCreader %m", LogName);
+       exit(1);
+     }
+-    RCchan = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
+-    syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(RCchan));
+-    RCHANadd(RCchan);
++
++    if (RCchan[0] == NULL) 
++        idx = 0;
++    else
++      idx = 1;
++    RCchan[idx] = CHANcreate(i, CTremconn, CSwaiting, RCreader, RCwritedone);
++
++    syslog(L_NOTICE, "%s rcsetup %s", LogName, CHANname(RCchan[idx]));
++    RCHANadd(RCchan[idx]);
+     /* Get the list of hosts we handle. */
+     RCreadlist();
+@@ -1617,8 +1782,11 @@
+     register REMOTEHOST       *rp;
+     register int      i;
+-    CHANclose(RCchan, CHANname(RCchan));
+-    RCchan = NULL;
++    for (i = 0; i < 2; i++)
++        if (RCchan[i] != NULL) {
++            CHANclose(RCchan[i], CHANname(RCchan[i]));
++            RCchan[i] = NULL;
++        }
+     if (RCpeerlist) {
+       for (rp = RCpeerlist, i = RCnpeerlist; --i >= 0; rp++) {
+           DISPOSE(rp->Name);
+diff -Nur inn-2.3.2.orig/innd/status.c inn-2.3.2/innd/status.c
+--- inn-2.3.2.orig/innd/status.c       Thu May  3 22:27:32 2001
++++ inn-2.3.2/innd/status.c    Tue Jun 19 16:06:41 2001
+@@ -16,7 +16,7 @@
+ typedef struct _STATUS {
+     char           name[SMBUF];
+-    char           ip_addr[15];
++    char           ip_addr[64];
+     BOOL           can_stream;
+     unsigned short activeCxn;
+     unsigned short sleepingCxns;
+@@ -134,7 +134,8 @@
+   tmp = head = NULL;
+   for (i = 0; (cp = CHANiter(&i, CTnntp)) != NULL; ) {
+     j = 0;
+-    strcpy(TempString, cp->Address.s_addr == 0 ? "localhost" : RChostname(cp));
++    strcpy(TempString, cp->Address.ss_family == 0 ? "localhost" : 
++         RChostname(cp));
+     for (status = head ; status != NULL ; status = status->next) {
+       if (strcmp(TempString, status->name) == 0)
+           break;
+@@ -143,7 +144,7 @@
+       status = NEW(STATUS, 1);
+       peers++;                                              /* a new peer */
+       strcpy (status->name, TempString);                         /* name */
+-      strcpy (status->ip_addr, inet_ntoa(cp->Address));    /* ip address */
++      strcpy (status->ip_addr, Inet_NtoA(&cp->Address));    /* ip address */
+       status->can_stream = cp->Streaming;
+       status->seconds = status->Size = status->DuplicateSize = 0;
+       status->Ihave = status->Ihave_Duplicate =
+diff -Nur inn-2.3.2.orig/innfeed/connection.c inn-2.3.2/innfeed/connection.c
+--- inn-2.3.2.orig/innfeed/connection.c        Thu May  3 22:27:32 2001
++++ inn-2.3.2/innfeed/connection.c     Tue Jun 19 16:06:41 2001
+@@ -131,6 +131,12 @@
+ #include "host.h"
+ #include "msgs.h"
++#ifndef       HAVE_SOCKADDR_STORAGE
++#include "sockaddr_storage.h"
++#endif
++
++#include "sa_len.h"
++
+ #if defined (NDEBUG)
+ #define VALIDATE_CONNECTION(x) ((void) 0)
+ #else
+@@ -263,7 +269,8 @@
+ static u_int gCxnCount = 0 ;
+ static u_int max_reconnect_period = MAX_RECON_PER ;
+ static u_int init_reconnect_period = INIT_RECON_PER ;
+-static u_long bind_addr = INADDR_ANY;
++static struct sockaddr_storage bind_addr;
++static int bind_addr_flag = 0;
+ #if 0
+ static bool inited = false ;
+ #endif
+@@ -406,17 +413,33 @@
+     iv = INIT_RECON_PER ;
+   init_reconnect_period = (u_int) iv ;
++  memset (&bind_addr, 0, sizeof(bind_addr));
+   if (getString (topScope,"bindaddress",&sv,NO_INHERIT))
+     {
+-      bind_addr = inet_addr(sv);
+-      if (bind_addr == INADDR_NONE)
+-      {
++      if (inet_addr(sv) != INADDR_NONE) {
++      bind_addr.ss_family = AF_INET;
++      ((struct sockaddr_in *)&bind_addr)->sin_addr.s_addr = inet_addr(sv);
++#ifdef HAVE_SOCKADDR_LEN
++      bind_addr.ss_len = sizeof(struct sockaddr_in);
++#endif
++      bind_addr_flag = 1;
++      }
++#ifdef INET6
++      else if (inet_pton(AF_INET6, sv, 
++             &((struct sockaddr_in6 *)&bind_addr)->sin6_addr) == 1) {
++      bind_addr.ss_family = AF_INET6;
++#ifdef HAVE_SOCKADDR_LEN
++      bind_addr.ss_len = sizeof(struct sockaddr_in6);
++#endif
++      bind_addr_flag = 1;
++      }
++#endif        /* INET6 */
++      else {
+         logOrPrint (LOG_ERR,fp,"innfeed unable to determine bind ip") ;
+-        bind_addr = INADDR_ANY;
++        bind_addr_flag = 0;
+       }
+-    }
+-  else
+-    bind_addr = INADDR_ANY;
++    } else
++    bind_addr_flag = 0;
+   return rval ;
+ }
+@@ -533,9 +556,9 @@
+  */
+ bool cxnConnect (Connection cxn)
+ {
+-  struct sockaddr_in cxnAddr, cxnSelf ;
++  struct sockaddr_storage cxnAddr, cxnSelf ;
+   int fd, rval ;
+-  struct in_addr *addr = NULL;
++  struct sockaddr_storage *addr = NULL;
+   const char *peerName = hostPeerName (cxn->myHost) ;
+   ASSERT (cxn->myEp == NULL) ;
+@@ -566,12 +589,15 @@
+       return false ;
+     }
+-  memset (&cxnAddr, 0, sizeof (cxnAddr)) ;
+-  cxnAddr.sin_family = AF_INET ;
+-  cxnAddr.sin_port = htons(cxn->port) ;
+-  cxnAddr.sin_addr.s_addr = addr->s_addr ;
++  memcpy (&cxnAddr, addr, sizeof(cxnAddr));
++  if (cxnAddr.ss_family == AF_INET) 
++    ((struct sockaddr_in *)&cxnAddr)->sin_port = htons(cxn->port);
++#ifdef INET6
++  else if (cxnAddr.ss_family == AF_INET6)
++    ((struct sockaddr_in6 *)&cxnAddr)->sin6_port = htons(cxn->port);
++#endif
+-  if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
++  if ((fd = socket (cxnAddr.ss_family, SOCK_STREAM, 0)) < 0)
+     {
+       syslog (LOG_ERR, SOCKET_CREATE_ERROR, peerName, cxn->ident) ;
+       d_printf (1,"Can't get a socket: %m\n") ;
+@@ -582,13 +608,15 @@
+     }
+   /* bind to a specified virtual host */
+-  if (bind_addr != INADDR_ANY)
++  if (bind_addr_flag == 1) 
+     {
+-      memset (&cxnSelf, 0, sizeof (cxnSelf)) ;
+-      cxnSelf.sin_family = AF_INET ;
+-      cxnSelf.sin_port = 0 ;
+-      cxnSelf.sin_addr.s_addr = bind_addr;
+-      if (bind (fd, (struct sockaddr *) &cxnSelf,sizeof (cxnSelf)) < 0)
++      (void)memcpy (&cxnSelf, &bind_addr, sizeof(cxnSelf));
++#ifdef HAVE_SOCKADDR_LEN
++      if (bind (fd, (struct sockaddr *) &cxnSelf, cxnSelf.ss_len) < 0)
++#else
++      if (bind (fd, (struct sockaddr *) &cxnSelf, 
++              SA_LEN((struct sockaddr *) &cxnSelf)) < 0)
++#endif
+       {
+         syslog (LOG_ERR,"bind: %m") ;
+@@ -620,7 +648,12 @@
+       return false ;
+     }
+-  rval = connect (fd, (struct sockaddr *) &cxnAddr, sizeof (cxnAddr)) ;
++#ifdef HAVE_SOCKADDR_LEN
++  rval = connect (fd, (struct sockaddr *) &cxnAddr, cxnAddr.ss_len);
++#else
++  rval = connect (fd, (struct sockaddr *) &cxnAddr, 
++                SA_LEN((struct sockaddr *) &cxnAddr));
++#endif
+   if (rval < 0 && errno != EINPROGRESS)
+     {
+       syslog (LOG_ERR, CONNECT_ERROR, peerName, cxn->ident) ;
+diff -Nur inn-2.3.2.orig/innfeed/endpoint.c inn-2.3.2/innfeed/endpoint.c
+--- inn-2.3.2.orig/innfeed/endpoint.c  Thu May  3 22:27:32 2001
++++ inn-2.3.2/innfeed/endpoint.c       Tue Jun 19 16:06:41 2001
+@@ -1628,6 +1628,11 @@
+   EndPoint accConn ;
+   struct sockaddr_in accNet ;
+   int accFd = socket (AF_INET,SOCK_STREAM,0) ;
++#ifdef INET6
++  EndPoint accConn6;
++  struct sockaddr_in6 accNet6;
++  int accFd6 = socket (AF_INET6,SOCK_STREAM,0);
++#endif
+   u_short port = atoi (argc > 1 ? argv[1] : "10000") ;
+   time_t t = theTime() ;
+@@ -1663,6 +1668,26 @@
+   accConn = newEndPoint (accFd) ;
+   prepareRead (accConn,NULL,newConn,NULL,0) ;
++
++#ifdef INET6
++  ASSERT(accFd6 >= 0);
++  memset (&accNet6,0,sizeof (accNet6));
++  accNet6.sin6_family = AF_INET6;
++  accNet6.sin6_addr = in6addr_any;
++  accNet6.sin6_port = htons (port);
++
++  if (bind (accFd6, (struct sockaddr_in6 *) &accNet6, sizeof (accNet6)) < 0)
++    {
++      perror ("bind: %m") ;
++      exit (1) ;
++    }
++  
++  listen (accFd6,5);
++
++  accCon6 = newEndPoint (accFd6);
++
++  prepareRead (accCon6,NULL,newConn,NULL,0) ;
++#endif
+   prepareSleep (Timeout,5,(void *) 0x10) ;
+diff -Nur inn-2.3.2.orig/innfeed/host.c inn-2.3.2/innfeed/host.c
+--- inn-2.3.2.orig/innfeed/host.c      Thu May  3 22:27:32 2001
++++ inn-2.3.2/innfeed/host.c   Tue Jun 19 16:06:41 2001
+@@ -40,6 +40,8 @@
+ #include "config.h"
+ #include "clibrary.h"
++#include <sys/types.h>
++#include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <assert.h>
+@@ -67,6 +69,10 @@
+ #include "msgs.h"
+ #include "tape.h"
++#ifndef HAVE_SOCKADDR_STORAGE
++#include "sockaddr_storage.h"
++#endif
++
+ #define REQ 1
+ #define NOTREQ 0
+ #define NOTREQNOADD 2
+@@ -1128,22 +1134,63 @@
+   return nh ;
+ }
+-struct in_addr *hostIpAddr (Host host)
++struct sockaddr_storage *hostIpAddr (Host host)
+ {
+   int i ;
+   char *p ;
+   char **newIpAddrs = NULL;
+-  struct in_addr ipAddr, *returnAddr ;
++  struct sockaddr_storage ipAddr, *returnAddr;
+   struct hostent *hostEnt ;
++#ifdef HAVE_GETADDRINFO
++  struct addrinfo hints, *res, *pr;
++#endif
+   char *msgstr[SMBUF] ;
+   ASSERT(host->params != NULL);
++  returnAddr = NULL;
+   /* check to see if need to look up the host name */
+   if (host->nextIpLookup <= theTime())
+     {
++#ifdef HAVE_GETADDRINFO
++      memset(&hints, 0, sizeof(hints));
++      hints.ai_family = PF_UNSPEC;
++      hints.ai_socktype = SOCK_STREAM;
++      i = getaddrinfo(host->params->ipName, NULL, &hints, &res);
++      if (i != 0)
++      {
++        syslog (LOG_ERR, HOST_RESOLV_ERROR, host->params->peerName,
++                host->params->ipName, gai_strerror(i));
++      }
++      else
++      {
++        /* figure number of pointers that need space */
++        i = 0;
++        for (pr = res; pr != NULL; pr = pr->ai_next, i++)
++          ;
++        i++;
++        
++        newIpAddrs = 
++          (char **) MALLOC ( (i * sizeof(char *)) +
++                             ( (i - 1) * sizeof(struct sockaddr_storage)) ) ;
++        ASSERT (newIpAddrs != NULL) ;
++
++        p = (char *)&newIpAddrs [ i ] ;
++        i = 0;
++        for (pr = res; pr != NULL; pr = pr->ai_next) 
++          {
++            newIpAddrs[i] = p;
++            memcpy (p, pr->ai_addr, pr->ai_addrlen);
++            p += sizeof(struct sockaddr_storage);
++            i++;
++          }
++        newIpAddrs[i] = NULL;
++        freeaddrinfo(res);
++      }
++#else
+       /* see if the ipName we're given is a dotted quad */
+-      if ( !inet_aton (host->params->ipName,&ipAddr) )
++      if ( !inet_aton (host->params->ipName,
++                     &((struct sockaddr_in *)&ipAddr)->sin_addr) )
+       {
+         if ((hostEnt = gethostbyname (host->params->ipName)) == NULL)
+           {
+@@ -1159,7 +1206,8 @@
+             newIpAddrs =
+               (char **) MALLOC ( (i * sizeof(char *)) +
+-                                ( (i - 1) * hostEnt->h_length) ) ;
++                                 ( (i - 1) * 
++                                   sizeof(struct sockaddr_storage) ) );
+             ASSERT (newIpAddrs != NULL) ;
+             /* copy the addresses from gethostbyname() static space */
+@@ -1168,7 +1216,13 @@
+             for (i = 0 ; hostEnt->h_addr_list[i] ; i++)
+               {
+                 newIpAddrs[i] = p;
+-                memcpy (p, hostEnt->h_addr_list[i], hostEnt->h_length) ;
++                memcpy (&((struct sockaddr_in *)p)->sin_addr, 
++                        hostEnt->h_addr_list[i], hostEnt->h_length) ;
++                ((struct sockaddr_in *)p)->sin_family = AF_INET;
++#ifdef HAVE_SOCKADDR_LEN
++                ((struct sockaddr_in *)p)->sin_len = 
++                  sizeof(struct sockaddr_in);
++#endif
+                 p += hostEnt->h_length ;
+               }
+             newIpAddrs[i] = NULL ;
+@@ -1181,9 +1235,13 @@
+         p = (char *)&newIpAddrs [ 2 ];
+         newIpAddrs[0] = p;
+         memcpy (p, (char *)&ipAddr, sizeof(ipAddr)) ;
++        ((struct sockaddr_in *)p)->sin_family = AF_INET;
++#ifdef HAVE_SOCKADDR_LEN
++        ((struct sockaddr_in *)p)->sin_len = sizeof(struct sockaddr_in);
++#endif
+         newIpAddrs[1] = NULL;
+       }
+-
++#endif        /* HAVE_GETADDRINFO */
+       if (newIpAddrs)
+       {
+         if (host->ipAddrs)
+@@ -1201,7 +1259,7 @@
+   if (host->ipAddrs)
+     {
+-      returnAddr = (struct in_addr *)(host->nextIpAddr[0]) ;
++      returnAddr = (struct sockaddr_storage *)(host->nextIpAddr[0]) ;
+       if (*(++host->nextIpAddr) == NULL)
+       host->nextIpAddr = host->ipAddrs ;
+     }
+diff -Nur inn-2.3.2.orig/innfeed/host.h inn-2.3.2/innfeed/host.h
+--- inn-2.3.2.orig/innfeed/host.h      Thu May  3 22:27:32 2001
++++ inn-2.3.2/innfeed/host.h   Tue Jun 19 16:06:41 2001
+@@ -105,7 +105,7 @@
+ void hostSendArticle (Host host, Article article) ;
+ /* return an IP address for the host */
+-struct in_addr *hostIpAddr (Host host) ;
++struct sockaddr_storage *hostIpAddr (Host host) ;
+ /*
+  * Functions used by the Connection to indicate Connection state.
+diff -Nur inn-2.3.2.orig/lib/Makefile inn-2.3.2/lib/Makefile
+--- inn-2.3.2.orig/lib/Makefile        Thu May  3 22:27:32 2001
++++ inn-2.3.2/lib/Makefile     Tue Jun 19 16:06:41 2001
+@@ -16,7 +16,7 @@
+       md5.c nonblocking.c parsedate.c perl.c qio.c radix32.c readin.c \
+       remopen.c reservedfd.c resource.c rwlock.c sendarticle.c \
+       sendpass.c tempname.c waitnb.c wildmat.c version.c xfopena.c \
+-      xmalloc.c xsignal.c xwrite.c xwritev.c
++      xmalloc.c xsignal.c xwrite.c xwritev.c inet_ntoa.c
+ OBJECTS = $(MISSING_OBJ) \
+       argparse.o checkart.o cleanfrom.o clientactive.o clientlib.o \
+@@ -26,7 +26,7 @@
+       md5.o nonblocking.o parsedate.o qio.o radix32.o readin.o \
+       remopen.o reservedfd.o resource.o rwlock.o sendarticle.o \
+       sendpass.o tempname.o waitnb.o wildmat.o version.o xfopena.o \
+-      xmalloc.o xsignal.o xwrite.o xwritev.o
++      xmalloc.o xsignal.o xwrite.o xwritev.o inet_ntoa.o
+ LOBJECTS= $(OBJECTS:.o=.lo)
+diff -Nur inn-2.3.2.orig/lib/getconfig.c inn-2.3.2/lib/getconfig.c
+--- inn-2.3.2.orig/lib/getconfig.c     Thu May  3 22:27:32 2001
++++ inn-2.3.2/lib/getconfig.c  Tue Jun 19 16:06:41 2001
+@@ -267,6 +267,9 @@
+     innconf->groupbaseexpiry = TRUE;
+     innconf->wipcheck = 5;
+     innconf->wipexpire = 10;
++    innconf->listenonipv6 = FALSE;
++    innconf->bindipv6address = NULL;
++    innconf->sourceipv6address = NULL;
+ }
+ void ClearInnConf()
+@@ -304,6 +307,9 @@
+     if (innconf->backoff_db != NULL) DISPOSE(innconf->backoff_db);
+     if (innconf->ovmethod != NULL) DISPOSE(innconf->ovmethod);
+     if (innconf->ovgrouppat != NULL) DISPOSE(innconf->ovgrouppat);
++    if (innconf->bindipv6address != NULL) DISPOSE(innconf->bindipv6address);
++    if (innconf->sourceipv6address != NULL) DISPOSE(innconf->sourceipv6address);
++
+     memset(ConfigBit, '\0', ConfigBitsize);
+ }
+@@ -981,6 +987,21 @@
+               TEST_CONFIG(CONF_VAR_WIPEXPIRE, bit);
+               if (!bit) innconf->wipexpire = atoi(p);
+               SET_CONFIG(CONF_VAR_WIPEXPIRE);
++          } else
++          if (EQ(ConfigBuff, _CONF_LISTENONIPV6)) {
++              TEST_CONFIG(CONF_VAR_LISTENONIPV6, bit);
++              if (!bit && boolval != -1) innconf->listenonipv6 = boolval;
++              SET_CONFIG(CONF_VAR_LISTENONIPV6);
++          } else
++          if (EQ(ConfigBuff, _CONF_BINDIPV6ADDRESS)) {
++              TEST_CONFIG(CONF_VAR_BINDIPV6ADDRESS, bit);
++              if (!bit) innconf->bindipv6address = COPY(p);
++              SET_CONFIG(CONF_VAR_BINDIPV6ADDRESS);
++          } else
++          if (EQ(ConfigBuff, _CONF_SOURCEIPV6ADDRESS)) {
++              TEST_CONFIG(CONF_VAR_SOURCEIPV6ADDRESS, bit);
++              if (!bit) innconf->sourceipv6address = COPY(p);
++              SET_CONFIG(CONF_VAR_SOURCEIPV6ADDRESS);
+           }
+       }
+       (void)Fclose(F);
+diff -Nur inn-2.3.2.orig/lib/inet_ntoa.c inn-2.3.2/lib/inet_ntoa.c
+--- inn-2.3.2.orig/lib/inet_ntoa.c     Thu May  3 22:27:32 2001
++++ inn-2.3.2/lib/inet_ntoa.c  Tue Jun 19 16:06:41 2001
+@@ -5,9 +5,17 @@
+ */
+ #include <stdio.h>
+ #include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <arpa/inet.h>
++#include <netdb.h>
+ #include "configdata.h"
+ #include "clibrary.h"
++#include "sockaddr_storage.h"
++#if   !defined(HAVE_SOCKADDR_LEN)
++#include "sa_len.h"
++#endif
+ /*
+  * Copyright (c) 1983 Regents of the University of California.
+@@ -40,7 +48,7 @@
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+- */
++ /
+ #if defined(LIBC_SCCS) && !defined(lint)
+ static char sccsid[] = "@(#)inet_ntoa.c       5.6 (Berkeley) 2/24/91";
+@@ -50,16 +58,45 @@
+  * Convert network-format internet address
+  * to base 256 d.d.d.d representation.
+  */
+-#include <netinet/in.h>
+ #define       UC(c)   (((int)c) & 0xFF)
+-char *inet_ntoa(struct in_addr in)
++char *Inet_NtoA(struct sockaddr_storage *ss)
+ {
++#if !defined(INET6)
++#if defined(HAVE_INET_NTOA)
++    return inet_ntoa(((struct sockaddr_in *)ss)->sin_addr);
++#else
+     static char               buff[18];
+     char              *p;
+     p = (char *)&in;
+     (void)sprintf(buff, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
+     return buff;
++#endif /* HAVE_INET_NTOA */
++#else /* INET6 */
++    static char               buff[256];
++    struct sockaddr_in sin;
++    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss;
++
++    if (ss->ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
++      memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
++              sizeof(sin.sin_addr));
++      sin.sin_port = ((struct sockaddr_in6 *)ss)->sin6_port;
++      sin.sin_family = AF_INET;
++#if defined(HAVE_SOCKADDR_LEN)
++      sin.sin_len = sizeof(struct sockaddr_in);
++#endif
++      return inet_ntoa(sin.sin_addr);
++    }
++#if defined(HAVE_SOCKADDR_LEN)
++    getnameinfo((struct sockaddr *)ss, ss->ss_len, buff, sizeof(buff), NULL, 0,
++                NI_NUMERICHOST);
++#else
++    getnameinfo((struct sockaddr *)ss, SA_LEN((struct sockaddr *)ss), buff,
++              sizeof(buff), NULL, 0, NI_NUMERICHOST);
++#endif /* HAVE_SOCKADDR_IN */
++
++    return buff;
++#endif /* INET6 */
+ }
+diff -Nur inn-2.3.2.orig/lib/remopen.c inn-2.3.2/lib/remopen.c
+--- inn-2.3.2.orig/lib/remopen.c       Thu May  3 22:27:32 2001
++++ inn-2.3.2/lib/remopen.c    Tue Jun 19 16:06:41 2001
+@@ -40,13 +40,69 @@
+     int               j;
+     int                       oerrno;
+     FILE              *F;
++#if   defined(HAVE_GETADDRINFO)
++    struct addrinfo   hints, *res, *addr;
++    char              portbuf[16];
++    struct sockaddr_storage   client;
++#else
+     struct hostent    *hp;
+     struct hostent    fakehp;
+     struct in_addr    quadaddr;
+     struct sockaddr_in        server, client;
++#endif        /* defined(HAVE_GETADDRINFO) */
+     buff = errbuff ? errbuff : mybuff;
+     *buff = '\0';
++
++#if   defined(HAVE_GETADDRINFO)
++    (void)memset((POINTER)&hints, 0, sizeof hints);
++    hints.ai_family = PF_UNSPEC;
++    hints.ai_socktype = SOCK_STREAM;
++    sprintf(portbuf, "%d", port);
++    if (getaddrinfo(host, portbuf, &hints, &res) != 0)
++      return -1;
++
++    for (addr = res; addr; addr = addr->ai_next) {
++        /* Make a socket and try to connect */
++      if ((i = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
++          break;
++      (void)memset((POINTER)&client, 0, sizeof client);
++      if (addr->ai_family == AF_INET) {
++          if (innconf->sourceaddress &&
++              inet_pton(AF_INET, innconf->sourceaddress, 
++                        &((struct sockaddr_in *)&client)->sin_addr) < 1) {
++              freeaddrinfo(addr);
++              return -1;
++          }
++          ((struct sockaddr_in *)&client)->sin_family = AF_INET;
++      }
++#if   defined(INET6)
++      if (addr->ai_family == AF_INET6) {
++          if (innconf->sourceipv6address &&
++              inet_pton(AF_INET6, innconf->sourceipv6address,
++                        &((struct sockaddr_in6 *)&client)->sin6_addr) < 1) {
++              freeaddrinfo(addr);
++              return -1;
++          }
++          ((struct sockaddr_in6 *)&client)->sin6_family = AF_INET6;
++      }
++#endif        /* defined(INET6) */
++      /* Bind to the source address we want. */
++      if (bind(i, (struct sockaddr *)&client, addr->ai_addrlen) < 0) {
++          oerrno = errno;
++          (void)close(i);
++          errno = oerrno;
++          continue;
++      }
++      if (connect(i, addr->ai_addr, addr->ai_addrlen) < 0) {
++          oerrno = errno;
++          (void)close(i);
++          errno = oerrno;
++          continue;
++      }
++
++#else /* HAVE_GETADDRINFO */
++
+     quadaddr.s_addr = inet_addr(host);
+     if (quadaddr.s_addr != (unsigned int) -1) {
+       /* Host was specified as a dotted-quad internet address.  Fill in
+@@ -111,6 +167,7 @@
+           errno = oerrno;
+           continue;
+       }
++#endif        /* defined(HAVE_GETADDRINFO) */
+       /* Connected -- now make sure we can post. */
+       if ((F = fdopen(i, "r")) == NULL) {
+diff -Nur inn-2.3.2.orig/nnrpd/commands.c inn-2.3.2/nnrpd/commands.c
+--- inn-2.3.2.orig/nnrpd/commands.c    Thu May  3 22:27:32 2001
++++ inn-2.3.2/nnrpd/commands.c Tue Jun 19 16:06:41 2001
+@@ -184,7 +184,22 @@
+     /*syslog(L_NOTICE, "%s (%ld) returned: %d %s %d\n", av[0], (long) pid, i, path, status);*/
+     /* Split "host:permissions:user:pass:groups" into fields. */
+-    for (fields[0] = path, i = 0, p = path; *p; p++)
++    /* "host" field for IPv6 address must be enclosed with "[" and "]" */
++    if (path[0] == '[') {
++      fields[0] = path + 1;
++      i = 0;
++      p = path + 1;
++      while (*p && *p != ']')
++          p++;
++      *p = '\0';
++      p += 2;         /* Skip next ':' */
++      fields[++i] = p;
++    } else {
++      fields[0] = path;
++      i = 0;
++      p = path;
++    }
++    for (; *p; p++)
+       if (*p == ':') {
+           *p = '\0';
+           fields[++i] = p + 1;
+@@ -753,7 +768,7 @@
+       /* Acquire lock (this could be in RateLimit but that would
+        * invoke the spaghetti factor). 
+        */
+-      if ((path = (char *) PostRecFilename(ClientIP,PERMuser)) == NULL) {
++      if ((path = (char *) PostRecFilename(&ClientIP,PERMuser)) == NULL) {
+         Reply("%s\r\n", NNTP_CANTPOST);
+         return;
+       }
+diff -Nur inn-2.3.2.orig/nnrpd/misc.c inn-2.3.2/nnrpd/misc.c
+--- inn-2.3.2.orig/nnrpd/misc.c        Thu May  3 22:27:32 2001
++++ inn-2.3.2/nnrpd/misc.c     Tue Jun 19 16:06:41 2001
+@@ -664,12 +664,12 @@
+  */
+ char
+ *PostRecFilename(ip,user) 
+-     unsigned long                 ip;
++     INADDR                       *ip;
+      char                         *user;
+ {
+      static char                   buff[SPOOLNAMEBUFF];
+      char                          dirbuff[SPOOLNAMEBUFF];
+-     unsigned char addr[4];
++     unsigned char addr[16];
+      unsigned int i;
+      if (PERMaccessconf->backoff_auth) {
+@@ -677,11 +677,27 @@
+        return(buff);
+      }
+-     for (i=0; i<4; i++) {
+-       addr[i] = (unsigned char) (0x000000ff & (ip>>(i*8)));
++     switch (ip->ss_family) {
++     case AF_INET:
++       for (i=0; i<4; i++) {
++       addr[i] = (unsigned char) 
++         (0x000000ff & (((struct sockaddr_in *)ip)->sin_addr.s_addr >> 
++                        (i*8)));
++       }
++       sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
++       break;
++#ifdef INET6
++     case AF_INET6:
++       for (i=0;i<15;i++)
++       addr[i] = ((struct sockaddr_in6 *)ip)->sin6_addr.s6_addr[i];
++       sprintf(dirbuff,"%s/%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x/%02x%02x",
++             postrec_dir,addr[0],addr[1],addr[2],addr[3],addr[4],addr[5],
++             addr[6],addr[7],addr[8],addr[9],addr[10],addr[11],
++             addr[12],addr[13]);
++       break;
++#endif         
+      }
+-     sprintf(dirbuff,"%s/%03d%03d/%03d",postrec_dir,addr[3],addr[2],addr[1]);
+      if (!MakeDirectory(dirbuff,TRUE)) {
+        syslog(L_ERROR,"%s Unable to create postrec directories '%s': %s",
+                ClientHost,dirbuff,strerror(errno));
+diff -Nur inn-2.3.2.orig/nnrpd/nnrpd.c inn-2.3.2/nnrpd/nnrpd.c
+--- inn-2.3.2.orig/nnrpd/nnrpd.c       Thu May  3 22:27:32 2001
++++ inn-2.3.2/nnrpd/nnrpd.c    Tue Jun 19 16:12:24 2001
+@@ -34,6 +34,8 @@
+ int nnrpd_starttls_done = 0;
+ #endif 
++#include "sa_len.h"
++
+ #if defined(hpux) || defined(__hpux) || defined(_SCO_DS)
+ extern int h_errno;
+ #endif
+@@ -362,11 +364,82 @@
+ Address2Name(INADDR *ap, char *hostname, int i)
+ {
+     char              *p;
++#if   defined(INET6)
++    struct addrinfo   hints, *res, *res0;
++    int                       len, ret;
++    struct sockaddr_in sin;
++    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ap;
++#else
+     struct hostent    *hp;
+ #if   defined(h_addr)
+     char              **pp;
+ #endif
++#endif        /* defined (INET6) */
++
++#if   defined(INET6)
++    /* Get the official hostname, store it away. (with new API) */
++    if (ap->ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
++      memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
++              sizeof(sin.sin_addr));
++      sin.sin_port = ((struct sockaddr_in6 *)ap)->sin6_port;
++      sin.sin_family = AF_INET;
++#if   defined(HAVE_SOCKADDR_LEN)
++      sin.sin_len = sizeof(struct sockaddr_in);
++#endif        /* defined(HAVE_SOCKADDR_LEN) */
++      ap = &sin;
++    }
++#if   defined(HAVE_SOCKADDR_LEN)
++    len = ap->ss_len;
++#else
++    len = SA_LEN((struct sockaddr *)ap);
++#endif        /* defined(HAVE_SOCKADDR_LEN) */
++    ret = getnameinfo((struct sockaddr *)ap, len, hostname, i, NULL, 0,
++                    NI_NAMEREQD);
++    if (ret != 0) {
++      HostErrorStr = gai_strerror(ret);
++      return FALSE;
++    }
++
++    /* Get the address for this host */
++    (void)memset(&hints, 0, sizeof(hints));
++    hints.ai_family = PF_UNSPEC;
++    hints.ai_flags = AI_CANONNAME;
++    hints.ai_socktype = SOCK_STREAM;
++    ret = getaddrinfo(hostname, NULL, &hints, &res0);
++    if (ret != 0) {
++      HostErrorStr = gai_strerror(ret);
++      return FALSE;
++    }   
++
++    /* Make sure one of those addresses is the address we got. */
++    for (res = res0; res != NULL; res = res->ai_next) {
++      if (res->ai_addr->sa_family == ap->ss_family) {
++          if (ap->ss_family == AF_INET && 
++              memcmp(&((struct sockaddr_in *)ap)->sin_addr,
++                     &((struct sockaddr_in *)res->ai_addr)->sin_addr,
++                     sizeof(struct in_addr)) == 0)
++              break;
++          else if (ap->ss_family == AF_INET6 &&
++                   memcmp(&((struct sockaddr_in6 *)ap)->sin6_addr,
++                          &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
++                          sizeof(struct in6_addr)) == 0)
++              break;
++      }
++    }
++    if (res == NULL) {
++      freeaddrinfo(res0);
++      return FALSE;
++    }
++    if (res->ai_canonname == NULL) {    /* XXX */
++      freeaddrinfo(res0);
++      return FALSE;
++    }
++    (void)strncpy(hostname, res->ai_canonname, i);
++    freeaddrinfo(res0);
++
++#else /* defined(INET6) */
++      
+     /* Get the official hostname, store it away. */
+     if ((hp = gethostbyaddr((char *)ap, sizeof *ap, AF_INET)) == NULL) {
+       HostErrorStr = (char *)hstrerror(h_errno);
+@@ -385,25 +458,27 @@
+ #if   defined(h_addr)
+     /* We have many addresses */
+     for (pp = hp->h_addr_list; *pp; pp++)
+-      if (memcmp((POINTER)&ap->s_addr, (POINTER)*pp,
+-              (SIZE_T)hp->h_length) == 0)
++      if (memcmp((POINTER)&(((struct sockaddr_in *)ap)->sin_addr.s_addr), 
++                 (POINTER)*pp, (SIZE_T)hp->h_length) == 0)
+           break;
+     if (*pp == NULL)
+       return FALSE;
+ #else
+     /* We have one address. */
+-    if (memcmp((POINTER)&ap->s_addr, (POINTER)hp->h_addr,
+-          (SIZE_T)hp->h_length) != 0)
++    if (memcmp((POINTER)&(((struct sockaddr_in *)ap)->sin_addr.s_addr), 
++             (POINTER)hp->h_addr, (SIZE_T)hp->h_length) != 0)
+       return FALSE;
+ #endif
+     /* Only needed for misconfigured YP/NIS systems. */
+-    if (ap->s_addr != INADDR_LOOPBACK && strchr(hostname, '.') == NULL
+-     && (p = innconf->domain) != NULL) {
++    if (((struct sockaddr_in *)ap)->sin_addr.s_addr != INADDR_LOOPBACK && 
++      strchr(hostname, '.') == NULL && (p = innconf->domain) != NULL) {
+       (void)strcat(hostname, ".");
+       (void)strcat(hostname, p);
+     }
++#endif        /* defined(INET6) */
++
+     /* Make all lowercase, for wildmat. */
+     for (p = hostname; *p; p++)
+       if (CTYPE(isupper, (int)*p))
+@@ -418,7 +493,7 @@
+ */
+ STATIC void StartConnection()
+ {
+-    struct sockaddr_in        sin;
++    struct sockaddr_storage   ss;             
+     ARGTYPE           length;
+     char              buff[SMBUF];
+     char              *ClientAddr;
+@@ -427,9 +502,9 @@
+     static ACCESSGROUP        *authconf;
+     /* Get the peer's name. */
+-    length = sizeof sin;
++    length = sizeof ss;
+     ClientAddr = NULL;
+-    if (getpeername(STDIN, (struct sockaddr *)&sin, &length) < 0) {
++    if (getpeername(STDIN, (struct sockaddr *)&ss, &length) < 0) {
+       if (!isatty(STDIN)) {
+           syslog(L_TRACE, "%s cant getpeername %m", "?");
+             (void)strcpy(ClientHost, "?"); /* so stats generation looks correct. */
+@@ -437,14 +512,18 @@
+           ExitWithStats(1, TRUE);
+       }
+       (void)strcpy(ClientHost, "stdin");
+-        ClientIP = 0L;
++        memset(&ClientIP, 0, sizeof(ClientIP));
+       ServerHost[0] = '\0';
+     }
+     else {
+-      if (sin.sin_family != AF_INET) {
++#if   defined(INET6)
++      if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) {
++#else
++      if (ss.ss_family != AF_INET) {
++#endif        /* defined(INET6) */
+           syslog(L_ERROR, "%s bad_address_family %ld",
+-              "?", (long)sin.sin_family);
++              "?", (long)ss.ss_family);
+           Printf("%d Bad address family.  Goodbye.\r\n", NNTP_ACCESS_VAL);
+           ExitWithStats(1, TRUE);
+       }
+@@ -452,8 +531,8 @@
+       /* Get client's name. */
+ #if   defined(DO_NNRP_GETHOSTBYADDR)
+       HostErrorStr = NULL;
+-      if (!Address2Name(&sin.sin_addr, ClientHost, (int)sizeof ClientHost)) {
+-          (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));
++      if (!Address2Name(&ss, ClientHost, (int)sizeof ClientHost)) {
++          (void)strcpy(ClientHost, Inet_NtoA(&ss));
+           if (HostErrorStr == NULL) {
+               syslog(L_NOTICE,
+                   "? cant gethostbyaddr %s %m -- using IP address for access",
+@@ -464,32 +543,32 @@
+                   ClientHost, HostErrorStr);
+           }
+           ClientAddr = ClientHost;
+-            ClientIP = inet_addr(ClientHost);
++            (void)memcpy(&ClientIP, &ss, sizeof(ss));
+       }
+       else {
+           ClientAddr = buff;
+-          (void)strcpy(buff, inet_ntoa(sin.sin_addr));
+-            ClientIP = inet_addr(buff);
++          (void)strcpy(buff, Inet_NtoA(&ss));
++            (void)memcpy(&ClientIP, &ss, sizeof(ss));
+       }
+ #else
+-      (void)strcpy(ClientHost, inet_ntoa(sin.sin_addr));
+-        ClientIP = inet_addr(ClientHost);
++      (void)strcpy(ClientHost, Inet_NtoA(&ss));
++        (void)memcpy(&ClientIP, &ss, sizeof(ss));
+ #endif /* defined(DO_NNRP_GETHOSTBYADDR) */
+-      (void)strncpy(ClientIp, inet_ntoa(sin.sin_addr), sizeof(ClientIp));
+-      length = sizeof sin;
+-      if (getsockname(STDIN, (struct sockaddr *)&sin, &length) < 0) {
++      (void)strncpy(ClientIp, Inet_NtoA(&ss), sizeof(ClientIp));
++      length = sizeof ss;
++      if (getsockname(STDIN, (struct sockaddr *)&ss, &length) < 0) {
+           syslog(L_NOTICE, "%s can't getsockname %m", ClientHost);
+           Printf("%d Can't figure out where you connected to.  Goodbye\r\n", NNTP_ACCESS_VAL);
+           ExitWithStats(1, TRUE);
+       }
+ #ifdef DO_NNRP_GETHOSTBYADDR
+       HostErrorStr = NULL;
+-      if (!Address2Name(&sin.sin_addr, ServerHost, sizeof(ServerHost))) {
+-          strcpy(ServerHost, inet_ntoa(sin.sin_addr));
++      if (!Address2Name(&ss, ServerHost, sizeof(ServerHost))) {
++          strcpy(ServerHost, Inet_NtoA(&ss));
+           /* suppress error reason */
+       }
+ #else
+-        strcpy(ServerHost, inet_ntoa(sin.sin_addr));
++        strcpy(ServerHost, Inet_NtoA(&ss));
+ #endif /* DO_NNRP_GETHOSTBYADDR */
+     }
+@@ -741,9 +820,14 @@
+     struct            timeval tv;
+     unsigned short    ListenPort = NNTP_PORT;
+     unsigned long     ListenAddr = htonl(INADDR_ANY);
+-    int                       lfd, fd;
++    int                       lfd[2], fd, maxfd, tmpfd;
++    fd_set            fds;
++#ifdef INET6
++    struct sockaddr_in6       ListenAddr6;
++#endif
+     ARGTYPE           clen;
+-    struct sockaddr_in        ssa, csa;
++    struct sockaddr_in        ssa;
++    struct sockaddr_storage   csa;
+     struct stat               Sb;
+     PID_T             pid = -1;
+     GID_T               NewsGID;
+@@ -777,17 +861,27 @@
+     openlog("nnrpd", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);
++#ifdef INET6
++    memset(&ListenAddr6, '\0', sizeof(ListenAddr6));
++#endif
++
+     if (ReadInnConf() < 0) exit(1);
+ #ifdef HAVE_SSL
+-    while ((i = getopt(argc, argv, "b:Di:g:op:Rr:s:tS")) != EOF)
++    while ((i = getopt(argc, argv, "6:b:Di:g:op:Rr:s:tS")) != EOF)
+ #else
+-    while ((i = getopt(argc, argv, "b:Di:g:op:Rr:s:t")) != EOF)
++    while ((i = getopt(argc, argv, "6:b:Di:g:op:Rr:s:t")) != EOF)
+ #endif /* HAVE_SSL */
+       switch (i) {
+       default:
+           Usage();
+           /* NOTREACHED */
++        case '6':                     /* bind to a certain ipv6 address in
++                                         daemon mode */
++#ifdef INET6
++          inet_pton(AF_INET6, optarg, &ListenAddr6.sin6_addr);
++#endif
++          break;
+       case 'b':                       /* bind to a certain address in
+                                          daemon mode */
+           ListenAddr = inet_addr(optarg);
+@@ -849,12 +943,12 @@
+     SPOOLlen = strlen(innconf->patharticles);
+     if (DaemonMode) {
+-      if ((lfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
++      if ((lfd[0] = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+           syslog(L_FATAL, "can't open socket (%m)");
+           exit(1);
+       }
+-      if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
++      if (setsockopt(lfd[0], SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
+           syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
+           exit(1);
+       }
+@@ -864,11 +958,38 @@
+       ssa.sin_addr.s_addr = ListenAddr;
+       ssa.sin_port = htons(ListenPort);
+       
+-      if (bind(lfd, (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
++      if (bind(lfd[0], (struct sockaddr *) &ssa, sizeof(ssa)) < 0) {
+           fprintf(stderr, "%s: can't bind (%s)\n", argv[0], strerror(errno));
+           syslog(L_FATAL, "can't bind local address (%m)");
+           exit(1);
+       }
++      
++      lfd[1] = -1;
++#ifdef INET6
++      if (innconf->bindipv6address) {
++          if ((lfd[1] = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
++              syslog(L_FATAL, "can't open socket(%m)");
++              exit(1);
++          }
++          if (setsockopt(lfd[1], SOL_SOCKET, SO_REUSEADDR, (char *)&one, 
++              sizeof(one)) < 0) {
++              syslog(L_FATAL, "can't setsockopt(SO_REUSEADDR) (%m)");
++              exit(1);
++          }
++          ListenAddr6.sin6_family = AF_INET6;
++          ListenAddr6.sin6_port = htons(ListenPort);
++#ifdef HAVE_SOCKADDR_LEN
++          ListenAddr6.sin6_len = sizeof(ListenAddr6);
++#endif
++          if (bind(lfd[1], (struct sockaddr *)&ListenAddr6, 
++                   sizeof(ListenAddr6)) < 0) {
++              fprintf(stderr, "%s: can't bind (%s)\n", argv[0], 
++                      strerror(errno));
++              syslog(L_FATAL, "can't bind local address (%m)");
++              exit(1);
++          }
++      }
++#endif        /* INET6 */
+       /* If started as root, switch to news uid */
+       if (getuid() == 0) {
+@@ -953,11 +1074,33 @@
+  
+       TITLEset("nnrpd: accepting connections");
+       
+-      listen(lfd, 128);       
++      listen(lfd[0], 128);    
++      maxfd = lfd[0];
++      if (lfd[1] != -1) {
++          if (maxfd < lfd[1])
++              lfd[1] = maxfd;
++          listen(lfd[1], 128);
++      }
++      maxfd++;
+       do {
++          FD_ZERO(&fds);
++          FD_SET(lfd[0], &fds);
++          if (lfd[1] != -1)
++              FD_SET(lfd[1], &fds);
++
++          if (select(maxfd, &fds, NULL, NULL, NULL) < 0) {
++              syslog(L_FATAL, "%s: select cause error (%m)");
++              exit(1);
++          }
++
+           clen = sizeof(csa);
+-          fd = accept(lfd, (struct sockaddr *) &csa, &clen);
++          if (FD_ISSET(lfd[0], &fds))
++              tmpfd = lfd[0];
++          else if (lfd[1] != -1 && FD_ISSET(lfd[1], &fds))
++              tmpfd = lfd[1];
++          fd = accept(tmpfd, (struct sockaddr *) &csa, &clen);
++
+           if (fd < 0)
+               continue;
+           
+@@ -980,7 +1123,9 @@
+       /* child process starts here */
+       TITLEset("nnrpd: connected");
+-      close(lfd);
++      close(lfd[0]);
++      if (lfd[1] != -1)
++          close(lfd[1]);
+       dup2(fd, 0);
+       close(fd);
+       dup2(0, 1);
+diff -Nur inn-2.3.2.orig/nnrpd/nnrpd.h inn-2.3.2/nnrpd/nnrpd.h
+--- inn-2.3.2.orig/nnrpd/nnrpd.h       Thu May  3 22:27:32 2001
++++ inn-2.3.2/nnrpd/nnrpd.h    Tue Jun 19 16:06:41 2001
+@@ -31,6 +31,9 @@
+ #include "paths.h"
+ #include "qio.h"
++#ifndef       HAVE_SOCKADDR_STORAGE
++#include "sockaddr_storage.h"
++#endif
+ /*
+ **  Maximum input line length, sigh.
+@@ -43,7 +46,7 @@
+ /*
+ **  Some convenient shorthands.
+ */
+-typedef struct in_addr        INADDR;
++typedef struct sockaddr_storage INADDR;
+ /*
+@@ -138,7 +141,7 @@
+ EXTERN char   ClientHost[SMBUF];
+ EXTERN char     ServerHost[SMBUF];
+ EXTERN char   Username[SMBUF];
+-EXTERN char     ClientIp[20];
++EXTERN char     ClientIp[64];
+ EXTERN char   LogName[256] ;
+ extern char   *ACTIVETIMES;
+ extern char   *HISTORY;
+@@ -176,7 +179,7 @@
+ EXTERN long   POSTrejected;
+ EXTERN BOOL     BACKOFFenabled;
+-EXTERN long     ClientIP;                                 
++EXTERN INADDR   ClientIP;                                 
+ EXTERN char   *VirtualPath;
+ EXTERN int    VirtualPathlen;
+diff -Nur inn-2.3.2.orig/nnrpd/perm.c inn-2.3.2/nnrpd/perm.c
+--- inn-2.3.2.orig/nnrpd/perm.c        Thu May  3 22:27:32 2001
++++ inn-2.3.2/nnrpd/perm.c     Tue Jun 19 16:06:41 2001
+@@ -1488,6 +1488,10 @@
+           if (!ret && (p = strchr(pat, '/')) != (char *)NULL) {
+               int bits, c;
+               struct in_addr ia, net;
++#ifdef INET6
++              int     n;
++              struct in6_addr ia6, net6;
++#endif
+               unsigned int mask;
+               *p = '\0';
+@@ -1505,6 +1509,23 @@
+                   if ((ia.s_addr & mask) == (net.s_addr & mask))
+                       ret = 1;
+               }
++#ifdef INET6
++              if (inet_pton(AF_INET6, ClientIp, &ia6) == 1 &&
++                  inet_pton(AF_INET6, pat, &net6) == 1) {
++                  if (strchr(p+1, '.') == (char *)NULL) {
++                      mask = atoi(p+1);
++                      n = mask / 8;
++                      bits = mask % 8;
++                      for (c = 0; c < n; c++) 
++                          if (ia6.s6_addr[c] != net6.s6_addr[c])
++                              break;
++                      if (c == n && 
++                          (ia6.s6_addr[c] & (0x00ff << (8 - bits))) == 
++                          (net6.s6_addr[c] & (0x00ff << (8 - bits))))
++                              ret = 1;
++                  }
++              }
++#endif        /* INET6 */
+           }
+         }
+       if (ret)
+diff -Nur inn-2.3.2.orig/samples/inn.conf.in inn-2.3.2/samples/inn.conf.in
+--- inn-2.3.2.orig/samples/inn.conf.in Thu May  3 22:27:32 2001
++++ inn-2.3.2/samples/inn.conf.in      Tue Jun 19 16:06:41 2001
+@@ -170,3 +170,7 @@
+ pathrun:                @RUNDIR@
+ pathspool:              @SPOOLDIR@
+ pathtmp:                @TMPPATH@
++
++# for IPv6 support
++
++listenonipv6:         @ipv6@
index dd58eda1cc62c420c9ad0f2c2316ff531112a4a0..81be1eed5dce6b9fc33d4160f60f15785315abc3 100644 (file)
--- a/inn.spec
+++ b/inn.spec
@@ -23,7 +23,7 @@ Source8:      %{name}-cnfsstat.cron
 Source9:       %{name}.logrotate
 Source10:      %{name}-etc-readers.conf
 #Patch0:       ftp://ftp.north.ad.jp/pub/IPv6/INN/tmp/%{name}-2.3.0-v6-20001011.diff.gz
-Patch0:                %{name}-2.3.1-v6-20010311.patch.gz
+Patch0:                %{name}-ipv6.patch
 Patch1:                %{name}-PLD.patch
 Patch2:                %{name}-install.patch
 Patch3:                %{name}-db3.patch
This page took 0.10853 seconds and 4 git commands to generate.