]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
configure compat replacements. start of ip6 ifdefing.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 16 Feb 2007 15:18:52 +0000 (15:18 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 16 Feb 2007 15:18:52 +0000 (15:18 +0000)
git-svn-id: file:///svn/unbound/trunk@113 be551aaa-1e26-0410-a405-d3ace91eadb9

compat/fake-rfc2553.c [new file with mode: 0644]
compat/fake-rfc2553.h [new file with mode: 0644]
compat/malloc.c [new file with mode: 0644]
compat/memmove.c [new file with mode: 0644]
compat/snprintf.c [new file with mode: 0644]
compat/strlcpy.c [new file with mode: 0644]
configure.ac
services/listen_dnsport.c

diff --git a/compat/fake-rfc2553.c b/compat/fake-rfc2553.c
new file mode 100644 (file)
index 0000000..91ddf8a
--- /dev/null
@@ -0,0 +1,227 @@
+/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */
+/*
+ * Copyright (C) 2000-2003 Damien Miller.  All rights reserved.
+ * Copyright (C) 1999 WIDE Project.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+/*
+ * Pseudo-implementation of RFC2553 name / address resolution functions
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For example, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "compat/fake-rfc2553.h"
+
+#ifndef HAVE_GETNAMEINFO
+int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host, 
+                size_t hostlen, char *serv, size_t servlen, int flags)
+{
+       struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+       struct hostent *hp;
+       char tmpserv[16];
+
+       if (serv != NULL) {
+               snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
+               if (strlcpy(serv, tmpserv, servlen) >= servlen)
+                       return (EAI_MEMORY);
+       }
+
+       if (host != NULL) {
+               if (flags & NI_NUMERICHOST) {
+                       if (strlcpy(host, inet_ntoa(sin->sin_addr),
+                           hostlen) >= hostlen)
+                               return (EAI_MEMORY);
+                       else
+                               return (0);
+               } else {
+                       hp = gethostbyaddr((char *)&sin->sin_addr, 
+                           sizeof(struct in_addr), AF_INET);
+                       if (hp == NULL)
+                               return (EAI_NODATA);
+                       
+                       if (strlcpy(host, hp->h_name, hostlen) >= hostlen)
+                               return (EAI_MEMORY);
+                       else
+                               return (0);
+               }
+       }
+       return (0);
+}
+#endif /* !HAVE_GETNAMEINFO */
+
+#ifndef HAVE_GAI_STRERROR
+#ifdef HAVE_CONST_GAI_STRERROR_PROTO
+const char *
+#else
+char *
+#endif
+gai_strerror(int err)
+{
+       switch (err) {
+       case EAI_NODATA:
+               return ("no address associated with name");
+       case EAI_MEMORY:
+               return ("memory allocation failure.");
+       case EAI_NONAME:
+               return ("nodename nor servname provided, or not known");
+       default:
+               return ("unknown/invalid error.");
+       }
+}    
+#endif /* !HAVE_GAI_STRERROR */
+
+#ifndef HAVE_FREEADDRINFO
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+       struct addrinfo *next;
+
+       for(; ai != NULL;) {
+               next = ai->ai_next;
+               free(ai);
+               ai = next;
+       }
+}
+#endif /* !HAVE_FREEADDRINFO */
+
+#ifndef HAVE_GETADDRINFO
+static struct
+addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
+{
+       struct addrinfo *ai;
+
+       ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
+       if (ai == NULL)
+               return (NULL);
+       
+       memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
+       
+       ai->ai_addr = (struct sockaddr *)(ai + 1);
+       /* XXX -- ssh doesn't use sa_len */
+       ai->ai_addrlen = sizeof(struct sockaddr_in);
+       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
+
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
+       
+       /* XXX: the following is not generally correct, but does what we want */
+       if (hints->ai_socktype)
+               ai->ai_socktype = hints->ai_socktype;
+       else
+               ai->ai_socktype = SOCK_STREAM;
+
+       if (hints->ai_protocol)
+               ai->ai_protocol = hints->ai_protocol;
+
+       return (ai);
+}
+
+int
+getaddrinfo(const char *hostname, const char *servname, 
+    const struct addrinfo *hints, struct addrinfo **res)
+{
+       struct hostent *hp;
+       struct servent *sp;
+       struct in_addr in;
+       int i;
+       long int port;
+       u_long addr;
+
+       port = 0;
+       if (servname != NULL) {
+               char *cp;
+
+               port = strtol(servname, &cp, 10);
+               if (port > 0 && port <= 65535 && *cp == '\0')
+                       port = htons(port);
+               else if ((sp = getservbyname(servname, NULL)) != NULL)
+                       port = sp->s_port;
+               else
+                       port = 0;
+       }
+
+       if (hints && hints->ai_flags & AI_PASSIVE) {
+               addr = htonl(0x00000000);
+               if (hostname && inet_aton(hostname, &in) != 0)
+                       addr = in.s_addr;
+               *res = malloc_ai(port, addr, hints);
+               if (*res == NULL) 
+                       return (EAI_MEMORY);
+               return (0);
+       }
+               
+       if (!hostname) {
+               *res = malloc_ai(port, htonl(0x7f000001), hints);
+               if (*res == NULL) 
+                       return (EAI_MEMORY);
+               return (0);
+       }
+       
+       if (inet_aton(hostname, &in)) {
+               *res = malloc_ai(port, in.s_addr, hints);
+               if (*res == NULL) 
+                       return (EAI_MEMORY);
+               return (0);
+       }
+       
+       /* Don't try DNS if AI_NUMERICHOST is set */
+       if (hints && hints->ai_flags & AI_NUMERICHOST)
+               return (EAI_NONAME);
+       
+       hp = gethostbyname(hostname);
+       if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+               struct addrinfo *cur, *prev;
+
+               cur = prev = *res = NULL;
+               for (i = 0; hp->h_addr_list[i]; i++) {
+                       struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];
+
+                       cur = malloc_ai(port, in->s_addr, hints);
+                       if (cur == NULL) {
+                               if (*res != NULL)
+                                       freeaddrinfo(*res);
+                               return (EAI_MEMORY);
+                       }
+                       if (prev)
+                               prev->ai_next = cur;
+                       else
+                               *res = cur;
+
+                       prev = cur;
+               }
+               return (0);
+       }
+       
+       return (EAI_NODATA);
+}
+#endif /* !HAVE_GETADDRINFO */
diff --git a/compat/fake-rfc2553.h b/compat/fake-rfc2553.h
new file mode 100644 (file)
index 0000000..3d30cf7
--- /dev/null
@@ -0,0 +1,174 @@
+/* From openssh 4.3p2 filename openbsd-compat/fake-rfc2553.h */
+/*
+ * Copyright (C) 2000-2003 Damien Miller.  All rights reserved.
+ * Copyright (C) 1999 WIDE Project.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+/*
+ * Pseudo-implementation of RFC2553 name / address resolution functions
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For example, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ */
+
+#ifndef _FAKE_RFC2553_H
+#define _FAKE_RFC2553_H
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <limits.h>
+
+/*
+ * First, socket and INET6 related definitions 
+ */
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
+# define       _SS_MAXSIZE     128     /* Implementation specific max size */
+# define       _SS_PADSIZE     (_SS_MAXSIZE - sizeof (struct sockaddr))
+struct sockaddr_storage {
+       struct sockaddr ss_sa;
+       char            __ss_pad2[_SS_PADSIZE];
+};
+# define ss_family ss_sa.sa_family
+#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
+
+#ifndef IN6_IS_ADDR_LOOPBACK
+# define IN6_IS_ADDR_LOOPBACK(a) \
+       (((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
+        ((uint32_t *)(a))[2] == 0 && ((uint32_t *)(a))[3] == htonl(1))
+#endif /* !IN6_IS_ADDR_LOOPBACK */
+
+#ifndef HAVE_STRUCT_IN6_ADDR
+struct in6_addr {
+       uint8_t s6_addr[16];
+};
+#endif /* !HAVE_STRUCT_IN6_ADDR */
+
+#ifndef HAVE_STRUCT_SOCKADDR_IN6
+struct sockaddr_in6 {
+       unsigned short  sin6_family;
+       uint16_t        sin6_port;
+       uint32_t        sin6_flowinfo;
+       struct in6_addr sin6_addr;
+};
+#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
+
+#ifndef AF_INET6
+/* Define it to something that should never appear */
+#define AF_INET6 AF_MAX
+#endif
+
+/*
+ * Next, RFC2553 name / address resolution API
+ */
+
+#ifndef NI_NUMERICHOST
+# define NI_NUMERICHOST    (1)
+#endif
+#ifndef NI_NAMEREQD
+# define NI_NAMEREQD       (1<<1)
+#endif
+#ifndef NI_NUMERICSERV
+# define NI_NUMERICSERV    (1<<2)
+#endif
+
+#ifndef AI_PASSIVE
+# define AI_PASSIVE            (1)
+#endif
+#ifndef AI_CANONNAME
+# define AI_CANONNAME          (1<<1)
+#endif
+#ifndef AI_NUMERICHOST
+# define AI_NUMERICHOST                (1<<2)
+#endif
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif /* !NI_MAXSERV */
+#ifndef NI_MAXHOST
+# define NI_MAXHOST 1025
+#endif /* !NI_MAXHOST */
+
+#ifndef INT_MAX
+#define INT_MAX                0xffffffff
+#endif
+
+#ifndef EAI_NODATA
+# define EAI_NODATA    (INT_MAX - 1)
+#endif
+#ifndef EAI_MEMORY
+# define EAI_MEMORY    (INT_MAX - 2)
+#endif
+#ifndef EAI_NONAME
+# define EAI_NONAME    (INT_MAX - 3)
+#endif
+#ifndef EAI_SYSTEM
+# define EAI_SYSTEM    (INT_MAX - 4)
+#endif
+
+#ifndef HAVE_STRUCT_ADDRINFO
+struct addrinfo {
+       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
+       int     ai_family;      /* PF_xxx */
+       int     ai_socktype;    /* SOCK_xxx */
+       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+       size_t  ai_addrlen;     /* length of ai_addr */
+       char    *ai_canonname;  /* canonical name for hostname */
+       struct sockaddr *ai_addr;       /* binary address */
+       struct addrinfo *ai_next;       /* next structure in linked list */
+};
+#endif /* !HAVE_STRUCT_ADDRINFO */
+
+#ifndef HAVE_GETADDRINFO
+#ifdef getaddrinfo
+# undef getaddrinfo
+#endif
+#define getaddrinfo(a,b,c,d)   (ssh_getaddrinfo(a,b,c,d))
+int getaddrinfo(const char *, const char *, 
+    const struct addrinfo *, struct addrinfo **);
+#endif /* !HAVE_GETADDRINFO */
+
+#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
+#define gai_strerror(a)                (ssh_gai_strerror(a))
+char *gai_strerror(int);
+#endif /* !HAVE_GAI_STRERROR */
+
+#ifndef HAVE_FREEADDRINFO
+#define freeaddrinfo(a)                (ssh_freeaddrinfo(a))
+void freeaddrinfo(struct addrinfo *);
+#endif /* !HAVE_FREEADDRINFO */
+
+#ifndef HAVE_GETNAMEINFO
+#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g))
+int getnameinfo(const struct sockaddr *, size_t, char *, size_t, 
+    char *, size_t, int);
+#endif /* !HAVE_GETNAMEINFO */
+
+#endif /* !_FAKE_RFC2553_H */
+
diff --git a/compat/malloc.c b/compat/malloc.c
new file mode 100644 (file)
index 0000000..c32b3f9
--- /dev/null
@@ -0,0 +1,22 @@
+/* Just a replacement, if the original malloc is not
+   GNU-compliant. See autoconf documentation. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#undef malloc
+
+#include <sys/types.h>
+
+void *malloc ();
+
+/* Allocate an N-byte block of memory from the heap.
+   If N is zero, allocate a 1-byte block.  */
+
+void *
+rpl_malloc (size_t n)
+{
+  if (n == 0)
+    n = 1;
+  return malloc (n);
+}
diff --git a/compat/memmove.c b/compat/memmove.c
new file mode 100644 (file)
index 0000000..0035bbf
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *     memmove.c: memmove compat implementation.
+ *
+ *     Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+*/
+
+#include <config.h>
+#include <stdlib.h>
+
+void *memmove(void *dest, const void *src, size_t n);
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+       uint8_t* from = (uint8_t*) src;
+       uint8_t* to = (uint8_t*) dest;
+
+       if (from == to || n == 0)
+               return dest;
+       if (to > from && to-from < (int)n) {
+               /* to overlaps with from */
+               /*  <from......>         */
+               /*         <to........>  */
+               /* copy in reverse, to avoid overwriting from */
+               int i;
+               for(i=n-1; i>=0; i--)
+                       to[i] = from[i];
+               return dest;
+       }
+       if (from > to  && from-to < (int)n) {
+               /* to overlaps with from */
+               /*        <from......>   */
+               /*  <to........>         */
+               /* copy forwards, to avoid overwriting from */
+               size_t i;
+               for(i=0; i<n; i++)
+                       to[i] = from[i];
+               return dest;
+       }
+       memcpy(dest, src, n);
+       return dest;
+}
diff --git a/compat/snprintf.c b/compat/snprintf.c
new file mode 100644 (file)
index 0000000..674cc09
--- /dev/null
@@ -0,0 +1,770 @@
+#include <config.h>
+
+#ifndef HAVE_SNPRINTF
+
+#include <ctype.h>
+#include <sys/types.h>
+
+/* Define this as a fall through, HAVE_STDARG_H is probably already set */
+
+#define HAVE_VARARGS_H
+
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long (blong@fiction.net) 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long (blong@fiction.net) 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ *
+ **************************************************************/
+
+
+/* varargs declarations: */
+
+#if defined(HAVE_STDARG_H)
+# include <stdarg.h>
+# define HAVE_STDARGS    /* let's hope that works everywhere (mj) */
+# define VA_LOCAL_DECL   va_list ap
+# define VA_START(f)     va_start(ap, f)
+# define VA_SHIFT(v,t)  ;   /* no-op for ANSI */
+# define VA_END          va_end(ap)
+#else
+# if defined(HAVE_VARARGS_H)
+#  include <varargs.h>
+#  undef HAVE_STDARGS
+#  define VA_LOCAL_DECL   va_list ap
+#  define VA_START(f)     va_start(ap)      /* f is ignored! */
+#  define VA_SHIFT(v,t) v = va_arg(ap,t)
+#  define VA_END        va_end(ap)
+# else
+/*XX ** NO VARARGS ** XX*/
+# endif
+#endif
+
+int snprintf (char *str, size_t count, const char *fmt, ...);
+int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+
+static void dopr (char *buffer, size_t maxlen, const char *format, 
+                  va_list args);
+static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
+                   char *value, int flags, int min, int max);
+static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
+                   long value, int base, int min, int max, int flags);
+static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
+                  long double fvalue, int min, int max, int flags);
+static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
+
+int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
+{
+  str[0] = 0;
+  dopr(str, count, fmt, args);
+  return(strlen(str));
+}
+
+/* VARARGS3 */
+#ifdef HAVE_STDARGS
+int snprintf (char *str,size_t count,const char *fmt,...)
+#else
+int snprintf (va_alist) va_dcl
+#endif
+{
+#ifndef HAVE_STDARGS
+  char *str;
+  size_t count;
+  char *fmt;
+#endif
+  VA_LOCAL_DECL;
+    
+  VA_START (fmt);
+  VA_SHIFT (str, char *);
+  VA_SHIFT (count, size_t );
+  VA_SHIFT (fmt, char *);
+  (void) vsnprintf(str, count, fmt, ap);
+  VA_END;
+  return(strlen(str));
+}
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS 1
+#define DP_F_PLUS  2
+#define DP_F_SPACE 4
+#define DP_F_NUM   8
+#define DP_F_ZERO  16
+#define DP_F_UP    32
+
+/* Conversion Flags */
+#define DP_C_SHORT   1
+#define DP_C_LONG    2
+#define DP_C_LDOUBLE 3
+
+#define char_to_int(p) (p - '0')
+#define MAX(p,q) ((p >= q) ? p : q)
+
+static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
+{
+  char ch;
+  long value;
+  long double fvalue;
+  char *strvalue;
+  int min;
+  int max;
+  int state;
+  int flags;
+  int cflags;
+  size_t currlen;
+  
+  state = DP_S_DEFAULT;
+  currlen = flags = cflags = min = 0;
+  max = -1;
+  ch = *format++;
+
+  while (state != DP_S_DONE)
+  {
+    if ((ch == '\0') || (currlen >= maxlen)) 
+      state = DP_S_DONE;
+
+    switch(state) 
+    {
+    case DP_S_DEFAULT:
+      if (ch == '%') 
+       state = DP_S_FLAGS;
+      else 
+       dopr_outch (buffer, &currlen, maxlen, ch);
+      ch = *format++;
+      break;
+    case DP_S_FLAGS:
+      switch (ch) 
+      {
+      case '-':
+       flags |= DP_F_MINUS;
+        ch = *format++;
+       break;
+      case '+':
+       flags |= DP_F_PLUS;
+        ch = *format++;
+       break;
+      case ' ':
+       flags |= DP_F_SPACE;
+        ch = *format++;
+       break;
+      case '#':
+       flags |= DP_F_NUM;
+        ch = *format++;
+       break;
+      case '0':
+       flags |= DP_F_ZERO;
+        ch = *format++;
+       break;
+      default:
+       state = DP_S_MIN;
+       break;
+      }
+      break;
+    case DP_S_MIN:
+      if (isdigit(ch)) 
+      {
+       min = 10*min + char_to_int (ch);
+       ch = *format++;
+      } 
+      else if (ch == '*') 
+      {
+       min = va_arg (args, int);
+       ch = *format++;
+       state = DP_S_DOT;
+      } 
+      else 
+       state = DP_S_DOT;
+      break;
+    case DP_S_DOT:
+      if (ch == '.') 
+      {
+       state = DP_S_MAX;
+       ch = *format++;
+      } 
+      else 
+       state = DP_S_MOD;
+      break;
+    case DP_S_MAX:
+      if (isdigit(ch)) 
+      {
+       if (max < 0)
+         max = 0;
+       max = 10*max + char_to_int (ch);
+       ch = *format++;
+      } 
+      else if (ch == '*') 
+      {
+       max = va_arg (args, int);
+       ch = *format++;
+       state = DP_S_MOD;
+      } 
+      else 
+       state = DP_S_MOD;
+      break;
+    case DP_S_MOD:
+      /* Currently, we don't support Long Long, bummer */
+      switch (ch) 
+      {
+      case 'h':
+       cflags = DP_C_SHORT;
+       ch = *format++;
+       break;
+      case 'l':
+       cflags = DP_C_LONG;
+       ch = *format++;
+       break;
+      case 'L':
+       cflags = DP_C_LDOUBLE;
+       ch = *format++;
+       break;
+      default:
+       break;
+      }
+      state = DP_S_CONV;
+      break;
+    case DP_S_CONV:
+      switch (ch) 
+      {
+      case 'd':
+      case 'i':
+       if (cflags == DP_C_SHORT) 
+         value = va_arg (args, int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, long int);
+       else
+         value = va_arg (args, int);
+       fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+       break;
+      case 'o':
+       flags &= ~DP_F_PLUS;
+       if (cflags == DP_C_SHORT)
+         value = va_arg (args, unsigned int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, unsigned long int);
+       else
+         value = va_arg (args, unsigned int);
+       fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
+       break;
+      case 'u':
+       flags &= ~DP_F_PLUS;
+       if (cflags == DP_C_SHORT)
+         value = va_arg (args, unsigned int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, unsigned long int);
+       else
+         value = va_arg (args, unsigned int);
+       fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+       break;
+      case 'X':
+       flags |= DP_F_UP;
+      case 'x':
+       flags &= ~DP_F_PLUS;
+       if (cflags == DP_C_SHORT)
+         value = va_arg (args, unsigned int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, unsigned long int);
+       else
+         value = va_arg (args, unsigned int);
+       fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
+       break;
+      case 'f':
+       if (cflags == DP_C_LDOUBLE)
+         fvalue = va_arg (args, long double);
+       else
+         fvalue = va_arg (args, double);
+       /* um, floating point? */
+       fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
+       break;
+      case 'E':
+       flags |= DP_F_UP;
+      case 'e':
+       if (cflags == DP_C_LDOUBLE)
+         fvalue = va_arg (args, long double);
+       else
+         fvalue = va_arg (args, double);
+       break;
+      case 'G':
+       flags |= DP_F_UP;
+      case 'g':
+       if (cflags == DP_C_LDOUBLE)
+         fvalue = va_arg (args, long double);
+       else
+         fvalue = va_arg (args, double);
+       break;
+      case 'c':
+       dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
+       break;
+      case 's':
+       strvalue = va_arg (args, char *);
+       if (max < 0) 
+         max = maxlen; /* ie, no max */
+       fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
+       break;
+      case 'p':
+       strvalue = va_arg (args, void *);
+       fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+       break;
+      case 'n':
+       if (cflags == DP_C_SHORT) 
+       {
+         short int *num;
+         num = va_arg (args, short int *);
+         *num = currlen;
+        } 
+       else if (cflags == DP_C_LONG) 
+       {
+         long int *num;
+         num = va_arg (args, long int *);
+         *num = currlen;
+        } 
+       else 
+       {
+         int *num;
+         num = va_arg (args, int *);
+         *num = currlen;
+        }
+       break;
+      case '%':
+       dopr_outch (buffer, &currlen, maxlen, ch);
+       break;
+      case 'w':
+       /* not supported yet, treat as next char */
+       ch = *format++;
+       break;
+      default:
+       /* Unknown, skip */
+       break;
+      }
+      ch = *format++;
+      state = DP_S_DEFAULT;
+      flags = cflags = min = 0;
+      max = -1;
+      break;
+    case DP_S_DONE:
+      break;
+    default:
+      /* hmm? */
+      break; /* some picky compilers need this */
+    }
+  }
+  if (currlen < maxlen - 1) 
+    buffer[currlen] = '\0';
+  else 
+    buffer[maxlen - 1] = '\0';
+}
+
+static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
+                   char *value, int flags, int min, int max)
+{
+  int padlen, strln;     /* amount to pad */
+  int cnt = 0;
+  
+  if (value == 0)
+  {
+    value = "<NULL>";
+  }
+
+  for (strln = 0; value[strln]; ++strln); /* strlen */
+  padlen = min - strln;
+  if (padlen < 0) 
+    padlen = 0;
+  if (flags & DP_F_MINUS) 
+    padlen = -padlen; /* Left Justify */
+
+  while ((padlen > 0) && (cnt < max)) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    --padlen;
+    ++cnt;
+  }
+  while (*value && (cnt < max)) 
+  {
+    dopr_outch (buffer, currlen, maxlen, *value++);
+    ++cnt;
+  }
+  while ((padlen < 0) && (cnt < max)) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    ++padlen;
+    ++cnt;
+  }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
+                   long value, int base, int min, int max, int flags)
+{
+  int signvalue = 0;
+  unsigned long uvalue;
+  char convert[20];
+  int place = 0;
+  int spadlen = 0; /* amount to space pad */
+  int zpadlen = 0; /* amount to zero pad */
+  int caps = 0;
+  
+  if (max < 0)
+    max = 0;
+
+  uvalue = value;
+  if( value < 0 ) {
+    signvalue = '-';
+    uvalue = -value;
+  }
+  else
+    if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+      signvalue = '+';
+    else
+      if (flags & DP_F_SPACE)
+       signvalue = ' ';
+
+  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
+
+  do {
+    convert[place++] =
+      (caps? "0123456789ABCDEF":"0123456789abcdef")
+      [uvalue % (unsigned)base  ];
+    uvalue = (uvalue / (unsigned)base );
+  } while(uvalue && (place < 20));
+  if (place == 20) place--;
+  convert[place] = 0;
+
+  zpadlen = max - place;
+  spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); 
+  if (zpadlen < 0) zpadlen = 0;
+  if (spadlen < 0) spadlen = 0;
+  if (flags & DP_F_ZERO)
+  {
+    zpadlen = MAX(zpadlen, spadlen);
+    spadlen = 0;
+  }
+  if (flags & DP_F_MINUS) 
+    spadlen = -spadlen; /* Left Justifty */
+
+#ifdef DEBUG_SNPRINTF
+  dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
+      zpadlen, spadlen, min, max, place));
+#endif
+
+  /* Spaces */
+  while (spadlen > 0) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    --spadlen;
+  }
+
+  /* Sign */
+  if (signvalue) 
+    dopr_outch (buffer, currlen, maxlen, signvalue);
+
+  /* Zeros */
+  if (zpadlen > 0) 
+  {
+    while (zpadlen > 0)
+    {
+      dopr_outch (buffer, currlen, maxlen, '0');
+      --zpadlen;
+    }
+  }
+
+  /* Digits */
+  while (place > 0) 
+    dopr_outch (buffer, currlen, maxlen, convert[--place]);
+  
+  /* Left Justified spaces */
+  while (spadlen < 0) {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    ++spadlen;
+  }
+}
+
+static long double abs_val (long double value)
+{
+  long double result = value;
+
+  if (value < 0)
+    result = -value;
+
+  return result;
+}
+
+static long double pow10 (int exp)
+{
+  long double result = 1;
+
+  while (exp)
+  {
+    result *= 10;
+    exp--;
+  }
+  
+  return result;
+}
+
+static long round (long double value)
+{
+  long intpart;
+
+  intpart = value;
+  value = value - intpart;
+  if (value >= 0.5)
+    intpart++;
+
+  return intpart;
+}
+
+static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
+                  long double fvalue, int min, int max, int flags)
+{
+  int signvalue = 0;
+  long double ufvalue;
+  char iconvert[20];
+  char fconvert[20];
+  int iplace = 0;
+  int fplace = 0;
+  int padlen = 0; /* amount to pad */
+  int zpadlen = 0; 
+  int caps = 0;
+  long intpart;
+  long fracpart;
+  
+  /* 
+   * AIX manpage says the default is 0, but Solaris says the default
+   * is 6, and sprintf on AIX defaults to 6
+   */
+  if (max < 0)
+    max = 6;
+
+  ufvalue = abs_val (fvalue);
+
+  if (fvalue < 0)
+    signvalue = '-';
+  else
+    if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+      signvalue = '+';
+    else
+      if (flags & DP_F_SPACE)
+       signvalue = ' ';
+
+#if 0
+  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
+#endif
+
+  intpart = ufvalue;
+
+  /* 
+   * Sorry, we only support 9 digits past the decimal because of our 
+   * conversion method
+   */
+  if (max > 9)
+    max = 9;
+
+  /* We "cheat" by converting the fractional part to integer by
+   * multiplying by a factor of 10
+   */
+  fracpart = round ((pow10 (max)) * (ufvalue - intpart));
+
+  if (fracpart >= pow10 (max))
+  {
+    intpart++;
+    fracpart -= pow10 (max);
+  }
+
+#ifdef DEBUG_SNPRINTF
+  dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
+#endif
+
+  /* Convert integer part */
+  do {
+    iconvert[iplace++] =
+      (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
+    intpart = (intpart / 10);
+  } while(intpart && (iplace < 20));
+  if (iplace == 20) iplace--;
+  iconvert[iplace] = 0;
+
+  /* Convert fractional part */
+  do {
+    fconvert[fplace++] =
+      (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
+    fracpart = (fracpart / 10);
+  } while(fracpart && (fplace < 20));
+  if (fplace == 20) fplace--;
+  fconvert[fplace] = 0;
+
+  /* -1 for decimal point, another -1 if we are printing a sign */
+  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
+  zpadlen = max - fplace;
+  if (zpadlen < 0)
+    zpadlen = 0;
+  if (padlen < 0) 
+    padlen = 0;
+  if (flags & DP_F_MINUS) 
+    padlen = -padlen; /* Left Justifty */
+
+  if ((flags & DP_F_ZERO) && (padlen > 0)) 
+  {
+    if (signvalue) 
+    {
+      dopr_outch (buffer, currlen, maxlen, signvalue);
+      --padlen;
+      signvalue = 0;
+    }
+    while (padlen > 0)
+    {
+      dopr_outch (buffer, currlen, maxlen, '0');
+      --padlen;
+    }
+  }
+  while (padlen > 0)
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    --padlen;
+  }
+  if (signvalue) 
+    dopr_outch (buffer, currlen, maxlen, signvalue);
+
+  while (iplace > 0) 
+    dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
+
+  /*
+   * Decimal point.  This should probably use locale to find the correct
+   * char to print out.
+   */
+  dopr_outch (buffer, currlen, maxlen, '.');
+
+  while (fplace > 0) 
+    dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
+
+  while (zpadlen > 0)
+  {
+    dopr_outch (buffer, currlen, maxlen, '0');
+    --zpadlen;
+  }
+
+  while (padlen < 0) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    ++padlen;
+  }
+}
+
+static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
+{
+  if (*currlen < maxlen)
+    buffer[(*currlen)++] = c;
+}
+
+#ifdef TEST_SNPRINTF
+#ifndef LONG_STRING
+#define LONG_STRING 1024
+#endif
+int main (void)
+{
+  char buf1[LONG_STRING];
+  char buf2[LONG_STRING];
+  char *fp_fmt[] = {
+    "%-1.5f",
+    "%1.5f",
+    "%123.9f",
+    "%10.5f",
+    "% 10.5f",
+    "%+22.9f",
+    "%+4.9f",
+    "%01.3f",
+    "%4f",
+    "%3.1f",
+    "%3.2f",
+    NULL
+  };
+  double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
+    0.9996, 1.996, 4.136, 0};
+  char *int_fmt[] = {
+    "%-1.5d",
+    "%1.5d",
+    "%123.9d",
+    "%5.5d",
+    "%10.5d",
+    "% 10.5d",
+    "%+22.33d",
+    "%01.3d",
+    "%4d",
+    NULL
+  };
+  long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
+  int x, y;
+  int fail = 0;
+  int num = 0;
+
+  printf ("Testing snprintf format codes against system sprintf...\n");
+
+  for (x = 0; fp_fmt[x] != NULL ; x++)
+    for (y = 0; fp_nums[y] != 0 ; y++)
+    {
+      snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
+      sprintf (buf2, fp_fmt[x], fp_nums[y]);
+      if (strcmp (buf1, buf2))
+      {
+       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
+           fp_fmt[x], buf1, buf2);
+       fail++;
+      }
+      num++;
+    }
+
+  for (x = 0; int_fmt[x] != NULL ; x++)
+    for (y = 0; int_nums[y] != 0 ; y++)
+    {
+      snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
+      sprintf (buf2, int_fmt[x], int_nums[y]);
+      if (strcmp (buf1, buf2))
+      {
+       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
+           int_fmt[x], buf1, buf2);
+       fail++;
+      }
+      num++;
+    }
+  printf ("%d tests failed out of %d.\n", fail, num);
+}
+#endif /* SNPRINTF_TEST */
+
+#endif /* !HAVE_SNPRINTF */
diff --git a/compat/strlcpy.c b/compat/strlcpy.c
new file mode 100644 (file)
index 0000000..acd306a
--- /dev/null
@@ -0,0 +1,57 @@
+/* from openssh 4.3p2 compat/strlcpy.c */
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */
+
+#include <config.h>
+#ifndef HAVE_STRLCPY
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+       char *d = dst;
+       const char *s = src;
+       size_t n = siz;
+
+       /* Copy as many bytes as will fit */
+       if (n != 0 && --n != 0) {
+               do {
+                       if ((*d++ = *s++) == 0)
+                               break;
+               } while (--n != 0);
+       }
+
+       /* Not enough room in dst, add NUL and traverse rest of src */
+       if (n == 0) {
+               if (siz != 0)
+                       *d = '\0';              /* NUL-terminate dst */
+               while (*s++)
+                       ;
+       }
+
+       return(s - src - 1);    /* count does not include NUL */
+}
+
+#endif /* !HAVE_STRLCPY */
index dbf9e117c5a10ae33240d2abcb2c72e495ed9d59..4b9dcaf9d9cc93696069d331c2adc4d5c50248b6 100644 (file)
@@ -267,7 +267,7 @@ AC_PROG_LIBTOOL
 
 # Checks for header files.
 AC_HEADER_STDC
