/*----------------------------------------------------------------------------*/
/*                                                                            */
/*  Copyright (c) 1996 - 2001 by                                              */
/*  blaxxun interactive Inc, San Francisco, California, USA                   */
/*  All rights reserved                                                       */
/*                                                                            */
/*  This software is furnished under a license  and may be  used and  copied  */
/*  only in  accordance of the  terms of such license and with the inclusion  */
/*  of the above copyright notice.  This software or any other copies therof  */
/*  may not be provided or otherwise made available to any other person.  No  */
/*  title to and ownership of the software is hereby transferred.             */
/*                                                                            */
/*  The information in this software is subject to change without notice and  */
/*  should not be construed as a commitment by blaxxun interactive Inc.       */
/*                                                                            */
/*----------------------------------------------------------------------------*/

/*
------------------------------------------------------------------------------

  MODULE NAME:  $RCSfile: raevent.c,v $
  REVISION:     $Revision: 1.7 $
  DATE:         $Date: 2001/02/15 17:47:37 $
  AUTHOR:       $Author: peter $
  STATE:        $State: Exp $

  CREATION DATE:       Jan 24, 1998

  =DocStart= Module raevent.c
  File raevent.c

  PROJECT:            VWP         - blaxxun virtual worlds platform
  SYSTEM:             server      - server processes
  COMPONENT:          apserver    - Community Server API server

  DESCRIPTION:
      Event functions called. The functions given in this file are
      examples for the Event Functions of the Interface.

      Customize them to your own needs.

  =DocEnd=

  MODIFICATION HISTORY:
------------------------------------------------------------------------------
*/

/*----------------------------------------------------------------------------*/
/*             LOCAL INCLUDE FILES                                            */
/*----------------------------------------------------------------------------*/
#include "raextern.h"

/*----------------------------------------------------------------------------*/
/*             MODULE VARIABLE DECLARATIONS                                   */
/*----------------------------------------------------------------------------*/

#if !defined (lint)
static char rcsid[] = "@(#) $Id: raevent.c,v 1.7 2001/02/15 17:47:37 peter Exp $";

/*
 * the following function is needed to suppress compiler warnings, don't call it
 */
static void rcsid_fkt()
{
    if( ! *rcsid )
        *rcsid = 0;
    if( 0 )
        rcsid_fkt();
}
#endif

/*----------------------------------------------------------------------------*/
/*             FUNCTIONS                                                      */
/*----------------------------------------------------------------------------*/

/*  =DocStart= Function raEventStartup
------------------------------------------------------------------------------
  FUNCTION NAME:        raEventStartup

  DESCRIPTION:
    This function is called when the RA server is started.

  NOTE: In order to make the process run correctly on NT this function must
        not perform any exits, use a return code of 110 or higher as the
        example does.

  RESTRICTION:
        In case the remote access library is linked into an apserver,
        this function is NOT called. The API server only calls its
        own startup event chEventStartup.

  RETURN VALUES:
    int rc == 0: ok process started successfully
        rc != 0: the startup failed, the process will go down with
                 the exitcode returned

------------------------------------------------------------------------------
*/
int raEventStartup(
int        argc,            /* number of parameters             */
char      *argv[]           /* comamnd line parameters          */
)
/*  =DocEnd= */
{
    int        rc = 0;

    PROCESS_LOG(( "RA.EV raEventStartup argc %d\n", argc ));

    if( rc )
    {
        return( 110 );
    }
    return( 0 );

} /* End of Function raEventStartup */

/*  =DocStart= Function raEventShutdown
------------------------------------------------------------------------------
  FUNCTION NAME:        raEventShutdown

  DESCRIPTION:
    This function is called when the RA server is terminated.

  RESTRICTION:
        In case the remote access library is linked into an apserver,
        this function is NOT called. The API server only calls its
        own shutdown event chEventShutdown.

  RETURN VALUES:
    void

------------------------------------------------------------------------------
*/
void raEventShutdown(
int exitcode                /* return code for exit call        */
)
/*  =DocEnd= */
{
    int your_exit_code = 0;

    PROCESS_LOG(( "RA.EV raEventShutdown exitcode %d\n", exitcode ));

    /*
     * do not exit this process, do all the shutdown things you need to do.
     * if you want to change the exit status of the program do so by setting
     * the global process_exitrc
     */
    if( your_exit_code )
    {
        process_exitrc = your_exit_code;
    }

    return;

} /* End of Function raEventShutdown */

