X-Git-Url: http://git.samba.org/samba.git/?p=bbaumbach%2Fsamba-autobuild%2F.git;a=blobdiff_plain;f=source4%2Flib%2Fsocket_wrapper%2Fsocket_wrapper.c;h=1c3d5c3bfcb3663330d846f1ca24bf555518135e;hp=940883a45f80665778bc04ee805b97c3df1a79aa;hb=5086945689f10db74fbb2a4340c7e22469f9e8d8;hpb=eb11eeb5dbeccd7710f92dc0639df36aad06c46b diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index 940883a45f8..1c3d5c3bfcb 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -57,6 +57,14 @@ #define real_close close #endif +/* we need to use a very terse format here as IRIX 6.4 silently + truncates names to 16 chars, so if we use a longer name then we + can't tell which port a packet came from with recvfrom() + + with this format we have 8 chars left for the directory name +*/ +#define SOCKET_FORMAT "%u_%u" + static struct sockaddr *sockaddr_dup(const void *data, socklen_t len) { struct sockaddr *ret = (struct sockaddr *)malloc(len); @@ -87,6 +95,19 @@ struct socket_info static struct socket_info *sockets = NULL; + +static const char *socket_wrapper_dir(void) +{ + const char *s = getenv("SOCKET_WRAPPER_DIR"); + if (s == NULL) { + return NULL; + } + if (strncmp(s, "./", 2) == 0) { + s += 2; + } + return s; +} + static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, socklen_t *len) { unsigned int prt; @@ -102,7 +123,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr_in *in, s p = strrchr(un->sun_path, '/'); if (p) p++; else p = un->sun_path; - if (sscanf(p, "sock_ip_%d_%u", &type, &prt) == 2) { + if (sscanf(p, SOCKET_FORMAT, &type, &prt) == 2) { in->sin_port = htons(prt); } in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); @@ -119,13 +140,13 @@ static int convert_in_un(struct socket_info *si, const struct sockaddr_in *in, s /* handle auto-allocation of ephemeral ports */ prt = 5000; do { - snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", - getenv("SOCKET_WRAPPER_DIR"), type, ++prt); + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, ++prt); } while (stat(un->sun_path, &st) == 0 && prt < 10000); ((struct sockaddr_in *)si->myname)->sin_port = htons(prt); } - snprintf(un->sun_path, sizeof(un->sun_path), "%s/sock_ip_%d_%u", - getenv("SOCKET_WRAPPER_DIR"), type, prt); + snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, + socket_wrapper_dir(), type, prt); return 0; } @@ -197,7 +218,7 @@ int swrap_socket(int domain, int type, int protocol) struct socket_info *si; int fd; - if (!getenv("SOCKET_WRAPPER_DIR")) { + if (!socket_wrapper_dir()) { return real_socket(domain, type, protocol); } @@ -230,6 +251,8 @@ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return real_accept(s, addr, addrlen); } + memset(&un_addr, 0, sizeof(un_addr)); + ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen); if (ret == -1) return ret; @@ -270,7 +293,7 @@ static int swrap_auto_bind(struct socket_info *si) for (i=0;i<1000;i++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), - "%s/sock_ip_%u_%u", getenv("SOCKET_WRAPPER_DIR"), + "%s/"SOCKET_FORMAT, socket_wrapper_dir(), SOCK_DGRAM, i + 10000); if (bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr)) == 0) { @@ -458,6 +481,8 @@ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr return real_recvfrom(s, buf, len, flags, from, fromlen); } + /* irix 6.4 forgets to null terminate the sun_path string :-( */ + memset(&un_addr, 0, sizeof(un_addr)); ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen); if (ret == -1) return ret;