-AC_CHECK_HEADERS([getopt.h stdarg.h stdbool.h netinet/in.h time.h sys/param.h sys/socket.h arpa/inet.h],,, [AC_INCLUDES_DEFAULT])
+AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h arpa/inet.h],,, [AC_INCLUDES_DEFAULT])
 
 # check for types
 AC_CHECK_TYPE(int8_t, char)
@@ -311,6 +311,16 @@ AC_INCLUDES_DEFAULT
 #endif
 ])
 
+AC_CHECK_TYPE(struct sockaddr_storage, [], [AC_DEFINE([sockaddr_storage], [sockaddr_in], [sockaddr_storage])], [
+AC_INCLUDES_DEFAULT
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+])
+
 # Checks for libraries.
 AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
                                     [enable SSL (will check /usr/local/ssl
@@ -398,14 +408,14 @@ AC_TYPE_SIGNAL
 AC_FUNC_FSEEKO
 AC_SYS_LARGEFILE
 
-#AC_REPLACE_FUNCS(snprintf)
-#AC_REPLACE_FUNCS(strlcpy)
-#AC_REPLACE_FUNCS(memmove)
+AC_REPLACE_FUNCS(snprintf)
+AC_REPLACE_FUNCS(strlcpy)
+AC_REPLACE_FUNCS(memmove)
 
-#AC_CHECK_FUNCS([getaddrinfo])
-#if test $ac_cv_func_getaddrinfo = no; then
-#AC_LIBOBJ([fake-rfc2553])
-#fi
+AC_CHECK_FUNCS([getaddrinfo])
+if test $ac_cv_func_getaddrinfo = no; then
+AC_LIBOBJ([fake-rfc2553])
+fi
 
 AC_ARG_WITH(ldns,
         AC_HELP_STRING([--with-ldns=PATH        specify prefix of path of ldns library to use])
@@ -475,6 +485,16 @@ AH_BOTTOM([
 #define ftello ftell
 #endif /* HAVE_FSEEKO */
 
+#ifndef IPV6_MIN_MTU
+#define IPV6_MIN_MTU 1280
+#endif /* IPV6_MIN_MTU */
+
+#ifdef AF_INET6
+#define INET6
+#else
+#define AF_INET6        28
+#endif
+
 #include "ldns/ldns.h"
 
 /** default port to listen for queries, passed to getaddrinfo */
index a18e84c42791d303c6192514933f41346d3c0d06..f308ee51788731cfb991410d0c18e1a3cfb98cfb 100644 (file)
@@ -67,9 +67,11 @@ verbose_print_addr(struct addrinfo *addr)
        if(verbosity >= VERB_ALGO) {
                char buf[100];
                void* sinaddr = &((struct sockaddr_in*)addr->ai_addr)->sin_addr;
+#ifdef INET6
                if(addr->ai_family == AF_INET6)
                        sinaddr = &((struct sockaddr_in6*)addr->ai_addr)->
                                sin6_addr;
+#endif /* INET6 */
                if(inet_ntop(addr->ai_family, sinaddr, buf,
                        (socklen_t)sizeof(buf)) == 0) {
                        strncpy(buf, "(null)", sizeof(buf));
@@ -78,8 +80,8 @@ verbose_print_addr(struct addrinfo *addr)
                        addr->ai_socktype==SOCK_DGRAM?"udp":
                        addr->ai_socktype==SOCK_STREAM?"tcp":"otherproto",
                        addr->ai_family==AF_INET?"4":
-                       addr->ai_family==AF_INET6?"6":"_otherfam", 
-                       buf, 
+                       addr->ai_family==AF_INET6?"6":
+                       "_otherfam", buf, 
                        ntohs(((struct sockaddr_in*)addr->ai_addr)->sin_port));
        }
 }