rbb         99/06/14 12:11:18

  Added:       apr/network_io/win32 network_io.def network_io.dsp
                        networkio.h poll.c sendrecv.c sockets.c sockopt.c
  Log:
  First pass at Windows Network I/O.  Couldn't get WSARecv to work, but I am 
still working
  on it.  This mostly works, and it provides a select implementation that 
mimics poll.  Not
  sure the select works yet, but it's close.  I'll update it as soon as I fix 
the rest of the
  bugs.
  
  Revision  Changes    Path
  1.1                  apache-apr/apr/network_io/win32/network_io.def
  
  Index: network_io.def
  ===================================================================
  ; network_io.def : 
  
  LIBRARY network_io
  DESCRIPTION ''
  
  EXPORTS
        ; Add new API calls to the end of this list.
      ap_create_tcp_socket   @1
      ap_shutdown   @2
      ap_close_socket   @3
      ap_bind   @4
      ap_listen   @5
      ap_accept   @6
      ap_connect   @7
      ap_get_remote_hostname   @8
      ap_gethostname   @9
      ap_send   @10
      ap_recv   @11
      ap_setsocketopt   @12
      ap_setport   @13
      ap_setup_poll   @14
      ap_poll   @15
      ap_add_poll_socket   @16
      ap_get_revents   @17
  
  
  
  1.1                  apache-apr/apr/network_io/win32/network_io.dsp
  
  Index: network_io.dsp
  ===================================================================
  # Microsoft Developer Studio Project File - Name="network_io" - Package 
Owner=<4>
  # Microsoft Developer Studio Generated Build File, Format Version 5.00
  # ** DO NOT EDIT **
  
  # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
  
  CFG=network_io - Win32 Debug
  !MESSAGE This is not a valid makefile. To build this project using NMAKE,
  !MESSAGE use the Export Makefile command and run
  !MESSAGE 
  !MESSAGE NMAKE /f "network_io.mak".
  !MESSAGE 
  !MESSAGE You can specify a configuration when running NMAKE
  !MESSAGE by defining the macro CFG on the command line. For example:
  !MESSAGE 
  !MESSAGE NMAKE /f "network_io.mak" CFG="network_io - Win32 Debug"
  !MESSAGE 
  !MESSAGE Possible choices for configuration are:
  !MESSAGE 
  !MESSAGE "network_io - Win32 Release" (based on\
   "Win32 (x86) Dynamic-Link Library")
  !MESSAGE "network_io - Win32 Debug" (based on\
   "Win32 (x86) Dynamic-Link Library")
  !MESSAGE 
  
  # Begin Project
  # PROP Scc_ProjName ""
  # PROP Scc_LocalPath ""
  CPP=cl.exe
  MTL=midl.exe
  RSC=rc.exe
  
  !IF  "$(CFG)" == "network_io - Win32 Release"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 0
  # PROP BASE Output_Dir "Release"
  # PROP BASE Intermediate_Dir "Release"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir "Release"
  # PROP Intermediate_Dir "Release"
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" 
/YX /FD /c
  # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX 
/FD /c
  # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
  # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
  # ADD BASE RSC /l 0x409 /d "NDEBUG"
  # ADD RSC /l 0x409 /d "NDEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
  # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
  
  !ELSEIF  "$(CFG)" == "network_io - Win32 Debug"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir "Debug"
  # PROP BASE Intermediate_Dir "Debug"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir "Debug"
  # PROP Intermediate_Dir "Debug"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D 
"_WINDOWS" /YX /FD /c
  # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /I 