/*  =DocStart= Function raEventPeriodic
------------------------------------------------------------------------------
  FUNCTION NAME:        raEventPeriodic

  DESCRIPTION:
    This function is called periodically.
   
    The default is every 60 seconds, the default can be changed by 
    calling raSetPeriod.

    The minimum value possible for period is 100000 microseconds.

  RESTRICTION:
        In case the remote access library is linked into an apserver,
        this function is NOT called. The API server only calls its
        own periodic event chEventPeriodic.

  RETURN VALUES:
    void

------------------------------------------------------------------------------
*/
void raEventPeriodic(
struct timeval * now                    /* time when function was called    */
)
/*  =DocEnd= */
{
    PROCESS_LOG(( "RA.LOG raEventPeriodic called.\n" ));

    return;

} /* End of Function raEventPeriodic */

/*  =DocStart= Function raEventUdpRequest
------------------------------------------------------------------------------
  FUNCTION NAME:        raEventUdpRequest

  DESCRIPTION:
    This function is called whenever a UDP client request comes in.
   
    Use the server api call raGetArg to retrieve the arguments one by
    one.

    And use raSetResult to set result strings for the client application.

    At least one result string has to be set, otherwise the client api
    call returns with the error RA_ERR_DENIED.

  RETURN VALUES:
    void

------------------------------------------------------------------------------
*/
void raEventUdpRequest(
char            *client,        /* client that sent the request     */
int              inargc,        /* number of arguments sent         */
char            *inargv[]       /* pointerarray of arguments sent   */
)
/*  =DocEnd= */
{
    int i;
    char *ptr;
    PROCESS_LOG(( "RA.LOG raEventUdpRequest %d args.\n", inargc ));

    /*
     * we just log the arguments we got
     */
    for( i = 0; i < inargc; i++ )
    {
        ptr = raGetArg( client, i );
        if( !ptr )
        {
            ptr = "NULL";
        }
        PROCESS_LOG(( "argv[ %d ] = \"%s\"\n", i, ptr ));
    }
    
    /*
     * for now we echo the arguments if the first argument is "echo"
     */
    ptr = raGetArg( client, 0 );
    if( ptr && ( 0 == strcmp( ptr, "echo" )))
    {
        for( i = 0; i < inargc; i++ )
        {
            ptr = raGetArg( client, i );
            if( !ptr )
            {
                break;
            }
            raSetResult( client, ptr );
        }
    }
    else if( ptr && ( 0 == strcmp( ptr, "ok" )))
    {
        raSetResult( client, ptr );
    }

    /*
     * we deny all other requests by doing nothing!
     */

    return;

} /* End of Function raEventUdpRequest */

/*  =DocStart= Function raEventHttpRequest
------------------------------------------------------------------------------
  FUNCTION NAME:        raEventHttpRequest

  DESCRIPTION:
    This function is called whenever a Http client request comes in.
   
    And use raSetHttpResult to set result strings for the client application.

    At least one result string has to be set, otherwise the client api
    call returns with the error RA_ERR_DENIED.

  RETURN VALUES:
    void

------------------------------------------------------------------------------
*/
void raEventHttpRequest(
char  *connection               /* r: connection that sent the request  */
)
/*  =DocEnd= */
{
    char * url = NULL;
    size_t urllen = 0;
    char * header = NULL;
    size_t headerlen = 0;
    char * content = NULL;
    size_t contentlen = 0;

    /*
     * read the url used for the request
     */
    url = raGetHttpUrl( connection, &urllen );

    PROCESS_LOG(( "RA.LOG raEventHttpRequest %s:%d Url: %.*s\n",
                  raIp2Str( raGetHttpClientIp( connection )),
                  ntohs( raGetHttpClientPort(  connection )),
                  urllen, url ));

    /*
     * read header and content, they are only given in the POST case
     */
    header = raGetHttpHeader( connection, &headerlen );
    content = raGetHttpContent( connection, &contentlen );
    if( header )
    {
        /*
         * this is a post request, print the header
         */
        PROCESS_LOG(( "RA.LOG POST Content length %ld\n%.*s\n\n",
                      contentlen, headerlen, header ));
    }

    /*
     * for now we echo the arguments if the url starts with "/echo"
     */
    if( url )
    {
        if( 0 == strncmp( url, "/echo", strlen( "/echo" ) ))
        {
            raSetHttpResult( connection, "<HTML>\n<BODY>\n" );
            raSetHttpResult( connection, url + 5 );
        }

        /*
         * we also echo the content if it is given
         */
        if( content )
        {
            raSetHttpResult( connection, "\n" );
            raSetHttpResult( connection, content );
        }
    }

    /*
     * we deny all other requests by doing nothing!
     */
    return;

} /* End of Function raEventHttpRequest */

