<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mutex.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:29:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{
    /** A mutual exclusion synchronization object
    */
    class Mutex {

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
            @seealso ::osl_createMutex()
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
            @seealso ::osl_destroyMutex()
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return sal_False if system-call fails.
            @seealso ::osl_acquireMutex()
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return sal_False if it could not be acquired.
            @seealso ::osl_tryToAcquireMutex()
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return sal_False if system-call fails.
            @seealso ::osl_releaseMutex()
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        /** Returns a global static mutex object.
            The global and static mutex object can be used to initialize other
            static objects in a thread safe manner.
            @return the global mutex object
            @seealso ::osl_getGlobalMutex()
        */
        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }

    private:
        oslMutex mutex;

        /** The underlying oslMutex has no reference count.

        Since the underlying oslMutex is not a reference counted object, copy
        constructed Mutex may work on an already destructed oslMutex object.

        */
        Mutex(const Mutex&);

        /** The underlying oslMutex has no reference count.

        When destructed, the Mutex object destroys the undelying oslMutex,
        which might cause severe problems in case it's a temporary object.

        */
        Mutex(oslMutex Mutex);

        /** This assignment operator is private for the same reason as
            the copy constructor.
        */
        Mutex& operator= (const Mutex&);

        /** This assignment operator is private for the same reason as
            the constructor taking a oslMutex argument.
        */
        Mutex& operator= (oslMutex);
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class Guard
    {
    private:
        Guard( const Guard& );
        const Guard& operator = ( const Guard& );

    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        Guard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface. */
        ~Guard()
        {
            pT->release();
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class ClearableGuard
    {
    private:
        ClearableGuard( const ClearableGuard& );
        const ClearableGuard& operator = ( const ClearableGuard& );
    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface if not already released by clear().
        */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases the mutex or interface.
        */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    protected:
        T* pResetT;
    public:
        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T* pT ) :
                ClearableGuard<T>( pT ),
                pResetT( pT )
        {}

        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T& rT ) :
                ClearableGuard<T>( rT ),
                pResetT( &rT )
        {}

        /** Re-aquires the mutex or interface.
        */
        void reset()
        {
            if( pResetT )
            {
                this->pT = pResetT;
                this->pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

<commit_msg>INTEGRATION: CWS warnings01 (1.11.122); FILE MERGED 2005/11/07 12:11:25 sb 1.11.122.3: #i53898# Made code warning-free (additional -W switches for GCC). 2005/09/23 00:35:06 sb 1.11.122.2: RESYNC: (1.11-1.12); FILE MERGED 2005/09/20 12:57:14 sb 1.11.122.1: #i53898# Globally disable problematic warnings.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: mutex.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 04:12:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OSL_MUTEX_HXX_
#define _OSL_MUTEX_HXX_

#ifdef __cplusplus

#include <osl/mutex.h>

namespace osl
{
    /** A mutual exclusion synchronization object
    */
    class Mutex {

    public:
        /** Create a thread-local mutex.
            @return 0 if the mutex could not be created, otherwise a handle to the mutex.
            @seealso ::osl_createMutex()
        */
        Mutex()
        {
            mutex = osl_createMutex();
        }

        /** Release the OS-structures and free mutex data-structure.
            @seealso ::osl_destroyMutex()
        */
        ~Mutex()
        {
            osl_destroyMutex(mutex);
        }

        /** Acquire the mutex, block if already acquired by another thread.
            @return sal_False if system-call fails.
            @seealso ::osl_acquireMutex()
        */
        sal_Bool acquire()
        {
            return osl_acquireMutex(mutex);
        }

        /** Try to acquire the mutex without blocking.
            @return sal_False if it could not be acquired.
            @seealso ::osl_tryToAcquireMutex()
        */
        sal_Bool tryToAcquire()
        {
            return osl_tryToAcquireMutex(mutex);
        }

        /** Release the mutex.
            @return sal_False if system-call fails.
            @seealso ::osl_releaseMutex()
        */
        sal_Bool release()
        {
            return osl_releaseMutex(mutex);
        }

        /** Returns a global static mutex object.
            The global and static mutex object can be used to initialize other
            static objects in a thread safe manner.
            @return the global mutex object
            @seealso ::osl_getGlobalMutex()
        */
        static Mutex * getGlobalMutex()
        {
            return (Mutex *)osl_getGlobalMutex();
        }

    private:
        oslMutex mutex;

        /** The underlying oslMutex has no reference count.

        Since the underlying oslMutex is not a reference counted object, copy
        constructed Mutex may work on an already destructed oslMutex object.

        */
        Mutex(const Mutex&);

        /** The underlying oslMutex has no reference count.

        When destructed, the Mutex object destroys the undelying oslMutex,
        which might cause severe problems in case it's a temporary object.

        */
        Mutex(oslMutex Mutex);

        /** This assignment operator is private for the same reason as
            the copy constructor.
        */
        Mutex& operator= (const Mutex&);

        /** This assignment operator is private for the same reason as
            the constructor taking a oslMutex argument.
        */
        Mutex& operator= (oslMutex);
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class Guard
    {
    private:
        Guard( const Guard& );
        const Guard& operator = ( const Guard& );

    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        Guard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        Guard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface. */
        ~Guard()
        {
            pT->release();
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template<class T>
    class ClearableGuard
    {
    private:
        ClearableGuard( const ClearableGuard& );
        const ClearableGuard& operator = ( const ClearableGuard& );
    protected:
        T * pT;
    public:

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T * pT_) : pT(pT_)
        {
            pT->acquire();
        }

        /** Acquires the object specified as parameter.
        */
        ClearableGuard(T & t) : pT(&t)
        {
            pT->acquire();
        }

        /** Releases the mutex or interface if not already released by clear().
        */
        ~ClearableGuard()
        {
            if (pT)
                pT->release();
        }

        /** Releases the mutex or interface.
        */
        void clear()
        {
            if(pT)
            {
                pT->release();
                pT = NULL;
            }
        }
    };

    /** A helper class for mutex objects and interfaces.
    */
    template< class T >
    class ResettableGuard : public ClearableGuard< T >
    {
    private:
        ResettableGuard(ResettableGuard &); // not defined
        void operator =(ResettableGuard &); // not defined

    protected:
        T* pResetT;
    public:
        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T* pT_ ) :
                ClearableGuard<T>( pT_ ),
                pResetT( pT_ )
        {}

        /** Acquires the object specified as parameter.
        */
        ResettableGuard( T& rT ) :
                ClearableGuard<T>( rT ),
                pResetT( &rT )
        {}

        /** Re-aquires the mutex or interface.
        */
        void reset()
        {
            if( pResetT )
            {
                this->pT = pResetT;
                this->pT->acquire();
            }
        }
    };

    typedef Guard<Mutex> MutexGuard;
    typedef ClearableGuard<Mutex> ClearableMutexGuard;
    typedef ResettableGuard< Mutex > ResettableMutexGuard;
}

#endif  /* __cplusplus */
#endif  /* _OSL_MUTEX_HXX_ */

<|endoftext|>


<commit_before>#include <winsock2.h>

#include "IDAClientManager.h"
#include "SocketOperation.h"
#include "DataBaseWriter.h"
#include "ProcessUtils.h"
#include "LogOperation.h"

extern LogOperation Logger;

#define DATA_BUFSIZE 4096
#define DEFAULT_IDA_PATH TEXT( "c:\\Program Files\\IDA\\idag.exe" )

IDAClientManager::IDAClientManager():
	EscapedOutputFilename( NULL ),
	EscapedLogFilename( NULL ),
	ListeningSocket( INVALID_SOCKET ),
	TheSource( NULL ),
	TheTarget( NULL ),
	IDACommandProcessorThreadId( -1 )
{
	IDAPath=_strdup( DEFAULT_IDA_PATH );
}

void IDAClientManager::SetDatabase( DBWrapper *OutputDB )
{
	m_OutputDB=OutputDB;
}

bool IDAClientManager::StartIDAListener( unsigned short port )
{
	StopIDAListener();
	ListeningPort=port;
	if( ListeningPort>0 )
	{
		ListeningSocket = CreateListener( NULL, port );
		Logger.Log( 10, "%s: ListeningSocket=%d\n", __FUNCTION__, ListeningSocket );
		return TRUE;
	}
	return FALSE;
}

bool IDAClientManager::StopIDAListener()
{
	if( ListeningSocket != INVALID_SOCKET )
	{
		closesocket( ListeningSocket );
		return TRUE;
	}
	return FALSE;
}

IDAClientManager::~IDAClientManager()
{
	StopIDAListener();

	if( IDAPath )
		free( IDAPath );
	if( EscapedOutputFilename )
		free( EscapedOutputFilename );
	if( EscapedLogFilename )
		free( EscapedLogFilename );

	if( TheSource )
		delete TheSource;

	if( TheTarget )
		delete TheTarget;
}

OneIDAClientManager *IDAClientManager::GetOneIDAClientManagerFromFile( char *DataFile )
{
	OneIDAClientManager *pOneIDAClientManager=new OneIDAClientManager( m_OutputDB );
	pOneIDAClientManager->Retrieve( DataFile );
	return pOneIDAClientManager;
}

BOOL IDAClientManager::AcceptIDAClient( OneIDAClientManager *pOneIDAClientManager, bool RetrieveData )
{
	SOCKET ClientSocket=accept( ListeningSocket, NULL, NULL );
	Logger.Log( 10, "%s: accepting=%d\n", __FUNCTION__, ClientSocket );
	if( ClientSocket==INVALID_SOCKET )
	{
		int error=WSAGetLastError();
		Logger.Log( 10, "Socket error=%d\n", error );
		return FALSE;
	}else
	{
		if( RetrieveData )
		{
			Logger.Log( 10, "%s: Calling RetrieveIDARawDataFromSocket\n", __FUNCTION__ );
			pOneIDAClientManager->RetrieveIDARawDataFromSocket( ClientSocket );
		}
		else
		{
			Logger.Log( 10, "%s: SetSocket\n", __FUNCTION__ );
			pOneIDAClientManager->SetSocket( ClientSocket );
		}
		return TRUE;
	}
	return FALSE;
}

DWORD IDAClientManager::SetMembers( OneIDAClientManager *OneIDAClientManagerTheSource, OneIDAClientManager *OneIDAClientManagerTheTarget, DiffMachine *pArgDiffMachine )
{
	TheSource=OneIDAClientManagerTheSource;
	TheTarget=OneIDAClientManagerTheTarget;
	pDiffMachine=pArgDiffMachine;
	return 1;
}

DWORD IDAClientManager::IDACommandProcessor()
{
	SOCKET SocketArray[WSA_MAXIMUM_WAIT_EVENTS];
	WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
	WSANETWORKEVENTS NetworkEvents;
	DWORD EventTotal=0, index;

	SocketArray[0]=TheSource->GetSocket();
	SocketArray[1]=TheTarget->GetSocket();
	for( int i=0;i<2;i++ )
	{
		WSAEVENT NewEvent=WSACreateEvent();
		WSAEventSelect( SocketArray[i], NewEvent, FD_READ|FD_CLOSE );
		EventArray[EventTotal]=NewEvent;
		EventTotal++;
	}
	while( 1 )
	{
		index=WSAWaitForMultipleEvents( EventTotal,
			EventArray,
			FALSE,
			WSA_INFINITE,
			FALSE );

		if( index<0 )
			break;

		index=index-WSA_WAIT_EVENT_0;
		//-------------------------
		// Iterate through all events and enumerate
		// if the wait does not fail.
		for( DWORD i=index; i<EventTotal; i++ )
		{
			if( SocketArray[i]==WSA_INVALID_HANDLE )
				continue;

			index=WSAWaitForMultipleEvents( 1,
				&EventArray[i],
				TRUE,
				1000,
				FALSE );
			if ( ( index !=WSA_WAIT_FAILED ) && ( index !=WSA_WAIT_TIMEOUT ) )
			{
				if( WSAEnumNetworkEvents( SocketArray[i], EventArray[i], &NetworkEvents )==0 )
				{
					Logger.Log( 10, "Signal( %d - %d )\n", i, NetworkEvents.lNetworkEvents );
					if( NetworkEvents.lNetworkEvents==FD_READ )
					{
						char buffer[DATA_BUFSIZE]={0, };
						WSABUF DataBuf;
						DataBuf.len=DATA_BUFSIZE;
						DataBuf.buf=buffer;
						/*
						DWORD RecvBytes;
						DWORD Flags=0;
						if ( WSARecv( SocketArray[i], &DataBuf, 1, &RecvBytes, &Flags, NULL, NULL )==SOCKET_ERROR )
						{
							Logger.Log( 10, "Error occurred at WSARecv()\n" );
						}else
						{
							Logger.Log( 10, "Read %d bytes\n", RecvBytes );
						}*/
						char type;
						DWORD length;
						PBYTE data=RecvTLVData( SocketArray[i], &type, &length );
						if( data )
						{
							Logger.Log( 10, "%s: Type: %d Length: %d data:%x\n", __FUNCTION__, type, length, data );
							if( type==SHOW_MATCH_ADDR && length>=4 )
							{
								DWORD address=*( DWORD * )data;
								Logger.Log( 10, "%s: Showing address=%x\n", __FUNCTION__, address );
								//Get Matching Address

								DWORD MatchingAddress = 0;
								if( pDiffMachine )
								{
									MatchingAddress = pDiffMachine->GetMatchAddr( i, address );
								}
								if( MatchingAddress!=0 )
								{
									//Show using JUMP_TO_ADDR
									if( i==0 )
									{
										TheTarget->ShowAddress( MatchingAddress );
									}else
									{
										TheSource->ShowAddress( MatchingAddress );
									}
								}
							}
						}
					}else if( NetworkEvents.lNetworkEvents==FD_CLOSE )
					{
						closesocket( SocketArray[i] );
						WSACloseEvent( EventArray[i] );
						memcpy( SocketArray+i, SocketArray+i+1, EventTotal-i+1 );
						memcpy( EventArray+i, EventArray+i+1, EventTotal-i+1 );
						EventTotal--;
						break;
					}
				}
			}
		}
	}
	return 1;
}

DWORD WINAPI IDACommandProcessorThread( LPVOID lpParameter )
{
	IDAClientManager *pIDAClientManager=( IDAClientManager * )lpParameter;
	pIDAClientManager->IDACommandProcessor();
	return 1;
}

BOOL IDAClientManager::CreateIDACommandProcessorThread()
{
	if( IDACommandProcessorThreadId > 0 )
	{
		HANDLE hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, IDACommandProcessorThreadId );
		if( hThread )
		{
			CloseHandle( hThread );
		}
		else
		{
			IDACommandProcessorThreadId = -1;
		}
	}

	if( IDACommandProcessorThreadId == -1 )
	{
		CreateThread( NULL, 0, IDACommandProcessorThread, ( PVOID )this, 0, &IDACommandProcessorThreadId );
		return TRUE;
	}
	return FALSE;
}

void SendAddMatchAddrTLVData( FunctionMatchInfo &Data, PVOID Context )
{
	OneIDAClientManager *TheSource=( OneIDAClientManager * )Context;
	if( TheSource )
	{
		TheSource->SendTLVData(
			ADD_MATCH_ADDR,
			( PBYTE )&( Data ),
			sizeof( Data ) );
	}
}

void SendUnidentifiedAddrTLVData( DWORD Data, PVOID Context )
{
	OneIDAClientManager *TheSource=( OneIDAClientManager * )Context;
	if( TheSource )
	{
		TheSource->SendTLVData(
			ADD_UNINDENTIFIED_ADDR,
			( PBYTE )&( Data ),
			sizeof( Data ) );
	}
}

void IDAClientManager::ShowResultsOnIDA()
{
	pDiffMachine->ExecuteOnFunctionMatchInfoList( SendAddMatchAddrTLVData, ( PVOID )TheSource );
	pDiffMachine->ExecuteOnTheSourceUnidentifedBlockHash( SendUnidentifiedAddrTLVData, ( PVOID )TheSource );
	pDiffMachine->ExecuteOnTheTargetUnidentifedBlockHash( SendUnidentifiedAddrTLVData, ( PVOID )TheTarget );
#ifdef TODO
	for( iter=ReverseFunctionMatchInfoList.begin();iter!=ReverseFunctionMatchInfoList.end();iter++ )
	{
		TheTarget->SendTLVData(
			ADD_MATCH_ADDR,
			( PBYTE )&( *iter ),
			sizeof( *iter ) );
	}
#endif
	TheSource->SendTLVData(
		SHOW_DATA,
		( PBYTE )"test",
		4 );
	TheTarget->SendTLVData(
		SHOW_DATA,
		( PBYTE )"test",
		4 );
}

#define RUN_DARUNGRIM2_PLUGIN_STR "static main()\n\
{\n\
	Wait();\n\
	RunPlugin( \"DarunGrim2\", 1 );\n\
	SetLogFile( \"%s\" );\n\
	SaveAnalysisData( \"%s\", %d, %d );\n\
	Exit( 0 );\n\
}"

#define CONNECT_TO_DARUNGRIM2_STR "static main()\n\
{\n\
	Wait();\n\
	RunPlugin( \"DarunGrim2\", 1 );\n\
	SetLogFile( \"%s\" );\n\
	ConnectToDarunGrim2();\n\
	Exit( 0 );\n\
}"

void IDAClientManager::SetIDAPath( const char *ParamIDAPath )
{
	if( IDAPath )
		free( IDAPath );
	IDAPath=_strdup( ParamIDAPath );
}

void IDAClientManager::SetOutputFilename( char *OutputFilename )
{
	//Create IDC file
	EscapedOutputFilename=( char * )malloc( strlen( OutputFilename )*2+1 );

	if( EscapedOutputFilename )
	{
		DWORD i=0, j=0;
		for( ;i<strlen( OutputFilename );i++, j++ )
		{
			EscapedOutputFilename[j]=OutputFilename[i];
			if( OutputFilename[i]=='\\' )
			{
				j++;
				EscapedOutputFilename[j]='\\';
			}
		}
		EscapedOutputFilename[j]=NULL;
	}
}

void IDAClientManager::SetLogFilename( char *LogFilename )
{
	EscapedLogFilename=NULL;
	if( LogFilename )
	{
		EscapedLogFilename=( char * )malloc( strlen( LogFilename )*2+1 );
		if( EscapedLogFilename )
		{
			DWORD i=0, j=0;
			for( ;i<strlen( LogFilename );i++, j++ )
			{
				EscapedLogFilename[j]=LogFilename[i];
				if( LogFilename[i]=='\\' )
				{
					j++;
					EscapedLogFilename[j]='\\';
				}
			}
			EscapedLogFilename[j]=NULL;
		}
	}
}

void IDAClientManager::RunIDAToGenerateDB( char *ida_filename, DWORD StartAddress, DWORD EndAddress )
{
	char *idc_filename=WriteToTemporaryFile( RUN_DARUNGRIM2_PLUGIN_STR,
		EscapedLogFilename?EscapedLogFilename:"",
		EscapedOutputFilename?EscapedOutputFilename:"",
		StartAddress,
		EndAddress );

	if( idc_filename )
	{
		//Run IDA
		Logger.Log( 10, "Analyzing [%s]( %s )\n", ida_filename, idc_filename );
		Logger.Log( 10, "Executing \"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		Execute( TRUE, "\"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		free( idc_filename );
	}
}

void IDAClientManager::ConnectToDarunGrim2( char *ida_filename )
{
	char *idc_filename=WriteToTemporaryFile( CONNECT_TO_DARUNGRIM2_STR, EscapedLogFilename?EscapedLogFilename:"");

	if( idc_filename )
	{
		//Run IDA
		Logger.Log( 10, "Analyzing [%s]( %s )\n", ida_filename, idc_filename );
		Logger.Log( 10, "Executing \"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		Execute( TRUE, "\"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		free( idc_filename );
	}
}<commit_msg>Use showing mode by default<commit_after>#include <winsock2.h>

#include "IDAClientManager.h"
#include "SocketOperation.h"
#include "DataBaseWriter.h"
#include "ProcessUtils.h"
#include "LogOperation.h"

extern LogOperation Logger;

#define DATA_BUFSIZE 4096
#define DEFAULT_IDA_PATH TEXT( "c:\\Program Files\\IDA\\idag.exe" )

IDAClientManager::IDAClientManager():
	EscapedOutputFilename( NULL ),
	EscapedLogFilename( NULL ),
	ListeningSocket( INVALID_SOCKET ),
	TheSource( NULL ),
	TheTarget( NULL ),
	IDACommandProcessorThreadId( -1 )
{
	IDAPath=_strdup( DEFAULT_IDA_PATH );
}

void IDAClientManager::SetDatabase( DBWrapper *OutputDB )
{
	m_OutputDB=OutputDB;
}

bool IDAClientManager::StartIDAListener( unsigned short port )
{
	StopIDAListener();
	ListeningPort=port;
	if( ListeningPort>0 )
	{
		ListeningSocket = CreateListener( NULL, port );
		Logger.Log( 10, "%s: ListeningSocket=%d\n", __FUNCTION__, ListeningSocket );
		return TRUE;
	}
	return FALSE;
}

bool IDAClientManager::StopIDAListener()
{
	if( ListeningSocket != INVALID_SOCKET )
	{
		closesocket( ListeningSocket );
		return TRUE;
	}
	return FALSE;
}

IDAClientManager::~IDAClientManager()
{
	StopIDAListener();

	if( IDAPath )
		free( IDAPath );
	if( EscapedOutputFilename )
		free( EscapedOutputFilename );
	if( EscapedLogFilename )
		free( EscapedLogFilename );

	if( TheSource )
		delete TheSource;

	if( TheTarget )
		delete TheTarget;
}

OneIDAClientManager *IDAClientManager::GetOneIDAClientManagerFromFile( char *DataFile )
{
	OneIDAClientManager *pOneIDAClientManager=new OneIDAClientManager( m_OutputDB );
	pOneIDAClientManager->Retrieve( DataFile );
	return pOneIDAClientManager;
}

BOOL IDAClientManager::AcceptIDAClient( OneIDAClientManager *pOneIDAClientManager, bool RetrieveData )
{
	SOCKET ClientSocket=accept( ListeningSocket, NULL, NULL );
	Logger.Log( 10, "%s: accepting=%d\n", __FUNCTION__, ClientSocket );
	if( ClientSocket==INVALID_SOCKET )
	{
		int error=WSAGetLastError();
		Logger.Log( 10, "Socket error=%d\n", error );
		return FALSE;
	}else
	{
		if( RetrieveData )
		{
			Logger.Log( 10, "%s: Calling RetrieveIDARawDataFromSocket\n", __FUNCTION__ );
			pOneIDAClientManager->RetrieveIDARawDataFromSocket( ClientSocket );
		}
		else
		{
			Logger.Log( 10, "%s: SetSocket\n", __FUNCTION__ );
			pOneIDAClientManager->SetSocket( ClientSocket );
		}
		return TRUE;
	}
	return FALSE;
}

DWORD IDAClientManager::SetMembers( OneIDAClientManager *OneIDAClientManagerTheSource, OneIDAClientManager *OneIDAClientManagerTheTarget, DiffMachine *pArgDiffMachine )
{
	TheSource=OneIDAClientManagerTheSource;
	TheTarget=OneIDAClientManagerTheTarget;
	pDiffMachine=pArgDiffMachine;
	return 1;
}

DWORD IDAClientManager::IDACommandProcessor()
{
	SOCKET SocketArray[WSA_MAXIMUM_WAIT_EVENTS];
	WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
	WSANETWORKEVENTS NetworkEvents;
	DWORD EventTotal=0, index;

	SocketArray[0]=TheSource->GetSocket();
	SocketArray[1]=TheTarget->GetSocket();
	for( int i=0;i<2;i++ )
	{
		WSAEVENT NewEvent=WSACreateEvent();
		WSAEventSelect( SocketArray[i], NewEvent, FD_READ|FD_CLOSE );
		EventArray[EventTotal]=NewEvent;
		EventTotal++;
	}
	while( 1 )
	{
		index=WSAWaitForMultipleEvents( EventTotal,
			EventArray,
			FALSE,
			WSA_INFINITE,
			FALSE );

		if( index<0 )
			break;

		index=index-WSA_WAIT_EVENT_0;
		//-------------------------
		// Iterate through all events and enumerate
		// if the wait does not fail.
		for( DWORD i=index; i<EventTotal; i++ )
		{
			if( SocketArray[i]==WSA_INVALID_HANDLE )
				continue;

			index=WSAWaitForMultipleEvents( 1,
				&EventArray[i],
				TRUE,
				1000,
				FALSE );
			if ( ( index !=WSA_WAIT_FAILED ) && ( index !=WSA_WAIT_TIMEOUT ) )
			{
				if( WSAEnumNetworkEvents( SocketArray[i], EventArray[i], &NetworkEvents )==0 )
				{
					Logger.Log( 10, "Signal( %d - %d )\n", i, NetworkEvents.lNetworkEvents );
					if( NetworkEvents.lNetworkEvents==FD_READ )
					{
						char buffer[DATA_BUFSIZE]={0, };
						WSABUF DataBuf;
						DataBuf.len=DATA_BUFSIZE;
						DataBuf.buf=buffer;
						/*
						DWORD RecvBytes;
						DWORD Flags=0;
						if ( WSARecv( SocketArray[i], &DataBuf, 1, &RecvBytes, &Flags, NULL, NULL )==SOCKET_ERROR )
						{
							Logger.Log( 10, "Error occurred at WSARecv()\n" );
						}else
						{
							Logger.Log( 10, "Read %d bytes\n", RecvBytes );
						}*/
						char type;
						DWORD length;
						PBYTE data=RecvTLVData( SocketArray[i], &type, &length );
						if( data )
						{
							Logger.Log( 10, "%s: Type: %d Length: %d data:%x\n", __FUNCTION__, type, length, data );
							if( type==SHOW_MATCH_ADDR && length>=4 )
							{
								DWORD address=*( DWORD * )data;
								Logger.Log( 10, "%s: Showing address=%x\n", __FUNCTION__, address );
								//Get Matching Address

								DWORD MatchingAddress = 0;
								if( pDiffMachine )
								{
									MatchingAddress = pDiffMachine->GetMatchAddr( i, address );
								}
								if( MatchingAddress!=0 )
								{
									//Show using JUMP_TO_ADDR
									if( i==0 )
									{
										TheTarget->ShowAddress( MatchingAddress );
									}else
									{
										TheSource->ShowAddress( MatchingAddress );
									}
								}
							}
						}
					}else if( NetworkEvents.lNetworkEvents==FD_CLOSE )
					{
						closesocket( SocketArray[i] );
						WSACloseEvent( EventArray[i] );
						memcpy( SocketArray+i, SocketArray+i+1, EventTotal-i+1 );
						memcpy( EventArray+i, EventArray+i+1, EventTotal-i+1 );
						EventTotal--;
						break;
					}
				}
			}
		}
	}
	return 1;
}

DWORD WINAPI IDACommandProcessorThread( LPVOID lpParameter )
{
	IDAClientManager *pIDAClientManager=( IDAClientManager * )lpParameter;
	pIDAClientManager->IDACommandProcessor();
	return 1;
}

BOOL IDAClientManager::CreateIDACommandProcessorThread()
{
	if( IDACommandProcessorThreadId > 0 )
	{
		HANDLE hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, IDACommandProcessorThreadId );
		if( hThread )
		{
			CloseHandle( hThread );
		}
		else
		{
			IDACommandProcessorThreadId = -1;
		}
	}

	if( IDACommandProcessorThreadId == -1 )
	{
		CreateThread( NULL, 0, IDACommandProcessorThread, ( PVOID )this, 0, &IDACommandProcessorThreadId );
		return TRUE;
	}
	return FALSE;
}

void SendAddMatchAddrTLVData( FunctionMatchInfo &Data, PVOID Context )
{
	OneIDAClientManager *TheSource=( OneIDAClientManager * )Context;
	if( TheSource )
	{
		TheSource->SendTLVData(
			ADD_MATCH_ADDR,
			( PBYTE )&( Data ),
			sizeof( Data ) );
	}
}

void SendUnidentifiedAddrTLVData( DWORD Data, PVOID Context )
{
	OneIDAClientManager *TheSource=( OneIDAClientManager * )Context;
	if( TheSource )
	{
		TheSource->SendTLVData(
			ADD_UNINDENTIFIED_ADDR,
			( PBYTE )&( Data ),
			sizeof( Data ) );
	}
}

void IDAClientManager::ShowResultsOnIDA()
{
	pDiffMachine->ExecuteOnFunctionMatchInfoList( SendAddMatchAddrTLVData, ( PVOID )TheSource );
	pDiffMachine->ExecuteOnTheSourceUnidentifedBlockHash( SendUnidentifiedAddrTLVData, ( PVOID )TheSource );
	pDiffMachine->ExecuteOnTheTargetUnidentifedBlockHash( SendUnidentifiedAddrTLVData, ( PVOID )TheTarget );
#ifdef TODO
	for( iter=ReverseFunctionMatchInfoList.begin();iter!=ReverseFunctionMatchInfoList.end();iter++ )
	{
		TheTarget->SendTLVData(
			ADD_MATCH_ADDR,
			( PBYTE )&( *iter ),
			sizeof( *iter ) );
	}
#endif
	TheSource->SendTLVData(
		SHOW_DATA,
		( PBYTE )"test",
		4 );
	TheTarget->SendTLVData(
		SHOW_DATA,
		( PBYTE )"test",
		4 );
}

#define RUN_DARUNGRIM2_PLUGIN_STR "static main()\n\
{\n\
	Wait();\n\
	RunPlugin( \"DarunGrim2\", 1 );\n\
	SetLogFile( \"%s\" );\n\
	SaveAnalysisData( \"%s\", %d, %d );\n\
	Exit( 0 );\n\
}"

#define CONNECT_TO_DARUNGRIM2_STR "static main()\n\
{\n\
	Wait();\n\
	RunPlugin( \"DarunGrim2\", 1 );\n\
	SetLogFile( \"%s\" );\n\
	ConnectToDarunGrim2();\n\
	Exit( 0 );\n\
}"

void IDAClientManager::SetIDAPath( const char *ParamIDAPath )
{
	if( IDAPath )
		free( IDAPath );
	IDAPath=_strdup( ParamIDAPath );
}

void IDAClientManager::SetOutputFilename( char *OutputFilename )
{
	//Create IDC file
	EscapedOutputFilename=( char * )malloc( strlen( OutputFilename )*2+1 );

	if( EscapedOutputFilename )
	{
		DWORD i=0, j=0;
		for( ;i<strlen( OutputFilename );i++, j++ )
		{
			EscapedOutputFilename[j]=OutputFilename[i];
			if( OutputFilename[i]=='\\' )
			{
				j++;
				EscapedOutputFilename[j]='\\';
			}
		}
		EscapedOutputFilename[j]=NULL;
	}
}

void IDAClientManager::SetLogFilename( char *LogFilename )
{
	EscapedLogFilename=NULL;
	if( LogFilename )
	{
		EscapedLogFilename=( char * )malloc( strlen( LogFilename )*2+1 );
		if( EscapedLogFilename )
		{
			DWORD i=0, j=0;
			for( ;i<strlen( LogFilename );i++, j++ )
			{
				EscapedLogFilename[j]=LogFilename[i];
				if( LogFilename[i]=='\\' )
				{
					j++;
					EscapedLogFilename[j]='\\';
				}
			}
			EscapedLogFilename[j]=NULL;
		}
	}
}

void IDAClientManager::RunIDAToGenerateDB( char *ida_filename, DWORD StartAddress, DWORD EndAddress )
{
	char *idc_filename=WriteToTemporaryFile( RUN_DARUNGRIM2_PLUGIN_STR,
		EscapedLogFilename?EscapedLogFilename:"",
		EscapedOutputFilename?EscapedOutputFilename:"",
		StartAddress,
		EndAddress );

	if( idc_filename )
	{
		//Run IDA
		Logger.Log( 10, "Analyzing [%s]( %s )\n", ida_filename, idc_filename );
		Logger.Log( 10, "Executing \"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		Execute( TRUE, "\"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		free( idc_filename );
	}
}

void IDAClientManager::ConnectToDarunGrim2( char *ida_filename )
{
	char *idc_filename=WriteToTemporaryFile( CONNECT_TO_DARUNGRIM2_STR, EscapedLogFilename?EscapedLogFilename:"");

	if( idc_filename )
	{
		//Run IDA
		Logger.Log( 10, "Analyzing [%s]( %s )\n", ida_filename, idc_filename );
		Logger.Log( 10, "Executing \"%s\" -A -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		Execute( TRUE, "\"%s\" -S\"%s\" \"%s\"", IDAPath, idc_filename, ida_filename );
		free( idc_filename );
	}
}<|endoftext|>


<commit_before>#include "synctool.h"
#include <dirent.h>
#include <unistd.h>
#include <utime.h>

bool isFile(string path)
{
	struct stat st;
	return (lstat(path.c_str(), &st) != -1) && TYPE(st) == S_IFREG;
}

bool isDirectory(string path)
{
	struct stat st;
	return (lstat(path.c_str(), &st) != -1) && TYPE(st) == S_IFDIR;
}

bool isLink(string path)
{
	struct stat st;
	return (lstat(path.c_str(), &st) != -1) && TYPE(st) == S_IFLNK;
}

/* Write with colorized output */
void setColor(string color)
{
	if (gUseColors)
		cout << color;
}

/* File operations */
void removeFile(string file)
{
	if (!isFile(file))
		return;

	logMessage("RM " + file, RED);
	if(remove(file.c_str()) == -1)
		die(EXIT_FAILURE, "Error: Could not delete " + file);
}

void copyFile(string src, string dst)
{
	if (!filesDiffer(src, dst))
		return;

	if (isFile(dst))
		removeFile(dst);

	logMessage("CP " + src + " -> " + dst, BLUE);

	ifstream fin(src.c_str(), ios::binary);
	ofstream fout(dst.c_str(), ios::binary);

	if (!(fin.is_open() && fout.is_open() && (fout << fin.rdbuf())))
		die(EXIT_FAILURE, "Error: Could not copy " + src);

	fin.close();
	fout.close();

	struct stat st;

	if (stat(src.c_str(), &st) != -1)
	{
		struct utimbuf buf;

		buf.actime = st.st_atime;
		buf.modtime = st.st_mtime;

		utime(dst.c_str(), &buf);

		/* also copy file permissions */
		chmod(dst.c_str(), st.st_mode);
	}
}

void copyLink(string src, string dst)
{
	int r;
	char *target;

	int size = 1024;
	struct stat st;

	removeFile(dst);

	if ((r = lstat(src.c_str(), &st)) != -1)
	{
		size = st.st_size;
	}

	target = new char[size];

	if (readlink(src.c_str(), target, size) == -1)
		die(EXIT_FAILURE, "Error: Could not read link " + src);

	logMessage("LN " + dst + " -> " + target, BLUE);

	if (symlink(target, dst.c_str()) == -1)
		die(EXIT_FAILURE, "Error: Could not create link " + dst);

	delete target;

	if (r != -1)
	{
		struct utimbuf buf;

		buf.actime = st.st_atime;
		buf.modtime = st.st_mtime;

		utime(dst.c_str(), &buf);
	}
}

void removeDirectory(string dir)
{
	if (!isDirectory(dir))
		return;

	DIR *d = opendir(dir.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string path = dir + '/' + ent->d_name;

		if (isDirectory(path))
			removeDirectory(path);
		else
			removeFile(path);
	}

	closedir(d);

	logMessage("RM " + dir, RED);
	if (rmdir(dir.c_str()) == -1)
		die(EXIT_FAILURE, "Error: Could not delete " + dir);
}

void assertCanOpenDirectory(string dir)
{
	DIR *d = opendir(dir.c_str());
	if (d == NULL)
		die(EXIT_FAILURE, "Error: Cannot access " + dir);

	closedir(d);
}

void copyAllFiles(string src, string dst)
{
	DIR *d = opendir(src.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(srcPath))
			copyAllFiles(srcPath, dstPath);
		else if (isFile(srcPath))
			copyFile(srcPath, dstPath);
		else if (isLink(srcPath))
			copyLink(srcPath, dstPath);
	}

	closedir(d);
}

void copyNewAndUpdatedFiles(string src, string dst)
{
	DIR *d = opendir(src.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(srcPath) && !isDirectory(dstPath))
			logMessage("Warning: " + srcPath + " is a directory, but " + dstPath + " is not.");
		else if (!isDirectory(srcPath) && isDirectory(dstPath))
			logMessage("Warning: " + srcPath + " is not a directory, but " + dstPath + " is.");
		else if (isDirectory(srcPath))
			copyNewAndUpdatedFiles(srcPath, dstPath);
		else if (isFile(srcPath) && isNewer(srcPath, dstPath))
			copyFile(srcPath, dstPath);
		else if (isLink(srcPath))
			copyLink(srcPath, dstPath);
	}

	closedir(d);
}

void createDirectoryTree(string src, string dst)
{
	DIR *d = opendir(src.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(srcPath) && !isDirectory(dstPath))
		{
			if (isFile(dstPath) || isLink(dstPath))
				removeFile(dstPath);

			logMessage("MK " + dstPath);
			if (mkdir(dstPath.c_str(), 0775) == -1)
				die(EXIT_FAILURE, "Could not create " + dstPath);

			struct stat st;

			if (stat(srcPath.c_str(), &st) != -1)
			{
				struct utimbuf buf;
				buf.actime = st.st_atime;
				buf.modtime = st.st_mtime;

				utime(dstPath.c_str(), &buf);
			}
		}

		if (isDirectory(srcPath) && isDirectory(dstPath))
			createDirectoryTree(srcPath, dstPath);
	}

	closedir(d);
}

void removeMissing(string src, string dst)
{
	DIR *d = opendir(dst.c_str());
	struct dirent *ent;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(dstPath) && !isDirectory(srcPath))
			removeDirectory(dstPath);
		else if (isFile(dstPath) && !isFile(srcPath))
			removeFile(dstPath);
		else if (isLink(dstPath) && !isLink(srcPath))
			removeFile(dstPath);
		else if (isDirectory(dstPath) && isDirectory(srcPath))
			removeMissing(srcPath, dstPath);

	}

	closedir(d);
}
<commit_msg>fixed unable to copy errors on empty files<commit_after>#include "synctool.h"
#include <dirent.h>
#include <unistd.h>
#include <utime.h>

bool isFile(string path)
{
	struct stat st;
	return (lstat(path.c_str(), &st) != -1) && TYPE(st) == S_IFREG;
}

bool isDirectory(string path)
{
	struct stat st;
	return (lstat(path.c_str(), &st) != -1) && TYPE(st) == S_IFDIR;
}

bool isLink(string path)
{
	struct stat st;
	return (lstat(path.c_str(), &st) != -1) && TYPE(st) == S_IFLNK;
}

/* Write with colorized output */
void setColor(string color)
{
	if (gUseColors)
		cout << color;
}

/* File operations */
void removeFile(string file)
{
	if (!isFile(file))
		return;

	logMessage("RM " + file, RED);
	if(remove(file.c_str()) == -1)
		die(EXIT_FAILURE, "Error: Could not delete " + file);
}

void copyFile(string src, string dst)
{
	if (!filesDiffer(src, dst))
		return;

	if (isFile(dst))
		removeFile(dst);

	logMessage("CP " + src + " -> " + dst, BLUE);

	ifstream fin(src.c_str(), ios::binary);
	ofstream fout(dst.c_str(), ios::binary);

	if (!(fin.is_open() && fout.is_open()))
		die(EXIT_FAILURE, "Error: Could not copy " + src);

	fout << fin.rdbuf();

	fin.close();
	fout.close();

	struct stat st;

	if (stat(src.c_str(), &st) != -1)
	{
		struct utimbuf buf;

		buf.actime = st.st_atime;
		buf.modtime = st.st_mtime;

		utime(dst.c_str(), &buf);

		/* also copy file permissions */
		chmod(dst.c_str(), st.st_mode);
	}
}

void copyLink(string src, string dst)
{
	int r;
	char *target;

	int size = 1024;
	struct stat st;

	removeFile(dst);

	if ((r = lstat(src.c_str(), &st)) != -1)
	{
		size = st.st_size;
	}

	target = new char[size];

	if (readlink(src.c_str(), target, size) == -1)
		die(EXIT_FAILURE, "Error: Could not read link " + src);

	logMessage("LN " + dst + " -> " + target, BLUE);

	if (symlink(target, dst.c_str()) == -1)
		die(EXIT_FAILURE, "Error: Could not create link " + dst);

	delete target;

	if (r != -1)
	{
		struct utimbuf buf;

		buf.actime = st.st_atime;
		buf.modtime = st.st_mtime;

		utime(dst.c_str(), &buf);
	}
}

void removeDirectory(string dir)
{
	if (!isDirectory(dir))
		return;

	DIR *d = opendir(dir.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string path = dir + '/' + ent->d_name;

		if (isDirectory(path))
			removeDirectory(path);
		else
			removeFile(path);
	}

	closedir(d);

	logMessage("RM " + dir, RED);
	if (rmdir(dir.c_str()) == -1)
		die(EXIT_FAILURE, "Error: Could not delete " + dir);
}

void assertCanOpenDirectory(string dir)
{
	DIR *d = opendir(dir.c_str());
	if (d == NULL)
		die(EXIT_FAILURE, "Error: Cannot access " + dir);

	closedir(d);
}

void copyAllFiles(string src, string dst)
{
	DIR *d = opendir(src.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(srcPath))
			copyAllFiles(srcPath, dstPath);
		else if (isFile(srcPath))
			copyFile(srcPath, dstPath);
		else if (isLink(srcPath))
			copyLink(srcPath, dstPath);
	}

	closedir(d);
}

void copyNewAndUpdatedFiles(string src, string dst)
{
	DIR *d = opendir(src.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(srcPath) && !isDirectory(dstPath))
			logMessage("Warning: " + srcPath + " is a directory, but " + dstPath + " is not.");
		else if (!isDirectory(srcPath) && isDirectory(dstPath))
			logMessage("Warning: " + srcPath + " is not a directory, but " + dstPath + " is.");
		else if (isDirectory(srcPath))
			copyNewAndUpdatedFiles(srcPath, dstPath);
		else if (isFile(srcPath) && isNewer(srcPath, dstPath))
			copyFile(srcPath, dstPath);
		else if (isLink(srcPath))
			copyLink(srcPath, dstPath);
	}

	closedir(d);
}

void createDirectoryTree(string src, string dst)
{
	DIR *d = opendir(src.c_str());
	struct dirent *ent = NULL;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(srcPath) && !isDirectory(dstPath))
		{
			if (isFile(dstPath) || isLink(dstPath))
				removeFile(dstPath);

			logMessage("MK " + dstPath);
			if (mkdir(dstPath.c_str(), 0775) == -1)
				die(EXIT_FAILURE, "Could not create " + dstPath);

			struct stat st;

			if (stat(srcPath.c_str(), &st) != -1)
			{
				struct utimbuf buf;
				buf.actime = st.st_atime;
				buf.modtime = st.st_mtime;

				utime(dstPath.c_str(), &buf);
			}
		}

		if (isDirectory(srcPath) && isDirectory(dstPath))
			createDirectoryTree(srcPath, dstPath);
	}

	closedir(d);
}

void removeMissing(string src, string dst)
{
	DIR *d = opendir(dst.c_str());
	struct dirent *ent;

	while ((ent = readdir(d)))
	{
		if (string(ent->d_name) == "." || string(ent->d_name) == "..")
			continue;

		string srcPath = src + '/' + ent->d_name;
		string dstPath = dst + '/' + ent->d_name;

		if (isDirectory(dstPath) && !isDirectory(srcPath))
			removeDirectory(dstPath);
		else if (isFile(dstPath) && !isFile(srcPath))
			removeFile(dstPath);
		else if (isLink(dstPath) && !isLink(srcPath))
			removeFile(dstPath);
		else if (isDirectory(dstPath) && isDirectory(srcPath))
			removeMissing(srcPath, dstPath);

	}

	closedir(d);
}
<|endoftext|>


<commit_before>/*
* Stream Ciphers
* (C) 2015,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/stream_cipher.h>
#include <botan/scan_name.h>

#if defined(BOTAN_HAS_CHACHA)
  #include <botan/chacha.h>
#endif

#if defined(BOTAN_HAS_SALSA20)
  #include <botan/salsa20.h>
#endif

#if defined(BOTAN_HAS_SHAKE_CIPHER)
  #include <botan/shake_cipher.h>
#endif

#if defined(BOTAN_HAS_CTR_BE)
  #include <botan/ctr.h>
#endif

#if defined(BOTAN_HAS_OFB)
  #include <botan/ofb.h>
#endif

#if defined(BOTAN_HAS_RC4)
  #include <botan/rc4.h>
#endif

#if defined(BOTAN_HAS_OPENSSL)
  #include <botan/internal/openssl.h>
#endif

namespace Botan {

std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec,
                                                   const std::string& provider)
   {
   const SCAN_Name req(algo_spec);

#if defined(BOTAN_HAS_CTR_BE)
   if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1,2))
      {
      if(provider.empty() || provider == "base")
         {
         auto cipher = BlockCipher::create(req.arg(0));
         if(cipher)
            {
            size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
            return std::unique_ptr<StreamCipher>(new CTR_BE(cipher.release(), ctr_size));
            }
         }
      }
#endif

#if defined(BOTAN_HAS_CHACHA)
   if(req.algo_name() == "ChaCha")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new ChaCha(req.arg_as_integer(0, 20)));
      }
#endif

#if defined(BOTAN_HAS_SALSA20)
   if(req.algo_name() == "Salsa20")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new Salsa20);
      }
#endif

#if defined(BOTAN_HAS_SHAKE_CIPHER)
   if(req.algo_name() == "SHAKE-128")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new SHAKE_128_Cipher);
      }
#endif

#if defined(BOTAN_HAS_OFB)
   if(req.algo_name() == "OFB" && req.arg_count() == 1)
      {
      if(provider.empty() || provider == "base")
         {
         if(auto c = BlockCipher::create(req.arg(0)))
            return std::unique_ptr<StreamCipher>(new OFB(c.release()));
         }
      }
#endif

#if defined(BOTAN_HAS_RC4)

   if(req.algo_name() == "RC4" ||
      req.algo_name() == "ARC4" ||
      req.algo_name() == "MARK-4")
      {
      const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);

#if defined(BOTAN_HAS_OPENSSL)
      if(provider.empty() || provider == "openssl")
         {
         return std::unique_ptr<StreamCipher>(make_openssl_rc4(skip));
         }
#endif

      if(provider.empty() || provider == "base")
         {
         return std::unique_ptr<StreamCipher>(new RC4(skip));
         }
      }

#endif

   BOTAN_UNUSED(req);
   BOTAN_UNUSED(provider);

   return nullptr;
   }

//static
std::unique_ptr<StreamCipher>
StreamCipher::create_or_throw(const std::string& algo,
                             const std::string& provider)
   {
   if(auto sc = StreamCipher::create(algo, provider))
      {
      return sc;
      }
   throw Lookup_Error("Stream cipher", algo, provider);
   }

std::vector<std::string> StreamCipher::providers(const std::string& algo_spec)
   {
   return probe_providers_of<StreamCipher>(algo_spec, {"base", "openssl"});
   }

}
<commit_msg>Accept ChaCha20 as a name<commit_after>/*
* Stream Ciphers
* (C) 2015,2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/stream_cipher.h>
#include <botan/scan_name.h>

#if defined(BOTAN_HAS_CHACHA)
  #include <botan/chacha.h>
#endif

#if defined(BOTAN_HAS_SALSA20)
  #include <botan/salsa20.h>
#endif

#if defined(BOTAN_HAS_SHAKE_CIPHER)
  #include <botan/shake_cipher.h>
#endif

#if defined(BOTAN_HAS_CTR_BE)
  #include <botan/ctr.h>
#endif

#if defined(BOTAN_HAS_OFB)
  #include <botan/ofb.h>
#endif

#if defined(BOTAN_HAS_RC4)
  #include <botan/rc4.h>
#endif

#if defined(BOTAN_HAS_OPENSSL)
  #include <botan/internal/openssl.h>
#endif

namespace Botan {

std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec,
                                                   const std::string& provider)
   {
   const SCAN_Name req(algo_spec);

#if defined(BOTAN_HAS_CTR_BE)
   if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1,2))
      {
      if(provider.empty() || provider == "base")
         {
         auto cipher = BlockCipher::create(req.arg(0));
         if(cipher)
            {
            size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
            return std::unique_ptr<StreamCipher>(new CTR_BE(cipher.release(), ctr_size));
            }
         }
      }
#endif

#if defined(BOTAN_HAS_CHACHA)
   if(req.algo_name() == "ChaCha")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new ChaCha(req.arg_as_integer(0, 20)));
      }

   if(req.algo_name() == "ChaCha20")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new ChaCha(20));
      }
#endif

#if defined(BOTAN_HAS_SALSA20)
   if(req.algo_name() == "Salsa20")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new Salsa20);
      }
#endif

#if defined(BOTAN_HAS_SHAKE_CIPHER)
   if(req.algo_name() == "SHAKE-128")
      {
      if(provider.empty() || provider == "base")
         return std::unique_ptr<StreamCipher>(new SHAKE_128_Cipher);
      }
#endif

#if defined(BOTAN_HAS_OFB)
   if(req.algo_name() == "OFB" && req.arg_count() == 1)
      {
      if(provider.empty() || provider == "base")
         {
         if(auto c = BlockCipher::create(req.arg(0)))
            return std::unique_ptr<StreamCipher>(new OFB(c.release()));
         }
      }
#endif

#if defined(BOTAN_HAS_RC4)

   if(req.algo_name() == "RC4" ||
      req.algo_name() == "ARC4" ||
      req.algo_name() == "MARK-4")
      {
      const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);

#if defined(BOTAN_HAS_OPENSSL)
      if(provider.empty() || provider == "openssl")
         {
         return std::unique_ptr<StreamCipher>(make_openssl_rc4(skip));
         }
#endif

      if(provider.empty() || provider == "base")
         {
         return std::unique_ptr<StreamCipher>(new RC4(skip));
         }
      }

#endif

   BOTAN_UNUSED(req);
   BOTAN_UNUSED(provider);

   return nullptr;
   }

//static
std::unique_ptr<StreamCipher>
StreamCipher::create_or_throw(const std::string& algo,
                             const std::string& provider)
   {
   if(auto sc = StreamCipher::create(algo, provider))
      {
      return sc;
      }
   throw Lookup_Error("Stream cipher", algo, provider);
   }

std::vector<std::string> StreamCipher::providers(const std::string& algo_spec)
   {
   return probe_providers_of<StreamCipher>(algo_spec, {"base", "openssl"});
   }

}
<|endoftext|>


<commit_before>#include <matrix.hpp>

	Matrix :: Matrix(){};

	Matrix :: Matrix(int a, int b)
	{
		columns = b;
		strings = a;
		matrix = new int*[a];

		for (int i = 0; i < a; i++)
		{
			matrix[i] = new int[b]{0};
		}
	};

	void Matrix :: input(string filen)
	{
		ifstream file;
		file.open(filen);

		matrix[i] = new *int [strings];
		for (int i = 0; i < strings; i++)
		{
			matrix[i] = new *int [columns];
			for (int j = 0; j < columns; j++)
			{
				file >> matrix[i][j];
			}
		}
		file.close();
	};

	void Matrix :: set(int x, int y, int z)
	{
		matrix[x][y] = z;
	};

	int Matrix :: get(int x, int y) const
	{
		return matrix[x][y];
	};

	Matrix Matrix:: operator+ (Matrix a) const
	{
		Matrix c(strings, columns);

		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < columns; j++)
			{
				c.set(i, j, a.get(i, j) + get(i, j));
			}
		}
		return c;
	};

	Matrix Matrix :: operator* (Matrix a) const
	{
		Matrix c(strings, a.columns);

		for (int i = 0; i < strings; i++)
		{
			for (int j = 0; j < a.columns; j++)
			{
				int temp = 0;
				for (int k = 0; k < strings; k++)
				{
					temp += get(i, k) * a.get(k, j);
				}
				c.set(i, j, temp);
			}
		}

		return c;
	};

	Matrix& Matrix :: operator= (Matrix &other)
	{
		if (this != &other)
		{
			for (int i = 0; i < strings; i++)
			{
				delete[] matrix[i];
			}

			delete[] matrix;

			columns = other.columns;
			strings = other.strings;

			matrix = new int*[strings];

			for (int i = 0; i < strings; i++)
			{
				matrix[i] = new int[columns]{0};
			}

			matrix = other.matrix;
		}
		return *this;
	};

	bool Matrix :: operator== (Matrix &a) const
	{
		bool k = false;

		for (int i = 0; i < strings; i++){

			for (int j = 0; j < columns; j++){

				if (matrix[i][j] == a.matrix[i][j])

					k = true;

			}

		}

		return k;
	}

	istream& operator>> (istream& file, const Matrix& result)

	{

		for (int i = 0; i < result.strings; i++)

			for (int j = 0; j < result.columns; j++)

				file >> result.matrix[i][j];

		return file;

	}

	 ostream& operator<< (ostream& os, const Matrix& a)
	{
		for (int i = 0; i < a.strings; i++)
		{
			for (int j = 0; j < a.columns; j++)
			{
				os << a.matrix[i][j] << " ";
			}
			os << endl;
		}
		os << endl;
		return os;
	}

	Matrix :: ~Matrix()
	{
		/*for (int i = 0; i < strings; i++)
		{
			delete[] matrix[i];
		}

		delete[] matrix;*/
	};

<commit_msg>Update matrix.cpp<commit_after>#include "matrix.hpp"

int Matrix::Columns_() const
{
	return Columns;
}

int Matrix::Strings_() const
{
	return Strings;
}

Matrix::Matrix()
{
	Columns = 0;
	Strings = 0;
	matrix = new int*[Strings];
	for (int i = 0; i < Strings; i++)
	{
		matrix[i] = new int[Columns];
	}
}

Matrix::Matrix(int _Columns, int _Strings)
{
	Columns = _Columns;
	Strings = _Strings;
	matrix = new int*[Strings];
	for (int i = 0; i < Strings; ++i)
	{
		matrix[i] = new int[Columns];
		for (int j = 0; j < Columns; ++j)
		{
			matrix[i][j] = 0;
		}
	}
}

Matrix::Matrix(const Matrix& res)
{
	Columns = res.Columns;
	Strings = res.Strings;
	matrix = new int*[Strings];

	for (int i = 0; i < Strings; ++i)
	{
		matrix[i] = new int[Columns];
		for (int j = 0; j < Columns; ++j)
		{
			matrix[i][j] = res.matrix[i][j];
		}
	}
}

Matrix::~Matrix()
{
	for (int i = 0; i < Strings; ++i)
	{
		delete[]matrix[i];
	}
	delete[]matrix;
}

istream& operator >> (istream& infile, const Matrix& res) const
{
	for (int i = 0; i < res.Strings; i++)
	for (int j = 0; j < res.Columns; j++)
		infile >> res.matrix[i][j];
	return infile;
}

void Matrix::search(string filen) const
{
	ifstream file;
	file.open(filen);
	if (!file.is_open())
		cout << "Error! Try again!" << endl;
	else
	{
		matrix = new int*[Strings];
		for (int i = 0; i < Strings; i++)
		{
			matrix[i] = new int[Columns];
			for (int j = 0; j < Columns; j++)
			{
				file >> matrix[i][j];
			}
		}
	}
	file.close();
}

ostream& operator << (ostream& outfile, const Matrix& resu)
{
	for (int i = 0; i < res.Strings; i++)
	{
		for (int j = 0; j < resu.Columns; j++)
		{
			outfile << res.matrix[i][j] << " ";
		}
	}
	outfile << endl;
	return outfile;
}

bool Matrix::operator == (const Matrix& m2) const
{
	bool k = false;
	for (int i = 0; i < Strings; i++)
	{
		for (int j = 0; j < Columns; j++)
		{
			if (matrix[i][j] == m2.matrix[i][j])
				k = true;
		}
	}
	return k;
}

Matrix Matrix::operator + (const Matrix& m2) const
{
	if ((Columns != m2.Columns) || (Strings != m2.Strings))
	{
		cout << "Error!";
	}
	else
	{
		Matrix result(Columns, Strings);
		for (int i = 0; i < Strings; ++i)
		{
			for (int j = 0; j < Columns; ++j)
			{
				result.matrix[i][j] = matrix[i][j] + m2.matrix[i][j];
			}
		}
		return result;
	}
}

Matrix Matrix::operator * (const Matrix& m2) const
{
	if (m2.Strings != Columns)
	{
		cout << "Error!";
	}
	else
	{
		Matrix res(Strings, m2.Columns);

		for (int i = 0; i < Strings; i++)
		{
			for (int j = 0; j < m2.Columns; j++)
			{
				for (int k = 0; k < Columns; k++)
				{
					res.matrix[i][j] += matrix[i][k] * m2.matrix[k][j];
				}
			}
		}
		return result;
	}
}

Matrix& Matrix::operator = (const Matrix& res)
{
	if (&result != this)
	{
		for (int i = 0; i < Strings; i++)
		{
			delete[] matrix[i];
		}
		delete[] matrix;
	}
	Strings = res.Strings;
	Columns = res.Columns;

	matrix = new int*[Strings];

	for (int i = 0; i < Strings; i++)
	{
		matrix[i] = new int[Columns];
		for (int j = 0; j < Columns; j++)
		{
			matrix[i][j] = res.matrix[i][j];
		}
	}
	return *this;

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/TransformationMatrix.h"

namespace IECore {

template class TransformationMatrix<double>;
template class TransformationMatrix<float>;

} // namespace IECore
<commit_msg>Fixed formatting<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/TransformationMatrix.h"

namespace IECore
{

template class TransformationMatrix<double>;
template class TransformationMatrix<float>;

} // namespace IECore
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <cmath>
#include <gtest/gtest.h>
#include "../parallel.h"
#include "../sequence.h"
#include "../task.h"

class ParallelSequenceTest : testing::Test
{

};

TEST(ParallelSequenceTest, Test1)
{
	auto task1 = asyncply::parallel(
		[&]()
		{
			return asyncply::sequence(7.0,
				[](double data)
				{
					return data + 3.0;
				},
				[](double data)
				{
					return data + 4.0;
				});
		},
		[&]()
		{
			return asyncply::sequence(9.0,
				[](double data)
				{
					return data + 5.0;
				},
				[](double data)
				{
					return data + 4.0;
				});
		});
	ASSERT_EQ(task1->get(), 32.0);
}
<commit_msg>Update test_parallel_sequence.cpp<commit_after>#include <iostream>
#include <vector>
#include <cmath>
#include <gtest/gtest.h>
#include "../parallel.h"
#include "../sequence.h"
#include "../task.h"

class ParallelSequenceTest : testing::Test
{

};

TEST(ParallelSequenceTest, Test1)
{
	double total = asyncply::parallel_sync(
		[&]()
		{
			return asyncply::sequence(7.0,
				[](double data)
				{
					return data + 3.0;
				},
				[](double data)
				{
					return data + 4.0;
				});
		},
		[&]()
		{
			return asyncply::sequence(9.0,
				[](double data)
				{
					return data + 5.0;
				},
				[](double data)
				{
					return data + 4.0;
				});
		});
	ASSERT_EQ(total, 32.0);
}
<|endoftext|>


<commit_before>/*  Sirikata
 *  main.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
 * 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.
 */

#include <sirikata/core/util/Timer.hpp>
#include <sirikata/core/network/NTPTimeSync.hpp>

#include <sirikata/core/network/IOServiceFactory.hpp>
#include <sirikata/core/network/IOStrandImpl.hpp>

#include <sirikata/space/ObjectHostSession.hpp>
#include <sirikata/space/ObjectSessionManager.hpp>
#include <sirikata/space/Authenticator.hpp>

#include <sirikata/space/SpaceNetwork.hpp>

#include "Forwarder.hpp"

#include <sirikata/space/LocationService.hpp>

#include <sirikata/space/Proximity.hpp>
#include <sirikata/space/AggregateManager.hpp>
#include "Server.hpp"

#include "Options.hpp"
#include <sirikata/core/options/CommonOptions.hpp>
#include <sirikata/core/util/PluginManager.hpp>
#include <sirikata/core/trace/Trace.hpp>
#include "TCPSpaceNetwork.hpp"
#include "FairServerMessageReceiver.hpp"
#include "FairServerMessageQueue.hpp"
#include <sirikata/core/network/ServerIDMap.hpp>
#include "UniformCoordinateSegmentation.hpp"
#include "CoordinateSegmentationClient.hpp"
#include <sirikata/space/LoadMonitor.hpp>
#include <sirikata/space/ObjectSegmentation.hpp>
#include "caches/CommunicationCache.hpp"
#include "caches/CacheLRUOriginal.hpp"

#include <sirikata/space/SpaceContext.hpp>
#include <sirikata/mesh/Filter.hpp>
#include <sirikata/mesh/ModelsSystemFactory.hpp>

namespace {
using namespace Sirikata;
void createServer(Server** server_out, SpaceContext* space_context, Authenticator* auth, Forwarder* forwarder, LocationService* loc_service, CoordinateSegmentation* cseg, Proximity* prox, ObjectSegmentation* oseg, Address4 addr, ObjectHostSessionManager* oh_sess_mgr, ObjectSessionManager* obj_sess_mgr) {
    if (addr == Address4::Null) {
        SILOG(space, fatal, "The requested server ID isn't in ServerIDMap");
        space_context->shutdown();
    }

    Server* server = new Server(space_context, auth, forwarder, loc_service, cseg, prox, oseg, addr, oh_sess_mgr, obj_sess_mgr);
    prox->initialize(cseg);
    space_context->add(prox);
    space_context->add(server);

    *server_out = server;
}
}

int main(int argc, char** argv) {

    using namespace Sirikata;

    DynamicLibrary::Initialize();

    InitOptions();
    Trace::Trace::InitOptions();
    SpaceTrace::InitOptions();
    InitSpaceOptions();
    ParseOptions(argc, argv, OPT_CONFIG_FILE);

    PluginManager plugins;
    plugins.loadList( GetOptionValue<String>(OPT_PLUGINS) );
    plugins.loadList( GetOptionValue<String>(OPT_SPACE_PLUGINS) );

    // Fill defaults after plugin loading to ensure plugin-added
    // options get their defaults.
    FillMissingOptionDefaults();
    // Rerun original parse to make sure any newly added options are
    // properly parsed.
    ParseOptions(argc, argv, OPT_CONFIG_FILE);

    ReportVersion(); // After options so log goes to the right place

    std::string time_server=GetOptionValue<String>("time-server");
    NTPTimeSync sync;
    if (time_server.size() > 0)
        sync.start(time_server);

    ServerID server_id = GetOptionValue<ServerID>("id");
    String trace_file = GetPerServerFile(STATS_TRACE_FILE, server_id);
    Sirikata::Trace::Trace* gTrace = new Trace::Trace(trace_file);

    // Compute the starting date/time
    String start_time_str = GetOptionValue<String>("wait-until");
    Time start_time = start_time_str.empty() ? Timer::now() : Timer::getSpecifiedDate( start_time_str );
    start_time += GetOptionValue<Duration>("wait-additional");

    Duration duration = GetOptionValue<Duration>("duration");

    Network::IOService* ios = Network::IOServiceFactory::makeIOService();
    Network::IOStrand* mainStrand = ios->createStrand();

    ODPSST::ConnectionManager* sstConnMgr = new ODPSST::ConnectionManager();
    OHDPSST::ConnectionManager* ohSstConnMgr = new OHDPSST::ConnectionManager();

    SpaceContext* space_context = new SpaceContext("space", server_id, sstConnMgr, ohSstConnMgr, ios, mainStrand, start_time, gTrace, duration);

    String servermap_type = GetOptionValue<String>("servermap");
    String servermap_options = GetOptionValue<String>("servermap-options");
    ServerIDMap * server_id_map =
        ServerIDMapFactory::getSingleton().getConstructor(servermap_type)(space_context, servermap_options);

    space_context->add(space_context);

    String timeseries_type = GetOptionValue<String>(OPT_TRACE_TIMESERIES);
    String timeseries_options = GetOptionValue<String>(OPT_TRACE_TIMESERIES_OPTIONS);
    Trace::TimeSeries* time_series = Trace::TimeSeriesFactory::getSingleton().getConstructor(timeseries_type)(space_context, timeseries_options);

    Sirikata::SpaceNetwork* gNetwork = NULL;
    String network_type = GetOptionValue<String>(NETWORK_TYPE);
    if (network_type == "tcp")
      gNetwork = new TCPSpaceNetwork(space_context);

    BoundingBox3f region = GetOptionValue<BoundingBox3f>("region");
    Vector3ui32 layout = GetOptionValue<Vector3ui32>("layout");

    srand( GetOptionValue<uint32>("rand-seed") );

    ObjectHostSessionManager* oh_sess_mgr = new ObjectHostSessionManager(space_context);
    ObjectSessionManager* obj_sess_mgr = new ObjectSessionManager(space_context);

    String auth_type = GetOptionValue<String>(SPACE_OPT_AUTH);
    String auth_opts = GetOptionValue<String>(SPACE_OPT_AUTH_OPTIONS);
    Authenticator* auth =
        AuthenticatorFactory::getSingleton().getConstructor(auth_type)(space_context, auth_opts);

    gNetwork->setServerIDMap(server_id_map);

    Forwarder* forwarder = new Forwarder(space_context);

    String cseg_type = GetOptionValue<String>(CSEG);
    CoordinateSegmentation* cseg = NULL;
    if (cseg_type == "uniform")
        cseg = new UniformCoordinateSegmentation(space_context, region, layout);
    else if (cseg_type == "client") {
      cseg = new CoordinateSegmentationClient(space_context, region, layout, server_id_map);
    }
    else {
        assert(false);
        exit(-1);
    }

    String loc_update_type = GetOptionValue<String>(LOC_UPDATE);
    String loc_update_opts = GetOptionValue<String>(LOC_UPDATE_OPTIONS);
    LocationUpdatePolicy* loc_update_policy =
        LocationUpdatePolicyFactory::getSingleton().getConstructor(loc_update_type)(space_context, loc_update_opts);

    String loc_service_type = GetOptionValue<String>(LOC);
    String loc_service_opts = GetOptionValue<String>(LOC_OPTIONS);
    LocationService* loc_service =
        LocationServiceFactory::getSingleton().getConstructor(loc_service_type)(space_context, loc_update_policy, loc_service_opts);

    ServerMessageQueue* sq = NULL;
    String server_queue_type = GetOptionValue<String>(SERVER_QUEUE);
    if (server_queue_type == "fair") {
        sq = new FairServerMessageQueue(
            space_context, gNetwork,
            (ServerMessageQueue::Sender*)forwarder);
    }
    else {
        assert(false);
        exit(-1);
    }

    ServerMessageReceiver* server_message_receiver = NULL;
    String server_receiver_type = GetOptionValue<String>(SERVER_RECEIVER);
    if (server_queue_type == "fair")
        server_message_receiver =
                new FairServerMessageReceiver(space_context, gNetwork, (ServerMessageReceiver::Listener*)forwarder);
    else {
        assert(false);
        exit(-1);
    }

    LoadMonitor* loadMonitor = new LoadMonitor(space_context, cseg);

    // OSeg Cache
    OSegCache* oseg_cache = NULL;
    std::string cacheSelector = GetOptionValue<String>(CACHE_SELECTOR);
    uint32 cacheSize = GetOptionValue<uint32>(OSEG_CACHE_SIZE);
    if (cacheSelector == CACHE_TYPE_COMMUNICATION) {
        double cacheCommScaling = GetOptionValue<double>(CACHE_COMM_SCALING);
        oseg_cache = new CommunicationCache(space_context, cacheCommScaling, cseg, cacheSize);
    }
    else if (cacheSelector == CACHE_TYPE_ORIGINAL_LRU) {
        uint32 cacheCleanGroupSize = GetOptionValue<uint32>(OSEG_CACHE_CLEAN_GROUP_SIZE);
        Duration entryLifetime = GetOptionValue<Duration>(OSEG_CACHE_ENTRY_LIFETIME);
        oseg_cache = new CacheLRUOriginal(space_context, cacheSize, cacheCleanGroupSize, entryLifetime);
    }
    else {
        std::cout<<"\n\nUNKNOWN CACHE TYPE SELECTED.  Please re-try.\n\n";
        std::cout.flush();
        assert(false);
    }

    //Create OSeg
    std::string oseg_type = GetOptionValue<String>(OSEG);
    std::string oseg_options = GetOptionValue<String>(OSEG_OPTIONS);
    Network::IOStrand* osegStrand = space_context->ioService->createStrand();
    ObjectSegmentation* oseg =
        OSegFactory::getSingleton().getConstructor(oseg_type)(space_context, osegStrand, cseg, oseg_cache, oseg_options);
    //end create oseg

    // We have all the info to initialize the forwarder now
    forwarder->initialize(oseg, sq, server_message_receiver, loc_service);

    AggregateManager* aggmgr = new AggregateManager(loc_service);

    std::string prox_type = GetOptionValue<String>(OPT_PROX);
    std::string prox_options = GetOptionValue<String>(OPT_PROX_OPTIONS);
    Proximity* prox = ProximityFactory::getSingleton().getConstructor(prox_type)(space_context, loc_service, gNetwork, aggmgr, prox_options);

    // We need to do an async lookup, and to finish it the server needs to be
    // running. But we can't create the server until we have the address from
    // this lookup. We isolate as little as possible into this callback --
    // creating the server, finishing prox initialization, and getting them both
    // registered. We pass storage for the Server to the callback so we can
    // handle cleaning it up ourselves.
    using std::tr1::placeholders::_1;
    Server* server = NULL;
    server_id_map->lookupExternal(
        space_context->id(),
        space_context->mainStrand->wrap(
            std::tr1::bind( &createServer, &server, space_context, auth, forwarder, loc_service, cseg, prox, oseg, _1, oh_sess_mgr, obj_sess_mgr)
        )
    );

    // If we're one of the initial nodes, we'll have to wait until we hit the start time
    {
        Time now_time = Timer::now();
        if (start_time > now_time) {
            Duration sleep_time = start_time - now_time;
            printf("Waiting %f seconds\n", sleep_time.toSeconds() ); fflush(stdout);
#if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
            Sleep( sleep_time.toMilliseconds() );
#else
            usleep( sleep_time.toMicroseconds() );
#endif
        }
    }

    ///////////Go go go!! start of simulation/////////////////////

    space_context->add(auth);
    space_context->add(gNetwork);
    space_context->add(cseg);
    space_context->add(loc_service);
    space_context->add(oseg);
    space_context->add(loadMonitor);
    space_context->add(sstConnMgr);
    space_context->add(ohSstConnMgr);

    space_context->run(2);

    space_context->cleanup();

    if (GetOptionValue<bool>(PROFILE)) {
        space_context->profiler->report();
    }

    gTrace->prepareShutdown();
    prox->shutdown();
    Mesh::FilterFactory::destroy();
    ModelsSystemFactory::destroy();
    LocationServiceFactory::destroy();
    LocationUpdatePolicyFactory::destroy();
    delete server;
    delete sq;
    delete server_message_receiver;
    delete prox;
    delete aggmgr;
    delete server_id_map;

    delete loadMonitor;

    delete cseg;
    delete oseg;
    delete oseg_cache;
    delete loc_service;
    delete forwarder;

    delete obj_sess_mgr;
    delete oh_sess_mgr;

    delete gNetwork;
    gNetwork=NULL;

    gTrace->shutdown();
    delete gTrace;
    gTrace = NULL;

    delete space_context;
    space_context = NULL;

    delete time_series;

    delete mainStrand;
    delete osegStrand;

    Network::IOServiceFactory::destroyIOService(ios);

    delete sstConnMgr;
    delete ohSstConnMgr;

    sync.stop();

    plugins.gc();

    Sirikata::Logging::finishLog();

    return 0;
}
<commit_msg>Change the way the createServer callback is setup in space's main() because some platforms can't bind enough parameters.<commit_after>/*  Sirikata
 *  main.cpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
 * 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.
 */

#include <sirikata/core/util/Timer.hpp>
#include <sirikata/core/network/NTPTimeSync.hpp>

#include <sirikata/core/network/IOServiceFactory.hpp>
#include <sirikata/core/network/IOStrandImpl.hpp>

#include <sirikata/space/ObjectHostSession.hpp>
#include <sirikata/space/ObjectSessionManager.hpp>
#include <sirikata/space/Authenticator.hpp>

#include <sirikata/space/SpaceNetwork.hpp>

#include "Forwarder.hpp"

#include <sirikata/space/LocationService.hpp>

#include <sirikata/space/Proximity.hpp>
#include <sirikata/space/AggregateManager.hpp>
#include "Server.hpp"

#include "Options.hpp"
#include <sirikata/core/options/CommonOptions.hpp>
#include <sirikata/core/util/PluginManager.hpp>
#include <sirikata/core/trace/Trace.hpp>
#include "TCPSpaceNetwork.hpp"
#include "FairServerMessageReceiver.hpp"
#include "FairServerMessageQueue.hpp"
#include <sirikata/core/network/ServerIDMap.hpp>
#include "UniformCoordinateSegmentation.hpp"
#include "CoordinateSegmentationClient.hpp"
#include <sirikata/space/LoadMonitor.hpp>
#include <sirikata/space/ObjectSegmentation.hpp>
#include "caches/CommunicationCache.hpp"
#include "caches/CacheLRUOriginal.hpp"

#include <sirikata/space/SpaceContext.hpp>
#include <sirikata/mesh/Filter.hpp>
#include <sirikata/mesh/ModelsSystemFactory.hpp>

namespace {
using namespace Sirikata;

// Some platforms can't bind as many variables as we want to use, so we need to
// manually package them up.
struct ServerData {
    SpaceContext* space_context;
    Authenticator* auth;
    Forwarder* forwarder;
    LocationService* loc_service;
    CoordinateSegmentation* cseg;
    Proximity* prox;
    ObjectSegmentation* oseg;
    ObjectHostSessionManager* oh_sess_mgr;
    ObjectSessionManager* obj_sess_mgr;
};
void createServer(Server** server_out, ServerData sd, Address4 addr) {
    if (addr == Address4::Null) {
        SILOG(space, fatal, "The requested server ID isn't in ServerIDMap");
        sd.space_context->shutdown();
    }

    Server* server = new Server(sd.space_context, sd.auth, sd.forwarder, sd.loc_service, sd.cseg, sd.prox, sd.oseg, addr, sd.oh_sess_mgr, sd.obj_sess_mgr);
    sd.prox->initialize(sd.cseg);
    sd.space_context->add(sd.prox);
    sd.space_context->add(server);

    *server_out = server;
}
}

int main(int argc, char** argv) {

    using namespace Sirikata;

    DynamicLibrary::Initialize();

    InitOptions();
    Trace::Trace::InitOptions();
    SpaceTrace::InitOptions();
    InitSpaceOptions();
    ParseOptions(argc, argv, OPT_CONFIG_FILE);

    PluginManager plugins;
    plugins.loadList( GetOptionValue<String>(OPT_PLUGINS) );
    plugins.loadList( GetOptionValue<String>(OPT_SPACE_PLUGINS) );

    // Fill defaults after plugin loading to ensure plugin-added
    // options get their defaults.
    FillMissingOptionDefaults();
    // Rerun original parse to make sure any newly added options are
    // properly parsed.
    ParseOptions(argc, argv, OPT_CONFIG_FILE);

    ReportVersion(); // After options so log goes to the right place

    std::string time_server=GetOptionValue<String>("time-server");
    NTPTimeSync sync;
    if (time_server.size() > 0)
        sync.start(time_server);

    ServerID server_id = GetOptionValue<ServerID>("id");
    String trace_file = GetPerServerFile(STATS_TRACE_FILE, server_id);
    Sirikata::Trace::Trace* gTrace = new Trace::Trace(trace_file);

    // Compute the starting date/time
    String start_time_str = GetOptionValue<String>("wait-until");
    Time start_time = start_time_str.empty() ? Timer::now() : Timer::getSpecifiedDate( start_time_str );
    start_time += GetOptionValue<Duration>("wait-additional");

    Duration duration = GetOptionValue<Duration>("duration");

    Network::IOService* ios = Network::IOServiceFactory::makeIOService();
    Network::IOStrand* mainStrand = ios->createStrand();

    ODPSST::ConnectionManager* sstConnMgr = new ODPSST::ConnectionManager();
    OHDPSST::ConnectionManager* ohSstConnMgr = new OHDPSST::ConnectionManager();

    SpaceContext* space_context = new SpaceContext("space", server_id, sstConnMgr, ohSstConnMgr, ios, mainStrand, start_time, gTrace, duration);

    String servermap_type = GetOptionValue<String>("servermap");
    String servermap_options = GetOptionValue<String>("servermap-options");
    ServerIDMap * server_id_map =
        ServerIDMapFactory::getSingleton().getConstructor(servermap_type)(space_context, servermap_options);

    space_context->add(space_context);

    String timeseries_type = GetOptionValue<String>(OPT_TRACE_TIMESERIES);
    String timeseries_options = GetOptionValue<String>(OPT_TRACE_TIMESERIES_OPTIONS);
    Trace::TimeSeries* time_series = Trace::TimeSeriesFactory::getSingleton().getConstructor(timeseries_type)(space_context, timeseries_options);

    Sirikata::SpaceNetwork* gNetwork = NULL;
    String network_type = GetOptionValue<String>(NETWORK_TYPE);
    if (network_type == "tcp")
      gNetwork = new TCPSpaceNetwork(space_context);

    BoundingBox3f region = GetOptionValue<BoundingBox3f>("region");
    Vector3ui32 layout = GetOptionValue<Vector3ui32>("layout");

    srand( GetOptionValue<uint32>("rand-seed") );

    ObjectHostSessionManager* oh_sess_mgr = new ObjectHostSessionManager(space_context);
    ObjectSessionManager* obj_sess_mgr = new ObjectSessionManager(space_context);

    String auth_type = GetOptionValue<String>(SPACE_OPT_AUTH);
    String auth_opts = GetOptionValue<String>(SPACE_OPT_AUTH_OPTIONS);
    Authenticator* auth =
        AuthenticatorFactory::getSingleton().getConstructor(auth_type)(space_context, auth_opts);

    gNetwork->setServerIDMap(server_id_map);

    Forwarder* forwarder = new Forwarder(space_context);

    String cseg_type = GetOptionValue<String>(CSEG);
    CoordinateSegmentation* cseg = NULL;
    if (cseg_type == "uniform")
        cseg = new UniformCoordinateSegmentation(space_context, region, layout);
    else if (cseg_type == "client") {
      cseg = new CoordinateSegmentationClient(space_context, region, layout, server_id_map);
    }
    else {
        assert(false);
        exit(-1);
    }

    String loc_update_type = GetOptionValue<String>(LOC_UPDATE);
    String loc_update_opts = GetOptionValue<String>(LOC_UPDATE_OPTIONS);
    LocationUpdatePolicy* loc_update_policy =
        LocationUpdatePolicyFactory::getSingleton().getConstructor(loc_update_type)(space_context, loc_update_opts);

    String loc_service_type = GetOptionValue<String>(LOC);
    String loc_service_opts = GetOptionValue<String>(LOC_OPTIONS);
    LocationService* loc_service =
        LocationServiceFactory::getSingleton().getConstructor(loc_service_type)(space_context, loc_update_policy, loc_service_opts);

    ServerMessageQueue* sq = NULL;
    String server_queue_type = GetOptionValue<String>(SERVER_QUEUE);
    if (server_queue_type == "fair") {
        sq = new FairServerMessageQueue(
            space_context, gNetwork,
            (ServerMessageQueue::Sender*)forwarder);
    }
    else {
        assert(false);
        exit(-1);
    }

    ServerMessageReceiver* server_message_receiver = NULL;
    String server_receiver_type = GetOptionValue<String>(SERVER_RECEIVER);
    if (server_queue_type == "fair")
        server_message_receiver =
                new FairServerMessageReceiver(space_context, gNetwork, (ServerMessageReceiver::Listener*)forwarder);
    else {
        assert(false);
        exit(-1);
    }

    LoadMonitor* loadMonitor = new LoadMonitor(space_context, cseg);

    // OSeg Cache
    OSegCache* oseg_cache = NULL;
    std::string cacheSelector = GetOptionValue<String>(CACHE_SELECTOR);
    uint32 cacheSize = GetOptionValue<uint32>(OSEG_CACHE_SIZE);
    if (cacheSelector == CACHE_TYPE_COMMUNICATION) {
        double cacheCommScaling = GetOptionValue<double>(CACHE_COMM_SCALING);
        oseg_cache = new CommunicationCache(space_context, cacheCommScaling, cseg, cacheSize);
    }
    else if (cacheSelector == CACHE_TYPE_ORIGINAL_LRU) {
        uint32 cacheCleanGroupSize = GetOptionValue<uint32>(OSEG_CACHE_CLEAN_GROUP_SIZE);
        Duration entryLifetime = GetOptionValue<Duration>(OSEG_CACHE_ENTRY_LIFETIME);
        oseg_cache = new CacheLRUOriginal(space_context, cacheSize, cacheCleanGroupSize, entryLifetime);
    }
    else {
        std::cout<<"\n\nUNKNOWN CACHE TYPE SELECTED.  Please re-try.\n\n";
        std::cout.flush();
        assert(false);
    }

    //Create OSeg
    std::string oseg_type = GetOptionValue<String>(OSEG);
    std::string oseg_options = GetOptionValue<String>(OSEG_OPTIONS);
    Network::IOStrand* osegStrand = space_context->ioService->createStrand();
    ObjectSegmentation* oseg =
        OSegFactory::getSingleton().getConstructor(oseg_type)(space_context, osegStrand, cseg, oseg_cache, oseg_options);
    //end create oseg

    // We have all the info to initialize the forwarder now
    forwarder->initialize(oseg, sq, server_message_receiver, loc_service);

    AggregateManager* aggmgr = new AggregateManager(loc_service);

    std::string prox_type = GetOptionValue<String>(OPT_PROX);
    std::string prox_options = GetOptionValue<String>(OPT_PROX_OPTIONS);
    Proximity* prox = ProximityFactory::getSingleton().getConstructor(prox_type)(space_context, loc_service, gNetwork, aggmgr, prox_options);

    // We need to do an async lookup, and to finish it the server needs to be
    // running. But we can't create the server until we have the address from
    // this lookup. We isolate as little as possible into this callback --
    // creating the server, finishing prox initialization, and getting them both
    // registered. We pass storage for the Server to the callback so we can
    // handle cleaning it up ourselves.
    using std::tr1::placeholders::_1;
    Server* server = NULL;
    ServerData sd;
    sd.space_context = space_context;
    sd.auth = auth;
    sd.forwarder = forwarder;
    sd.loc_service = loc_service;
    sd.cseg = cseg;
    sd.prox = prox;
    sd.oseg = oseg;
    sd.oh_sess_mgr = oh_sess_mgr;
    sd.obj_sess_mgr = obj_sess_mgr;
    server_id_map->lookupExternal(
        space_context->id(),
        space_context->mainStrand->wrap(
            std::tr1::bind( &createServer, &server, sd, _1)
        )
    );

    // If we're one of the initial nodes, we'll have to wait until we hit the start time
    {
        Time now_time = Timer::now();
        if (start_time > now_time) {
            Duration sleep_time = start_time - now_time;
            printf("Waiting %f seconds\n", sleep_time.toSeconds() ); fflush(stdout);
#if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
            Sleep( sleep_time.toMilliseconds() );
#else
            usleep( sleep_time.toMicroseconds() );
#endif
        }
    }

    ///////////Go go go!! start of simulation/////////////////////

    space_context->add(auth);
    space_context->add(gNetwork);
    space_context->add(cseg);
    space_context->add(loc_service);
    space_context->add(oseg);
    space_context->add(loadMonitor);
    space_context->add(sstConnMgr);
    space_context->add(ohSstConnMgr);

    space_context->run(2);

    space_context->cleanup();

    if (GetOptionValue<bool>(PROFILE)) {
        space_context->profiler->report();
    }

    gTrace->prepareShutdown();
    prox->shutdown();
    Mesh::FilterFactory::destroy();
    ModelsSystemFactory::destroy();
    LocationServiceFactory::destroy();
    LocationUpdatePolicyFactory::destroy();
    delete server;
    delete sq;
    delete server_message_receiver;
    delete prox;
    delete aggmgr;
    delete server_id_map;

    delete loadMonitor;

    delete cseg;
    delete oseg;
    delete oseg_cache;
    delete loc_service;
    delete forwarder;

    delete obj_sess_mgr;
    delete oh_sess_mgr;

    delete gNetwork;
    gNetwork=NULL;

    gTrace->shutdown();
    delete gTrace;
    gTrace = NULL;

    delete space_context;
    space_context = NULL;

    delete time_series;

    delete mainStrand;
    delete osegStrand;

    Network::IOServiceFactory::destroyIOService(ios);

    delete sstConnMgr;
    delete ohSstConnMgr;

    sync.stop();

    plugins.gc();

    Sirikata::Logging::finishLog();

    return 0;
}
<|endoftext|>