"..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
  # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
  # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
  # ADD BASE RSC /l 0x409 /d "_DEBUG"
  # ADD RSC /l 0x409 /d "_DEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
  # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib 
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib 
odbccp32.lib  ws2_32.lib ..\..\lib\Debug\lib.lib 
..\..\misc\win32\Debug\misc.lib /nologo /subsystem:windows /dll /debug 
/machine:I386 /pdbtype:sept
  
  !ENDIF 
  
  # Begin Target
  
  # Name "network_io - Win32 Release"
  # Name "network_io - Win32 Debug"
  # Begin Source File
  
  SOURCE=.\network_io.def
  # End Source File
  # Begin Source File
  
  SOURCE=.\networkio.h
  # End Source File
  # Begin Source File
  
  SOURCE=.\poll.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\sendrecv.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\sockets.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\sockopt.c
  # End Source File
  # End Target
  # End Project
  
  
  
  1.1                  apache-apr/apr/network_io/win32/networkio.h
  
  Index: networkio.h
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1999 The Apache Group.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED 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 APACHE GROUP OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  #ifndef NETWORK_IO_H
  #define NETWORK_IO_H
  
  #include "apr_network_io.h"
  #include "apr_general.h"
  
  struct socket_t {
      ap_context_t *cntxt;
      SOCKET sock;
      char *remote_hostname;
      struct sockaddr_in *addr;
      size_t addr_len;
  };
  
  struct pollfd_t {
      ap_context_t *cntxt;
      fd_set read;
      fd_set write;
      fd_set except;
      
  };
  
  #endif  /* ! NETWORK_IO_H */
  
  
  
  
  1.1                  apache-apr/apr/network_io/win32/poll.c
  
  Index: poll.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1999 The Apache Group.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED 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 APACHE GROUP OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  #include "networkio.h"
  #include "apr_network_io.h"
  #include "apr_general.h"
  #include "apr_lib.h"
  #include <errno.h>
  #include <windows.h>
  #include <time.h>
  
  
  ap_status_t ap_setup_poll(ap_context_t *cont, ap_int32_t num, struct pollfd_t 
**new)
  {
      (*new) = (struct pollfd_t *)ap_palloc(cont, sizeof(struct pollfd_t) * 
num);
      if ((*new) == NULL) {
          return APR_ENOMEM;
      }
      (*new)->cntxt = cont;
      FD_ZERO(&(*new)->read);
      FD_ZERO(&(*new)->write);
      FD_ZERO(&(*new)->except);
      return APR_SUCCESS;
  }
  
  ap_status_t ap_add_poll_socket(struct pollfd_t *aprset, 
                               struct socket_t *sock, ap_int16_t event)
  {
      if (event & APR_POLLIN) {
          FD_SET(sock->sock, &aprset->read);
      }
      if (event & APR_POLLPRI) {
          FD_SET(sock->sock, &aprset->read);
      }
      if (event & APR_POLLOUT) {
          FD_SET(sock->sock, &aprset->write);
      }
      if (event & APR_POLLERR) {
          FD_SET(sock->sock, &aprset->except);
      }
      if (event & APR_POLLHUP) {
          FD_SET(sock->sock, &aprset->except);
      }
      if (event & APR_POLLNVAL) {
          FD_SET(sock->sock, &aprset->except);
      }
      return APR_SUCCESS;
  }
  
  ap_status_t ap_poll(struct pollfd_t *aprset, ap_int32_t *nsds, ap_int32_t 
timeout)
  {
      int rv;
      struct timeval *thetime;
  
      if (timeout == -1) {
          thetime = NULL;
      }
      else {
          /* Convert milli-seconds into seconds and micro-seconds. */
          thetime = (struct timeval *)ap_palloc(aprset->cntxt, sizeof(struct 
timeval));
          thetime->tv_sec = timeout / (1000);
          timeout = timeout % 1000;
          thetime->tv_usec = timeout * 1000;
      }
  
      rv = select(500, &aprset->read, &aprset->read, &aprset->read, 
                  thetime);
  
      (*nsds) = rv;    
      if ((*nsds) < 0) {
          return APR_EEXIST;
      }
      return APR_SUCCESS;
  }
  
  ap_status_t ap_get_revents(struct pollfd_t *aprset, struct socket_t *sock, 
ap_int16_t *event)
  {
      ap_int16_t revents = 0;
      WSABUF data;
      int dummy;
      int flags = MSG_PEEK;
  
      /* We just want to PEEK at the data, so I am setting up a dummy WSABUF
       * variable here.
       */
      data.len = 256;
      data.buf = (char *)ap_palloc(aprset->cntxt, 256);
  
      if (FD_ISSET(sock->sock, &aprset->read)) {
          revents |= APR_POLLIN;
          if (WSARecv(sock->sock, &data, 1, &dummy, &flags, NULL, 
                      NULL) == SOCKET_ERROR) {
              dummy = WSAGetLastError();
              switch (dummy) {
                  case WSAECONNRESET:
                  case WSAECONNABORTED:
                  case WSAESHUTDOWN:
                  case WSAENETRESET: {
                      revents ^= APR_POLLIN;
                      revents |= APR_POLLHUP;
                      break;
                  }
                  case WSAENOTSOCK: {
                      revents ^= APR_POLLIN;
                      revents |= APR_POLLNVAL;
                  }
                  default: {
                      revents ^= APR_POLLIN;
                      revents |= APR_POLLERR;
                  }
              }
          }
      }
      if (FD_ISSET(sock->sock, &aprset->write)) {
          revents |= APR_POLLOUT;
      }
      /* I am assuming that the except is for out of band data, not a failed
       * connection on a non-blocking socket.  Might be a bad assumption, but
       * it works for now. rbb.
       */
      if (FD_ISSET(sock->sock, &aprset->except)) {
          revents |= APR_POLLPRI;
      }
  
      (*event) = revents;
      return APR_SUCCESS;
  }
   
  
  
  
  1.1                  apache-apr/apr/network_io/win32/sendrecv.c
  
  Index: sendrecv.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1996-1999 The Apache Group.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED 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 APACHE GROUP OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group and was originally based
   * on public domain software written at the National Center for
   * Supercomputing Applications, University of Illinois, Urbana-Champaign.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  #include "networkio.h"
  #include "apr_errno.h"
  #include "apr_general.h"
  #include "apr_network_io.h"
  #include "apr_lib.h"
  #include <time.h>
  
  ap_status_t ap_send(struct socket_t *sock, const char *buf, ap_ssize_t *len, 
time_t sec)
  {
      ap_ssize_t rv;
      WSABUF data;
      int lasterror;    
  
      data.len = *len;
      data.buf = ap_pstrdup(sock->cntxt, buf);
      do {
          rv = WSASend(sock->sock, &data, 1, len, 0, NULL, NULL);
          if (rv == SOCKET_ERROR) {
              lasterror = WSAGetLastError();
          } 
      } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  
      if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && sec > 0) {
          struct timeval tv;
          fd_set fdset;
          int srv;
  
          do {
              FD_ZERO(&fdset);
              FD_SET(sock->sock, &fdset);
              tv.tv_sec  = sec;
              tv.tv_usec = 0;
  
              srv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
              if (srv == SOCKET_ERROR) {
                  lasterror = WSAGetLastError();
              }
          } while (srv == SOCKET_ERROR && errno == WSAEINTR);
  
          if (srv == 0) {
              (*len) = -1;
              return APR_TIMEUP;
          }
          if (srv < 0) {
              (*len) = -1;
              return APR_EEXIST;
          }
          else {
              do {
                  rv = WSASend(sock->sock, &data, 1, len, 0, NULL, NULL);
                  if (rv == SOCKET_ERROR) {
                      lasterror = WSAGetLastError();
                  } 
              } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
          }
      }
      return APR_SUCCESS;
  }
  
  ap_status_t ap_recv(struct socket_t *sock, char *buf, ap_ssize_t *len, time_t 
sec)
  {
      ap_ssize_t rv;
      int lasterror;
  
      do {
          rv = recv(sock->sock, buf, *len, 0);
          if (rv == SOCKET_ERROR) {
              lasterror = WSAGetLastError();
          } 
      } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
  
      if (rv == SOCKET_ERROR && lasterror == WSAEWOULDBLOCK && sec > 0) {
          struct timeval tv;
          fd_set fdset;
          int srv;
  
          do {
              FD_ZERO(&fdset);
              FD_SET(sock->sock, &fdset);
              tv.tv_sec  = sec;
              tv.tv_usec = 0;
  
              srv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
              if (srv == SOCKET_ERROR) {
                  lasterror = WSAGetLastError();
              } 
          } while (srv == SOCKET_ERROR && errno == WSAEINTR);
  
          if (srv == 0) {
              (*len) = -1;
              return APR_TIMEUP;
          }
          else if (srv < 0) {
              (*len) = -1;
              return errno;
          }
          else {
              do {
                  rv = recv(sock->sock, buf, *len, 0);
                  if (rv == SOCKET_ERROR) {
                      lasterror = WSAGetLastError();
                  } 
              } while (rv == SOCKET_ERROR && lasterror == WSAEINTR);
          }
      }
      (*len) = rv;
      return APR_SUCCESS;
  }
  
  
  
  
  1.1                  apache-apr/apr/network_io/win32/sockets.c
  
  Index: sockets.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1999 The Apache Group.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED 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 APACHE GROUP OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  #include "networkio.h"
  #include "apr_network_io.h"
  #include "apr_general.h"
  #include "apr_lib.h"
  #include <string.h>
  #include <winsock2.h>
  #include <windows.h>
  
  
  ap_status_t socket_cleanup(void *sock)
  {
      struct socket_t *thesocket = sock;
      if (closesocket(thesocket->sock) != SOCKET_ERROR) {
          thesocket->sock = INVALID_SOCKET;
          return APR_SUCCESS;
      }
      else {
          return APR_EEXIST;
      }
  }
  
  ap_status_t ap_create_tcp_socket(ap_context_t *cont, struct socket_t **new)
  {
      (*new) = (struct socket_t *)ap_palloc(cont, sizeof(struct socket_t));
  
      if ((*new) == NULL) {
          return APR_ENOMEM;
      }
      (*new)->cntxt = cont; 
      (*new)->addr = (struct sockaddr_in *)ap_pcalloc((*new)->cntxt,
                         sizeof(struct sockaddr_in));
  
      if ((*new)->addr == NULL) {
          return APR_ENOMEM;
      }
      /* For right now, we are not using socket groups.  We may later.
       * No flags to use when creating a socket, so use 0 for that parameter as 
well.
       */
      (*new)->sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
      (*new)->remote_hostname = NULL;
  
      (*new)->addr->sin_family = AF_INET;
  
      (*new)->addr_len = sizeof(*(*new)->addr);
  
      (*new)->addr->sin_port = 0;   
   
      if ((*new)->sock == INVALID_SOCKET) {
          return APR_EEXIST;
      }
      ap_register_cleanup((*new)->cntxt, (void *)(*new), 
                          socket_cleanup, NULL);
      return APR_SUCCESS;
  } 
  
  ap_status_t ap_shutdown(struct socket_t *thesocket, ap_shutdown_how_e how)
  {
      int winhow;
  
      switch (how) {
          case APR_SHUTDOWN_READ: {
              winhow = SD_RECEIVE;
              break;
          }
          case APR_SHUTDOWN_WRITE: {
              winhow = SD_SEND;
              break;
          }
          case APR_SHUTDOWN_READWRITE: {
              winhow = SD_BOTH;
              break;
          }
      }
      if (shutdown(thesocket->sock, winhow) == 0) {
          return APR_SUCCESS;
      }
      else {
          return APR_EEXIST;
      }
  }
  
  ap_status_t ap_close_socket(struct socket_t *thesocket)
  {
      ap_kill_cleanup(thesocket->cntxt, thesocket, socket_cleanup);
      return socket_cleanup(thesocket);
  }
  
  ap_status_t ap_setport(struct socket_t *sock, ap_uint32_t port)
  {
      if (WSAHtons(sock->sock, (short)port, &sock->addr->sin_port) != 0) {
          return APR_EEXIST;
      }
      return APR_SUCCESS;
  }
  
  ap_status_t ap_bind(struct socket_t *sock)
  {
      sock->addr->sin_addr.s_addr = INADDR_ANY;
      if (bind(sock->sock, (struct sockaddr *)sock->addr, sock->addr_len) == 
-1) {
          return errno;
      }
      else
          return APR_SUCCESS;
  }
  
  ap_status_t ap_listen(struct socket_t *sock, ap_int32_t backlog)
  {
      if (listen(sock->sock, backlog) == SOCKET_ERROR)
          return APR_EEXIST;
      else
          return APR_SUCCESS;
  }
  
  ap_status_t ap_accept(const struct socket_t *sock, struct socket_t **new)
  {
      struct hostent *hptr;
      
    
      (*new) = (struct socket_t *)ap_palloc(sock->cntxt, 
                              sizeof(struct socket_t));
  
      (*new)->cntxt = sock->cntxt;
      (*new)->addr = (struct sockaddr_in *)ap_palloc((*new)->cntxt, 
                   sizeof(struct sockaddr_in));
      (*new)->addr_len = sizeof(struct sockaddr_in);
  
      (*new)->sock = WSAAccept(sock->sock, (struct sockaddr *)(*new)->addr,
                          &(*new)->addr_len, NULL, 0);
  
      if ((*new)->sock == INVALID_SOCKET) {
          return errno;
      }
      
      hptr = gethostbyaddr((char *)&(*new)->addr->sin_addr, 
                           sizeof(struct in_addr), AF_INET);
      if (hptr != NULL) {
          (*new)->remote_hostname = strdup(hptr->h_name);
      }
      
      ap_register_cleanup((*new)->cntxt, (void *)(*new), 
                          socket_cleanup, NULL);
      return APR_SUCCESS;
  }
  
  ap_status_t ap_connect(struct socket_t *sock, char *hostname)
  {
      struct hostent *hp;
      int lasterror;
  
      if ((sock->sock == INVALID_SOCKET) || (!sock->addr)) {
          return APR_ENOTSOCK;
      }
  
      if (*hostname >= '0' && *hostname <= '9' && 
          strspn(hostname, "0123456789.") == strlen(hostname)) {
          sock->addr->sin_addr.s_addr = inet_addr(hostname);
      }
      else {
          hp = gethostbyname(hostname);
          memcpy((char *)&sock->addr->sin_addr, hp->h_addr_list[0], 
hp->h_length);
          sock->addr_len = sizeof(*sock->addr);
          if (!hp)  {
              if (h_errno == TRY_AGAIN) {
                  return EAGAIN;
              }
              return h_errno;
          }
      }
      
      sock->addr->sin_family = AF_INET;
  
      if (WSAConnect(sock->sock, (const struct sockaddr *)sock->addr, 
sock->addr_len,
                      NULL, NULL, NULL, NULL) == 0) {
          sock->remote_hostname = strdup(hostname);
          return APR_SUCCESS;
      }
      else {
          lasterror = WSAGetLastError();
          return APR_EEXIST;
      }
  }
  
  
  
  
  1.1                  apache-apr/apr/network_io/win32/sockopt.c
  
  Index: sockopt.c
  ===================================================================
  /* ====================================================================
   * Copyright (c) 1999 The Apache Group.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * 4. The names "Apache Server" and "Apache Group" must not be used to
   *    endorse or promote products derived from this software without
   *    prior written permission. For written permission, please contact
   *    [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Apache Group
   *    for use in the Apache HTTP server project (http://www.apache.org/)."
   *
   * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
   * EXPRESSED 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 APACHE GROUP OR
   * ITS 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Group.
   * For more information on the Apache Group and the Apache HTTP server
   * project, please see <http://www.apache.org/>.
   *
   */
  
  #include "networkio.h"
  #include "apr_network_io.h"
  #include "apr_general.h"
  #include "apr_lib.h"
  #include <string.h>
  #include <winsock2.h>
  
  ap_status_t soblock(SOCKET sd)
  {
      int one = 1;
  
      if (ioctlsocket(sd, FIONBIO, &one) == SOCKET_ERROR) {
          return APR_EEXIST;
      }
      return APR_SUCCESS;
  }
  
  ap_status_t sononblock(SOCKET sd)
  {
      int zero = 0;
  
      if (ioctlsocket(sd, FIONBIO, &zero) == SOCKET_ERROR) {
          return APR_EEXIST;
      }
      return APR_SUCCESS;
  }
  
  ap_status_t ap_setsocketopt(struct socket_t *sock, ap_int32_t opt, ap_int32_t 
on)
  {
      int one;
      struct linger li;
      ap_status_t stat;
  
      if (on)
          one = 1;
      else
          one = 0;
  
      if (opt & APR_SO_KEEPALIVE) {
          if (setsockopt(sock->sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&one, 
sizeof(int)) == -1) {
              return APR_EEXIST;
          }
      }
      if (opt & APR_SO_DEBUG) {
          if (setsockopt(sock->sock, SOL_SOCKET, SO_DEBUG, (void *)&one, 
sizeof(int)) == -1) {
              return APR_EEXIST;
          }
      }
      if (opt & APR_SO_REUSEADDR) {
          if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, 
sizeof(int)) == -1) {
              return APR_EEXIST;
          }
      }
      if (opt & APR_SO_NONBLOCK) {
          if (on) {
              if ((stat = soblock(sock->sock)) != APR_SUCCESS) 
                  return stat;
          }
          else {
              if ((stat = sononblock(sock->sock)) != APR_SUCCESS)
                  return stat;
          }
      }
      if (opt & APR_SO_LINGER) {
          li.l_onoff = on;
          li.l_linger = MAX_SECS_TO_LINGER;
          if (setsockopt(sock->sock, SOL_SOCKET, SO_LINGER, (char *) &li, 
sizeof(struct linger)) == -1) {
              return APR_EEXIST;
          }
      }
      return APR_SUCCESS;
  }         
  
  ap_status_t ap_gethostname(ap_context_t *cont, char *buf, int len)
  {
      if (gethostname(buf, len) == -1)
          return APR_EEXIST;
      else
          return APR_SUCCESS;
  }
  
  ap_status_t ap_get_remote_hostname(struct socket_t *sock, char **name)
  {
      (*name) = ap_pstrdup(sock->cntxt, sock->remote_hostname);
      if (*name) {
          return APR_SUCCESS;
      }
      return APR_ENOMEM;
  }
  
  
  
  
  

Reply via email to