Logo Search packages:      
Sourcecode: dante version File versions

int_osf3.c

/*
 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003
 *      Inferno Nettverk A/S, Norway.  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. The above copyright notice, this list of conditions and the following
 *    disclaimer must appear in all copies of the software, derivative works
 *    or modified versions, and any portions thereof, aswell as in all
 *    supporting documentation.
 * 2. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by
 *      Inferno Nettverk A/S, Norway.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
 *
 * Inferno Nettverk A/S requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  sdc@inet.no
 *  Inferno Nettverk A/S
 *  Oslo Research Park
 *  Gaustadalléen 21
 *  NO-0349 Oslo
 *  Norway
 *
 * any improvements or extensions that they make and grant Inferno Nettverk A/S
 * the rights to redistribute these changes.
 *
 */

#include "autoconf.h"

#if HAVE_EXTRA_OSF_SYMBOLS

#if SOCKSLIBRARY_DYNAMIC

#undef _XOPEN_SOURCE_EXTENDED
#undef _SOCKADDR_LEN
#define HAVE_OSF_OLDSTYLE 1

/*
 * use of bzero in SYSCALL_START produces vast amounts of warnings
 * when compiling int_osf3.c (on OSF)
 */
#define bzero(a, b) (memset(a, 0, b))

#define SOCKS_DLIB_OSF

/* XXX prevents DEC cc from redefining these to _Ereadv/_Ewritev */
#define readv XXX
#define writev XXX

#include "common.h"

static const char rcsid[] =
"$Id: int_osf3.c,v 1.25 2003/07/01 13:21:13 michaels Exp $";

#undef accept
#undef bind
#undef getpeername
#undef getsockname
#undef recvfrom
#undef recvmsg
#undef sendmsg
#undef connect
#undef readv
#undef writev
#undef sendto

/* XXX Attempt to support old library calls, which use old version of
   sockaddr and msghdr struct. Other parts of libdsocks are compiled
   using the new versions. */

/* sockaddr struct, with sa_len */
struct n_sockaddr {
      unsigned char    sa_len;            /* total length */
      sa_family_t sa_family;        /* address family */
      char      sa_data[14];  /* actually longer; address value */
};

struct n_msghdr {
      void    *msg_name;            /* optional address */
      size_t      msg_namelen;      /* size of address */
      struct      iovec *msg_iov;/* scatter/gather array */
      int         msg_iovlen;       /* # elements in msg_iov */
      void    *msg_control;   /* ancillary data, see below */
      size_t      msg_controllen;/* ancillary data buffer len */
      int         msg_flags;        /* flags on received message */
};


__BEGIN_DECLS

ssize_t Rsendto __P((int, const void *, size_t, int,
                                          const struct n_sockaddr *, socklen_t));
int Rconnect __P((int, const struct n_sockaddr *, socklen_t));
ssize_t Rsendmsg __P((int, const struct n_msghdr *, int));
ssize_t Rrecvfrom __P((int, void *, int, int, struct n_sockaddr *, socklen_t *));
int Rgetsockname __P((int, struct n_sockaddr *, socklen_t *));
int Rgetpeername __P((int, struct n_sockaddr *, socklen_t *));
int Raccept __P((int, struct n_sockaddr *, socklen_t *));
ssize_t Rrecvmsg __P((int s, struct n_msghdr *msg, int flags));
int Rbind __P((int, const struct n_sockaddr *, socklen_t));

__END_DECLS


      /* 'old' versions (with sockaddr len) of the system calls. */

int
sys_accept(s, addr, addrlen)
      int s;
      struct sockaddr *addr;
      int *addrlen;
{
      int rc;
      int (*function)(int s, struct sockaddr * addr, socklen_t *addrlen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_ACCEPT);
      rc = function(s, addr, (socklen_t *) addrlen);
      SYSCALL_END(s);
      return rc;
}

int
sys_getpeername(s, name, namelen)
      int s;
      struct sockaddr *name;
      int *namelen;
{
      int rc;
      int (*function)(int s, const struct sockaddr * name, socklen_t *namelen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_GETPEERNAME);
      rc = function(s, name, (socklen_t *) namelen);
      SYSCALL_END(s);
      return rc;
}

