Fix build on Solaris 10.
[ircu2.10.12-pk.git] / ircd / os_generic.c
index 9191b387303639541a7925fd1c407dc296920464..ff56fce7f263bddbdfa06d62ca44e109a2b388d1 100644 (file)
  */
 #include "config.h"
 
-#define _XOPEN_SOURCE  500 /**< make limits.h #define IOV_MAX */
-#define __EXTENSIONS__  1   /**< make Solaris netinet/in.h know IPv6 */
+#ifdef IRCU_SOLARIS
+/* Solaris requires C99 support for SUSv3, but C99 support breaks other
+ * parts of the build.  So fall back to SUSv2, but request IPv6 support
+ * by defining __EXTENSIONS__.
+ */
+#define _XOPEN_SOURCE   500
+#define __EXTENSIONS__  1
+#else
+/* FreeBSD 6.0 requires SUSv3 to support IPv6.  Apparently some other
+ * OS requires SUSv3 to define IOV_MAX, but its identity is lost for
+ * the time being.
+ */
+#define _XOPEN_SOURCE   600
+#endif
 
 #include "ircd_osdep.h"
 #include "msgq.h"
+#include "ircd_log.h"
 #include "res.h"
 #include "s_bsd.h"
 #include "sys.h"
@@ -37,7 +50,7 @@
  * Solaris requires sys/time.h before struct rusage (indirectly) in
  * netinet/in.h.
  */
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
 #endif
 
+
+static void sockaddr_in_to_irc(const struct sockaddr_in *v4,
+                               struct irc_sockaddr *irc)
+{
+    memset(&irc->addr, 0, 5*sizeof(int16_t));
+    irc->addr.in6_16[5] = 0xffff;
+    memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
+    irc->port = ntohs(v4->sin_port);
+}
+
+
 #ifdef IPV6
 /** Native socket address type. */
 #define sockaddr_native sockaddr_in6
@@ -85,11 +109,7 @@ void sockaddr_to_irc(const struct sockaddr_in6 *v6, struct irc_sockaddr *irc)
         irc->port = ntohs(v6->sin6_port);
     }
     else if (v6->sin6_family == AF_INET) {
-        const struct sockaddr_in *v4 = (const struct sockaddr_in*)v6;
-        memset(&irc->addr, 0, 5*sizeof(int16_t));
-        irc->addr.in6_16[5] = 0xffff;
-        memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
-        irc->port = ntohs(v4->sin_port);
+        sockaddr_in_to_irc((struct sockaddr_in *)v6, irc);
     }
     else assert(0 && "Unhandled native address family");
 }
@@ -106,21 +126,18 @@ int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, i
     socklen_t slen;
     int family;
 
+    assert(irc != 0);
     slen = sizeof(sin6);
-    if ((0 <= compat_fd) && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
+    if ((0 <= compat_fd)
+        && (0 == getsockname(compat_fd, (struct sockaddr*)&sin6, &slen)))
         family = sin6.sin6_family;
-    else if (irc_in_addr_is_ipv4(&VirtualHost.addr))
+    else if ((irc == &VirtualHost_v4) || irc_in_addr_is_ipv4(&irc->addr))
         family = AF_INET;
     else
         family = AF_INET6;
 
     memset(v6, 0, sizeof(*v6));
-    if (!irc) {
-        memset(v6, 0, sizeof(v6));
-        v6->sin6_family = AF_INET6;
-        return sizeof(*v6);
-    }
-    else if ((family == AF_INET) && irc_in_addr_is_ipv4(&irc->addr)) {
+    if (family == AF_INET) {
         struct sockaddr_in *v4 = (struct sockaddr_in*)v6;
         v4->sin_family = AF_INET;
         memcpy(&v4->sin_addr, &irc->addr.in6_16[6], sizeof(v4->sin_addr));
@@ -138,17 +155,11 @@ int sockaddr_from_irc(struct sockaddr_in6 *v6, const struct irc_sockaddr *irc, i
 #else
 #define sockaddr_native sockaddr_in
 #define sn_family sin_family
-
-void sockaddr_to_irc(const struct sockaddr_in *v4, struct irc_sockaddr *irc)
-{
-    assert(v4->sin_family == AF_INET);
-    memset(&irc->addr, 0, 6*sizeof(irc->addr.in6_16[0]));
-    memcpy(&irc->addr.in6_16[6], &v4->sin_addr, sizeof(v4->sin_addr));
-    irc->port = ntohs(v4->sin_port);
-}
+#define sockaddr_to_irc sockaddr_in_to_irc
 
 int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, int compat_fd)
 {
+    assert(irc != 0);
     v4->sin_family = AF_INET;
     if (irc) {
         assert(!irc->addr.in6_16[0] && !irc->addr.in6_16[1] && !irc->addr.in6_16[2] && !irc->addr.in6_16[3] && !irc->addr.in6_16[4] && (!irc->addr.in6_16[5] || irc->addr.in6_16[5] == 0xffff));
@@ -163,14 +174,8 @@ int sockaddr_from_irc(struct sockaddr_in *v4, const struct irc_sockaddr *irc, in
 
 #endif
 
-/*
- * This is part of the STATS replies. There is no offical numeric for this
- * since this isnt an official command, in much the same way as HASH isnt.
- * It is also possible that some systems wont support this call or have
- * different field names for "struct rusage".
- * -avalon
- */
-/** Send resource usage information to a client.
+#ifdef DEBUGMODE
+/** Send resource usage information to an enumerator function.
  * @param[in] cptr Client requesting information.
  * @param[in] uptime Wall time in seconds since the server started.
  * @param[in] enumerator Function to call to send a line to \a cptr.
@@ -263,6 +268,7 @@ int os_get_rusage(struct Client *cptr, int uptime, EnumFn enumerator)
 #endif /* HAVE_GETRUSAGE */
   return 1;
 }
+#endif
 
 /** Look up the most recent socket error for a socket file descriptor.
  * @param[in] fd File descriptor to check.
@@ -509,6 +515,7 @@ IOResult os_sendto_nonb(int fd, const char* buf, unsigned int length,
   errno = 0;
 
   size = sockaddr_from_irc(&addr, peer, fd);
+  assert((addr.sn_family == AF_INET) == irc_in_addr_is_ipv4(&peer->addr));
   if (-1 < (res = sendto(fd, buf, length, flags, (struct sockaddr*)&addr, size))) {
     if (count_out)
       *count_out = (unsigned) res;
@@ -610,6 +617,7 @@ int os_socket(const struct irc_sockaddr* local, int type, const char* port_name)
   struct sockaddr_native addr;
   int size, fd;
 
+  assert(local != 0);
   size = sockaddr_from_irc(&addr, local, -1);
   fd = socket(addr.sn_family, type, 0);
   if (fd < 0) {