modules/mi_xmlrpc/abyss_socket.c
7721f9ff
 /******************************************************************************
 **
 ** socket.c
 **
 ** This file is part of the ABYSS Web server project.
 **
 ** Copyright (C) 2000 by Moez Mahfoudh <mmoez@bigfoot.com>.
 ** 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. 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 AND CONTRIBUTORS ``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 OR 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.
 **
 *******************************************************************************/
 
 /*============================================================================
   socket.c
 ==============================================================================
   Implementation of TSocket class: A generic socket over which one can
   transport an HTTP stream or manage HTTP connections
 ============================================================================*/
 
 #include <sys/types.h>
 #include <assert.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "abyss_mallocvar.h"
 #include "abyss_xmlrpc_int.h"
 #include <xmlrpc-c/abyss.h>
 #ifdef WIN32
   #include "socket_win.h"
 #else
   #include "abyss_socket_unix.h"
 #endif
 #include "abyss_socket.h"
 
 
 #ifdef WIN32
   #include "socket_win.h"
 #else
   #include "abyss_socket_unix.h"
 #endif
 
 #include "abyss_socket.h"
 
 
 static void
 socketOsInit(abyss_bool * const succeededP) {
 
 #ifdef WIN32
     SocketWinInit(succeededP);
 #else
     SocketUnixInit(succeededP);
 #endif
 }
 
 
 
 static void
 socketOsTerm(void) {
 
 #ifdef WIN32
     SocketWinTerm();
 #else
     SocketUnixTerm();
 #endif
 }
     
 
 
 abyss_bool SocketTraceIsActive;
 
 abyss_bool
 SocketInit(void) {
     abyss_bool retval;
 
     socketOsInit(&retval);
 
     SocketTraceIsActive = (getenv("ABYSS_TRACE_SOCKET") != NULL);
     if (SocketTraceIsActive)
         fprintf(stderr, "Abyss socket layer will trace socket traffic "
                 "due to ABYSS_TRACE_SOCKET environment variable\n");
 
     return retval;
 }
 
 
 
 void
 SocketTerm(void) {
 
     socketOsTerm();
 }
 
 
 
 /* SocketCreate() is not exported to the Abyss user.  It is meant to
    be used by an implementation-specific TSocket generator which is
    exported to the Abyss user, e.g. SocketCreateUnix() in
    socket_unix.c
 
    The TSocket generator functions are the _only_ user-accessible
    functions that are particular to an implementation.
 */
 
 static uint const socketSignature = 0x060609;
 
 void
 SocketCreate(const struct TSocketVtbl * const vtblP,
              void *                     const implP,
              TSocket **                 const socketPP) {
 
     TSocket * socketP;
 
     MALLOCVAR(socketP);
 
     if (socketP) {
         socketP->implP = implP;
         socketP->vtbl = *vtblP;
         socketP->signature = socketSignature;
         *socketPP = socketP;
     }
 }
 
 
 
 void
9f6ac8e6
 SocketClose(TSocket * const socketP) {
     socketP->vtbl.close(socketP);
 }
 
 
 
 void
7721f9ff
 SocketDestroy(TSocket * const socketP) {
 
     assert(socketP->signature == socketSignature);
 
     socketP->vtbl.destroy(socketP);
 
     socketP->signature = 0;  /* For debuggability */
 
     free(socketP);
 }
 
 
 
 void
 SocketWrite(TSocket *             const socketP,
             const unsigned char * const buffer,
             uint32_t              const len,
             abyss_bool *          const failedP) {
 
     (*socketP->vtbl.write)(socketP, buffer, len, failedP );
 }
 
 
 
 uint32_t
 SocketRead(TSocket *       const socketP, 
            unsigned char * const buffer, 
            uint32_t        const len) {
     
     return (*socketP->vtbl.read)(socketP, (char*)buffer, len);
 }
 
 
 
 abyss_bool
 SocketConnect(TSocket * const socketP,
               TIPAddr * const addrP,
               uint16_t  const portNumber) {
 
     return (*socketP->vtbl.connect)(socketP, addrP, portNumber);
 }
 
 
 
 abyss_bool
 SocketBind(TSocket * const socketP,
            TIPAddr * const addrP,
            uint16_t  const portNumber) {
 
     return (*socketP->vtbl.bind)(socketP, addrP, portNumber);
 }
 
 
 
 abyss_bool
 SocketListen(TSocket * const socketP,
              uint32_t  const backlog) {
 
     return (*socketP->vtbl.listen)(socketP, backlog);
 }
 
 
 
 void
 SocketAccept(TSocket *    const listenSocketP,
              abyss_bool * const connectedP,
              abyss_bool * const failedP,
              TSocket **   const acceptedSocketPP,
              TIPAddr *    const ipAddrP) {
 
     (*listenSocketP->vtbl.accept)(listenSocketP,
                                   connectedP,
                                   failedP,
                                   acceptedSocketPP,
                                   ipAddrP);
 }
 
 
 
 uint32_t
 SocketWait(TSocket *  const socketP,
            abyss_bool const rd,
            abyss_bool const wr,
            uint32_t   const timems) {
 
     return (*socketP->vtbl.wait)(socketP, rd, wr, timems);
 }
 
 
 
 uint32_t
 SocketAvailableReadBytes(TSocket * const socketP) {
 
     return (*socketP->vtbl.availableReadBytes)(socketP);
 }
 
 
 
 void
 SocketGetPeerName(TSocket *    const socketP,
                   TIPAddr *    const ipAddrP,
                   uint16_t *   const portNumberP,
                   abyss_bool * const successP) {
 
     (*socketP->vtbl.getPeerName)(socketP, ipAddrP, portNumberP, successP);
 }
 
 
 
 uint32_t
 SocketError(TSocket * const socketP) {
 
     return (*socketP->vtbl.error)(socketP);
 }