int
sys_getsockname(s, name, namelen)
      int s;
      struct sockaddr *name;
      int *namelen;
{
      int rc;
      int (*function)(int s, const struct sockaddr * name, socklen_t *namelen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_GETSOCKNAME);
      rc = function(s, name, (socklen_t *) namelen);
      SYSCALL_END(s);
      return rc;
}

int
sys_recvfrom(s, buf, len, flags, from, fromlen)
      int s;
      void *buf;
      int len;
      int flags;
      struct sockaddr *from;
      int *fromlen;
{
      int rc;
      int (*function)(int s, void *buf, size_t len, int flags,
                                  struct sockaddr * from, socklen_t *fromlen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_RECVFROM);
      rc = function(s, buf, len, flags, from, (socklen_t *) fromlen);
      SYSCALL_END(s);
      return rc;
}

ssize_t
sys_recvmsg(s, msg, flags)
      int s;
      struct msghdr *msg;
      int flags;
{
      ssize_t rc;
      int (*function)(int s, struct msghdr *msg, int flags);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_RECVMSG);
      rc = function(s, msg, flags);
      SYSCALL_END(s);
      return rc;
}

ssize_t
sys_sendmsg(s, msg, flags)
      int s;
      struct msghdr *msg;
      int flags;
{
      ssize_t rc;
      int (*function)(int s, const struct msghdr *msg, int flags);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_SENDMSG);
      rc = function(s, msg, flags);
      SYSCALL_END(s);
      return rc;
}

ssize_t
sys_readv(d, iov, iovcnt)
      int d;
      const struct iovec *iov;
      int iovcnt;
{
      ssize_t rc;
      int (*function)(int d, const struct iovec *iov, int iovcnt);

      SYSCALL_START(d);
      function = symbolfunction(SYMBOL_READV);
      rc = function(d, iov, iovcnt);
      SYSCALL_END(d);
      return rc;
}

ssize_t
sys_writev(d, iov, iovcnt)
      int d;
      const struct iovec *iov;
      int iovcnt;
{
      ssize_t rc;
      int (*function)(int d, const struct iovec *buf, int iovcnt);

      SYSCALL_START(d);
      function = symbolfunction(SYMBOL_WRITEV);
      rc = function(d, iov, iovcnt);
      SYSCALL_END(d);
      return rc;
}

int
sys_connect(s, name, namelen)
      int s;
      const struct sockaddr *name;
      int namelen;
{
      int rc;
      int (*function)(int s, const struct sockaddr * name, socklen_t namelen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_CONNECT);
      rc = function(s, name, namelen);
      SYSCALL_END(s);
      return rc;
}


int
sys_bind(s, name, namelen)
      int s;
      const struct sockaddr *name;
      int namelen;
{
      int rc;
      int (*function)(int s, const struct sockaddr *name, socklen_t namelen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_BIND);
      rc = function(s, name, namelen);
      SYSCALL_END(s);
      return rc;
}

int
sys_sendto(s, msg, len, flags, to, tolen)
      int s;
      const void *msg;
      int len;
      int flags;
      const struct sockaddr *to;
      socklen_t tolen;
{
      ssize_t rc;
      int (*function)(int s, const void *msg, size_t len, int flags,
                                  const struct sockaddr *to, socklen_t tolen);

      SYSCALL_START(s);
      function = symbolfunction(SYMBOL_SENDTO);
      rc = function(s, msg, len, flags, to, tolen);
      SYSCALL_END(s);
      return rc;
}

      /*
       * the interpositioned functions.
       */

/* sockaddr *, new len */
#define ADDRLEN_SET(a,b) (((a) == NULL) ? 0 : (b))

#ifdef lint
extern const int lintnoloop_int_osf3_c;
#else
#define lintnoloop_int_osf3_c 0
#endif

