#include <arpa/inet.h>
#endif
-/* Support for missing IPv6 components */
-#ifndef HAVE_SOCKADDR_STORAGE
-# define sockaddr_storage sockaddr_in
-# define ss_family sin_family
-#endif
-
#ifdef WORKING_IPV6
#define INET6
#endif
#define MAX_TAPE_LABEL_BUF (MAX_TAPE_LABEL_LEN+1)
#define MAX_TAPE_LABEL_FMT "%10240s"
+/* Unfortunately, the system-level sockaddr_storage definition can lead to
+ * C aliasing errors (where the optimizer doesn't notice that two operations
+ * affect the same datum). We define our own similar type as a union.
+ */
+typedef union sockaddr_union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+#ifdef WORKING_IPV6
+ struct sockaddr_in6 sin6;
+#endif
+#ifdef HAVE_SOCKADDR_STORAGE
+ struct sockaddr_storage ss; /* not used; just here to make the union full-size */
+#endif
+} sockaddr_union;
+
#include "debug.h"
#include "file.h"
/* from old bsd-security.c */
extern int debug;
-extern int check_security(struct sockaddr_storage *, char *, unsigned long, char **);
+extern int check_security(sockaddr_union *, char *, unsigned long, char **);
/*
* Handle functions which are not always declared on all systems. This
/* AIX #defines accept, and provides a prototype for the alternate name */
#if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
-extern int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+extern int accept(int s, struct sockaddr *addr, socklen_t_equiv *addrlen);
#endif
#ifndef HAVE_ATOF_DECL
#endif
#ifndef HAVE_BIND_DECL
-extern int bind(int s, const struct sockaddr *name, socklen_t namelen);
+extern int bind(int s, const struct sockaddr *name, socklen_t_equiv namelen);
#endif
#ifndef HAVE_BZERO
#endif
#ifndef HAVE_CONNECT_DECL
-extern int connect(int s, struct sockaddr *name, socklen_t namelen);
+extern int connect(int s, struct sockaddr *name, socklen_t_equiv namelen);
#endif
#ifndef HAVE_FCLOSE_DECL
/* AIX #defines getpeername, and provides a prototype for the alternate name */
#if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
-extern int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
+extern int getpeername(int s, struct sockaddr *name, socklen_t_equiv *namelen);
#endif
/* AIX #defines getsockname, and provides a prototype for the alternate name */
#if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
-extern int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
+extern int getsockname(int s, struct sockaddr *name, socklen_t_equiv *namelen);
#endif
#ifndef HAVE_GETSOCKOPT_DECL
extern int getsockopt(int s, int level, int optname, char *optval,
- socklen_t *optlen);
+ socklen_t_equiv *optlen);
#endif
#ifndef HAVE_INITGROUPS
/* AIX #defines recvfrom, and provides a prototype for the alternate name */
#if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
extern int recvfrom(int s, char *buf, int len, int flags,
- struct sockaddr *from, socklen_t *fromlen);
+ struct sockaddr *from, socklen_t_equiv *fromlen);
#endif
#ifndef HAVE_REMOVE_DECL