/* source sockaddr, len, dest sockaddr, len */
#define SOCKADDR_COPYRES(a,b,c,d) \
 do { if (((c) != NULL) && (*(d) > 0) && (*(b) > 0)) { \
            struct n_sockaddr n = *(a); \
            int tmplen = *(d); \
\
            if (tmplen >= sizeof(n.sa_family)) \
                  (c)->sa_family = (unsigned short)n.sa_family; \
            tmplen -= sizeof((c)->sa_family); \
            tmplen = MAX(0, tmplen); \
            memcpy((c)->sa_data, n.sa_data, (size_t)tmplen); \
            *(d) = MIN(*d, sizeof(struct sockaddr)); \
      } \
  } while (lintnoloop_int_osf3_c)

/* source sockaddr, len, dest sockaddr, len */
#define SOCKADDR_COPYPARAM(a,b,c,d) \
 do { if (((a) != NULL) && (*(b) > 0)) { \
            struct n_sockaddr n; \
            int tmplen = *(b); \
\
            bzero((char *)&n, sizeof(n));  \
            /* struct sockaddr -> sa_family == unsigned short */ \
            if (tmplen >= sizeof(unsigned short))  \
                  n.sa_family = (sa_family_t)(a)->sa_family; \
            tmplen -= sizeof(n.sa_family); \
            tmplen = MAX(0, tmplen); \
            memcpy(n.sa_data, (a)->sa_data, (size_t)tmplen); \
            *(d) = sizeof(n); \
            *c = n; \
      } else { \
            *(d) = *(b); \
      } \
  } while (lintnoloop_int_osf3_c)

int
accept(s, addr, addrlen)
      int s;
      struct sockaddr *addr;
      int *addrlen;
{
      struct n_sockaddr n_addr;
      socklen_t n_addrlen;
      int rc;

      if (ISSYSCALL(s))
            return sys_accept(s, addr, addrlen);

      n_addrlen = ADDRLEN_SET(addr, sizeof(n_addr));

      rc = Raccept(s, &n_addr, &n_addrlen);

      if (rc != -1)
            SOCKADDR_COPYRES(&n_addr, &n_addrlen, addr, addrlen);

      return rc;
}

int
getpeername(s, name, namelen)
      int s;
      struct sockaddr *name;
      int *namelen;
{
      struct n_sockaddr n_name;
      socklen_t n_namelen;
      int rc;

      if (ISSYSCALL(s))
            return sys_getpeername(s, name, namelen);

      n_namelen = ADDRLEN_SET(name, sizeof(n_name));

      rc = Rgetpeername(s, &n_name, &n_namelen);

      if (rc != -1)
            SOCKADDR_COPYRES(&n_name, &n_namelen, name, namelen);

      return rc;
}

int
getsockname(s, name, namelen)
      int s;
      struct sockaddr *name;
      int *namelen;
{
      struct n_sockaddr n_name;
      socklen_t n_namelen;
      int rc;

      if (ISSYSCALL(s))
            return sys_getsockname(s, name, namelen);

      n_namelen = ADDRLEN_SET(name, sizeof(n_name));

      rc = Rgetsockname(s, &n_name, &n_namelen);

      if (rc != -1)
            SOCKADDR_COPYRES(&n_name, &n_namelen, name, namelen);

      return rc;
}

int
recvfrom(s, buf, len, flags, from, fromlen)
      int s;
      void *buf;
      int len;
      int flags;
      struct sockaddr *from;
      int *fromlen;
{
      struct n_sockaddr n_from;
      socklen_t n_fromlen;
      ssize_t rc;

      if (ISSYSCALL(s))
            return sys_recvfrom(s, buf, len, flags, from, fromlen);

      n_fromlen = ADDRLEN_SET(from, sizeof(n_from));

      rc = Rrecvfrom(s, buf, len, flags, (struct n_sockaddr *)&n_from, &n_fromlen);

      if (rc != -1)
            SOCKADDR_COPYRES(&n_from, &n_fromlen, from, fromlen);

      return rc;
}

int
recvmsg(s, msg, flags)
      int s;
      struct msghdr *msg;
      int flags;
{
      struct n_msghdr n_msg;
      ssize_t rc;

      if (ISSYSCALL(s))
            return sys_recvmsg(s, msg, flags);

      bzero((char *)&n_msg, sizeof(struct n_msghdr));
      n_msg.msg_name = msg->msg_name;
      n_msg.msg_namelen = msg->msg_namelen;
      n_msg.msg_iov = msg->msg_iov;
      n_msg.msg_iovlen = msg->msg_iovlen;
      /* XXX msg_control/msg_accrights */

      rc = Rrecvmsg(s, &n_msg, flags);

      if (rc != -1) {
            msg->msg_name = n_msg.msg_name;
            msg->msg_namelen = n_msg.msg_namelen;
            msg->msg_iov = n_msg.msg_iov;
            msg->msg_iovlen = n_msg.msg_iovlen;
            /* XXX msg_control / msg_accrights */
            if (n_msg.msg_controllen != 0)
                  swarn("warning: msg_accrights/controllen conversion not supported");
      }

      return rc;
}

int
sendmsg(s, msg, flags)
      int s;
      struct msghdr *msg;
      int flags;
{
      struct n_msghdr n_msg;
      ssize_t rc;

      if (ISSYSCALL(s))
            return sys_sendmsg(s, msg, flags);

      bzero((char *)&n_msg, sizeof(struct n_msghdr));
      n_msg.msg_name = msg->msg_name;
      n_msg.msg_namelen = msg->msg_namelen;
      n_msg.msg_iov = msg->msg_iov;
      n_msg.msg_iovlen = msg->msg_iovlen;
      /* XXX msg_control/msg_accrights */
      if  (msg->msg_accrightslen != 0)
            swarn("warning: msg_accrights/controllen conversion not supported");


      rc = Rsendmsg(s, (struct n_msghdr *)&n_msg, flags);

      if (rc != -1) {
            msg->msg_name = n_msg.msg_name;
            msg->msg_namelen = n_msg.msg_namelen;
            msg->msg_iov = n_msg.msg_iov;
            msg->msg_iovlen = n_msg.msg_iovlen;
            /* XXX msg_control / msg_accrights */
      }

      return rc;
}

int
connect(s, name, namelen)
      int s;
      const struct sockaddr *name;
      int namelen;
{
      struct n_sockaddr n_name;
      int n_namelen;

      if (ISSYSCALL(s))
            return sys_connect(s, name, namelen);

      SOCKADDR_COPYPARAM(name, &namelen, &n_name, &n_namelen);

      return Rconnect(s, &n_name, n_namelen);
}

int
bind(s, name, namelen)
      int s;
      const struct sockaddr *name;
      int namelen;
{
      struct n_sockaddr n_name;
      int n_namelen;

      if (ISSYSCALL(s))
            return sys_bind(s, name, namelen);

      SOCKADDR_COPYPARAM(name, &namelen, &n_name, &n_namelen);

      return Rbind(s, &n_name, n_namelen);
}

int
sendto(s, msg, len, flags, to, tolen)
      int s;
      const void *msg;
      int len;
      int flags;
      const struct sockaddr *to;
      int tolen;
{
      struct n_sockaddr n_to;
      int n_tolen;

      if (ISSYSCALL(s))
            return sys_sendto(s, msg, len, flags, to, tolen);

      SOCKADDR_COPYPARAM(to, &tolen, &n_to, &n_tolen);

      return Rsendto(s, msg, len, flags, &n_to, n_tolen);
}

ssize_t
writev(d, iov, iovcnt)
      int d;
      const struct iovec *iov;
      int iovcnt;
{
      if (ISSYSCALL(d))
            return sys_writev(d, iov, iovcnt);

      return Rwritev(d, iov, iovcnt);
}

ssize_t
readv(d, iov, iovcnt)
      int d;
      const struct iovec *iov;
      int iovcnt;
{
      if (ISSYSCALL(d))
            return sys_readv(d, iov, iovcnt);

      return Rreadv(d, iov, iovcnt);
}

#endif /* SOCKSLIBRARY_DYNAMIC */

#endif /* HAVE_EXTRA_OSF_SYMBOLS */

Generated by  Doxygen 1.6.0   Back to index