<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgrePredefinedControllers.h"

#include "OgreRoot.h"
#include "OgreMath.h"
#include "OgreLogManager.h"
#include "OgreTextureUnitState.h"

namespace Ogre
{
    //-----------------------------------------------------------------------
    // FrameTimeControllerValue
    //-----------------------------------------------------------------------
    FrameTimeControllerValue::FrameTimeControllerValue()
    {
        // Register self
        Root::getSingleton().addFrameListener(this);
        mFrameTime = 0;
		mTimeFactor = 1;
		mFrameDelay = 0;
        mElapsedTime = 0;

    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameStarted(const FrameEvent &evt)
    {
		if(mFrameDelay)
		{
			// Fixed frame time
			mFrameTime = mFrameDelay;
			mTimeFactor =  mFrameDelay / evt.timeSinceLastFrame;
		}
		else
		{
			// Save the time value after applying time factor
			mFrameTime = mTimeFactor * evt.timeSinceLastFrame;
		}
        // Accumulate the elapsed time
        mElapsedTime += mFrameTime;
        return true;
    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameEnded(const FrameEvent &evt)
    {
        return true;
    }
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getValue() const
    {
        return mFrameTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setValue(Real value)
    {
        // Do nothing - value is set from frame listener
    }
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getTimeFactor(void) const {
		return mTimeFactor;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setTimeFactor(Real tf) {
		if(tf >= 0)
		{
			mTimeFactor = tf;
			mFrameDelay = 0;
		}
	}
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getFrameDelay(void) const {
		return mFrameDelay;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setFrameDelay(Real fd) {
		mTimeFactor = 0;
		mFrameDelay = fd;
	}
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getElapsedTime(void) const
    {
        return mElapsedTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setElapsedTime(Real elapsedTime)
    {
        mElapsedTime = elapsedTime;
    }
    //-----------------------------------------------------------------------
    // TextureFrameControllerValue
    //-----------------------------------------------------------------------
    TextureFrameControllerValue::TextureFrameControllerValue(TextureUnitState* t)
    {
        mTextureLayer = t;
    }
    //-----------------------------------------------------------------------
    Real TextureFrameControllerValue::getValue(void) const
    {
        int numFrames = mTextureLayer->getNumFrames();
        return (mTextureLayer->getCurrentFrame() / numFrames);
    }
    //-----------------------------------------------------------------------
    void TextureFrameControllerValue::setValue(Real value)
    {
        int numFrames = mTextureLayer->getNumFrames();
        mTextureLayer->setCurrentFrame((int)(value * numFrames) % numFrames);
    }
    //-----------------------------------------------------------------------
    // TexCoordModifierControllerValue
    //-----------------------------------------------------------------------
    TexCoordModifierControllerValue::TexCoordModifierControllerValue(TextureUnitState* t,
        bool translateU, bool translateV, bool scaleU, bool scaleV, bool rotate )
    {
        mTextureLayer = t;
        mTransU = translateU;
        mTransV = translateV;
        mScaleU = scaleU;
        mScaleV = scaleV;
        mRotate = rotate;
    }
    //-----------------------------------------------------------------------
    Real TexCoordModifierControllerValue::getValue() const
    {
        const Matrix4& pMat = mTextureLayer->getTextureTransform();
        if (mTransU)
        {
            return pMat[0][3];
        }
        else if (mTransV)
        {
            return pMat[1][3];
        }
        else if (mScaleU)
        {
            return pMat[0][0];
        }
        else if (mScaleV)
        {
            return pMat[1][1];
        }
        // Shouldn't get here
        return 0;
    }
    //-----------------------------------------------------------------------
    void TexCoordModifierControllerValue::setValue(Real value)
    {
        if (mTransU)
        {
            mTextureLayer->setTextureUScroll(value);
        }
        if (mTransV)
        {
            mTextureLayer->setTextureVScroll(value);
        }
        if (mScaleU)
        {
            if (value >= 0)
            {
                // Add 1 to scale (+ve scales up)
                mTextureLayer->setTextureUScale(1 + value);
            }
            else
            {
                // (-ve scales down)
                mTextureLayer->setTextureUScale(1 / -value);
            }
        }
        if (mScaleV)
        {
            if (value >= 0)
            {
                // Add 1 to scale (+ve scales up)
                mTextureLayer->setTextureVScale(1 + value);
            }
            else
            {
                // (-ve scales down)
                mTextureLayer->setTextureVScale(1 / -value);
            }
        }
        if (mRotate)
        {
            mTextureLayer->setTextureRotate(Radian(value * Math::TWO_PI));
        }
    }
    //-----------------------------------------------------------------------
    //-----------------------------------------------------------------------
	FloatGpuParameterControllerValue::FloatGpuParameterControllerValue(
			GpuProgramParameters* params, size_t index) :
		mParams(params), mParamIndex(index)
	{
	}
    //-----------------------------------------------------------------------
	Real FloatGpuParameterControllerValue::getValue(void) const
	{
		// do nothing, reading from a set of params not supported
		return 0.0f;
	}
    //-----------------------------------------------------------------------
	void FloatGpuParameterControllerValue::setValue(Real val)
	{
		static Vector4 v4 = Vector4(0,0,0,0);
		v4.x = val;
		mParams->setConstant(mParamIndex, v4);
	}
	//-----------------------------------------------------------------------
	// PassthroughControllerFunction
	//-----------------------------------------------------------------------
	PassthroughControllerFunction::PassthroughControllerFunction(bool delta)
		: ControllerFunction<Real>(delta)
	{
	}
	//-----------------------------------------------------------------------
	Real PassthroughControllerFunction::calculate(Real source)
	{
		return getAdjustedInput(source);

	}
    //-----------------------------------------------------------------------
    // AnimationControllerFunction
    //-----------------------------------------------------------------------
    AnimationControllerFunction::AnimationControllerFunction(Real sequenceTime, Real timeOffset)
		: ControllerFunction<Real>(false)
    {
        mSeqTime = sequenceTime;
        mTime = timeOffset;
    }
    //-----------------------------------------------------------------------
    Real AnimationControllerFunction::calculate(Real source)
    {
        // Assume source is time since last update
        mTime += source;
        // Wrap
        while (mTime >= mSeqTime) mTime -= mSeqTime;
        while (mTime < 0) mTime += mSeqTime;

        // Return parametric
        return mTime / mSeqTime;
    }
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setTime(Real timeVal)
	{
		mTime = timeVal;
	}
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setSequenceTime(Real seqVal)
	{
		mSeqTime = seqVal;
	}
    //-----------------------------------------------------------------------
    // ScaleControllerFunction
    //-----------------------------------------------------------------------
    ScaleControllerFunction::ScaleControllerFunction(Real factor, bool delta) : ControllerFunction<Real>(delta)
    {
        mScale = factor;
    }
    //-----------------------------------------------------------------------
    Real ScaleControllerFunction::calculate(Real source)
    {
        return getAdjustedInput(source * mScale);

    }
    //-----------------------------------------------------------------------
    // WaveformControllerFunction
    //-----------------------------------------------------------------------
    WaveformControllerFunction::WaveformControllerFunction(WaveformType wType, Real base,  Real frequency, Real phase, Real amplitude, bool delta, Real dutyCycle)
        :ControllerFunction<Real>(delta)
    {
        mWaveType = wType;
        mBase = base;
        mFrequency = frequency;
        mPhase = phase;
        mAmplitude = amplitude;
        mDeltaCount = phase;
		mDutyCycle = dutyCycle;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::getAdjustedInput(Real input)
    {
        Real adjusted = ControllerFunction<Real>::getAdjustedInput(input);

        // If not delta, adjust by phase here
        // (delta inputs have it adjusted at initialisation)
        if (!mDeltaInput)
        {
            adjusted += mPhase;
        }

        return adjusted;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::calculate(Real source)
    {
        Real input = getAdjustedInput(source * mFrequency);
        Real output;
        // For simplicity, factor input down to {0,1)
        // Use looped subtract rather than divide / round
        while (input >= 1.0)
            input -= 1.0;
        while (input < 0.0)
            input += 1.0;

        // Calculate output in -1..1 range
        switch (mWaveType)
        {
        case WFT_SINE:
            output = Math::Sin(Radian(input * Math::TWO_PI));
            break;
        case WFT_TRIANGLE:
            if (input < 0.25)
                output = input * 4;
            else if (input >= 0.25 && input < 0.75)
                output = 1.0 - ((input - 0.25) * 4);
            else
                output = ((input - 0.75) * 4) - 1.0;

            break;
        case WFT_SQUARE:
            if (input <= 0.5)
                output = 1.0;
            else
                output = -1.0;
            break;
        case WFT_SAWTOOTH:
            output = (input * 2) - 1;
            break;
        case WFT_INVERSE_SAWTOOTH:
            output = -((input * 2) - 1);
            break;
		case WFT_PWM:
			if( input <= mDutyCycle )
				output = 1.0;
			else
				output = -1.0;
			break;
        }

        // Scale output into 0..1 range and then by base + amplitude
        return mBase + ((output + 1.0) * 0.5 * mAmplitude);

    }
}

<commit_msg>Fix wave_xform and scaling factors. 1.0 should be the base otherwise it's very unintuitive to try to figure out the correct parameters. Also all previous demos assumed that basis.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program 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 program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgrePredefinedControllers.h"

#include "OgreRoot.h"
#include "OgreMath.h"
#include "OgreLogManager.h"
#include "OgreTextureUnitState.h"

namespace Ogre
{
    //-----------------------------------------------------------------------
    // FrameTimeControllerValue
    //-----------------------------------------------------------------------
    FrameTimeControllerValue::FrameTimeControllerValue()
    {
        // Register self
        Root::getSingleton().addFrameListener(this);
        mFrameTime = 0;
		mTimeFactor = 1;
		mFrameDelay = 0;
        mElapsedTime = 0;

    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameStarted(const FrameEvent &evt)
    {
		if(mFrameDelay)
		{
			// Fixed frame time
			mFrameTime = mFrameDelay;
			mTimeFactor =  mFrameDelay / evt.timeSinceLastFrame;
		}
		else
		{
			// Save the time value after applying time factor
			mFrameTime = mTimeFactor * evt.timeSinceLastFrame;
		}
        // Accumulate the elapsed time
        mElapsedTime += mFrameTime;
        return true;
    }
    //-----------------------------------------------------------------------
    bool FrameTimeControllerValue::frameEnded(const FrameEvent &evt)
    {
        return true;
    }
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getValue() const
    {
        return mFrameTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setValue(Real value)
    {
        // Do nothing - value is set from frame listener
    }
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getTimeFactor(void) const {
		return mTimeFactor;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setTimeFactor(Real tf) {
		if(tf >= 0)
		{
			mTimeFactor = tf;
			mFrameDelay = 0;
		}
	}
	//-----------------------------------------------------------------------
	Real FrameTimeControllerValue::getFrameDelay(void) const {
		return mFrameDelay;
	}
	//-----------------------------------------------------------------------
	void FrameTimeControllerValue::setFrameDelay(Real fd) {
		mTimeFactor = 0;
		mFrameDelay = fd;
	}
    //-----------------------------------------------------------------------
    Real FrameTimeControllerValue::getElapsedTime(void) const
    {
        return mElapsedTime;
    }
    //-----------------------------------------------------------------------
    void FrameTimeControllerValue::setElapsedTime(Real elapsedTime)
    {
        mElapsedTime = elapsedTime;
    }
    //-----------------------------------------------------------------------
    // TextureFrameControllerValue
    //-----------------------------------------------------------------------
    TextureFrameControllerValue::TextureFrameControllerValue(TextureUnitState* t)
    {
        mTextureLayer = t;
    }
    //-----------------------------------------------------------------------
    Real TextureFrameControllerValue::getValue(void) const
    {
        int numFrames = mTextureLayer->getNumFrames();
        return (mTextureLayer->getCurrentFrame() / numFrames);
    }
    //-----------------------------------------------------------------------
    void TextureFrameControllerValue::setValue(Real value)
    {
        int numFrames = mTextureLayer->getNumFrames();
        mTextureLayer->setCurrentFrame((int)(value * numFrames) % numFrames);
    }
    //-----------------------------------------------------------------------
    // TexCoordModifierControllerValue
    //-----------------------------------------------------------------------
    TexCoordModifierControllerValue::TexCoordModifierControllerValue(TextureUnitState* t,
        bool translateU, bool translateV, bool scaleU, bool scaleV, bool rotate )
    {
        mTextureLayer = t;
        mTransU = translateU;
        mTransV = translateV;
        mScaleU = scaleU;
        mScaleV = scaleV;
        mRotate = rotate;
    }
    //-----------------------------------------------------------------------
    Real TexCoordModifierControllerValue::getValue() const
    {
        const Matrix4& pMat = mTextureLayer->getTextureTransform();
        if (mTransU)
        {
            return pMat[0][3];
        }
        else if (mTransV)
        {
            return pMat[1][3];
        }
        else if (mScaleU)
        {
            return pMat[0][0];
        }
        else if (mScaleV)
        {
            return pMat[1][1];
        }
        // Shouldn't get here
        return 0;
    }
    //-----------------------------------------------------------------------
    void TexCoordModifierControllerValue::setValue(Real value)
    {
        if (mTransU)
        {
            mTextureLayer->setTextureUScroll(value);
        }
        if (mTransV)
        {
            mTextureLayer->setTextureVScroll(value);
        }
        if (mScaleU)
        {
            mTextureLayer->setTextureUScale(value);
        }
        if (mScaleV)
        {
            mTextureLayer->setTextureVScale(value);
        }
        if (mRotate)
        {
            mTextureLayer->setTextureRotate(Radian(value * Math::TWO_PI));
        }
    }
    //-----------------------------------------------------------------------
    //-----------------------------------------------------------------------
	FloatGpuParameterControllerValue::FloatGpuParameterControllerValue(
			GpuProgramParameters* params, size_t index) :
		mParams(params), mParamIndex(index)
	{
	}
    //-----------------------------------------------------------------------
	Real FloatGpuParameterControllerValue::getValue(void) const
	{
		// do nothing, reading from a set of params not supported
		return 0.0f;
	}
    //-----------------------------------------------------------------------
	void FloatGpuParameterControllerValue::setValue(Real val)
	{
		static Vector4 v4 = Vector4(0,0,0,0);
		v4.x = val;
		mParams->setConstant(mParamIndex, v4);
	}
	//-----------------------------------------------------------------------
	// PassthroughControllerFunction
	//-----------------------------------------------------------------------
	PassthroughControllerFunction::PassthroughControllerFunction(bool delta)
		: ControllerFunction<Real>(delta)
	{
	}
	//-----------------------------------------------------------------------
	Real PassthroughControllerFunction::calculate(Real source)
	{
		return getAdjustedInput(source);

	}
    //-----------------------------------------------------------------------
    // AnimationControllerFunction
    //-----------------------------------------------------------------------
    AnimationControllerFunction::AnimationControllerFunction(Real sequenceTime, Real timeOffset)
		: ControllerFunction<Real>(false)
    {
        mSeqTime = sequenceTime;
        mTime = timeOffset;
    }
    //-----------------------------------------------------------------------
    Real AnimationControllerFunction::calculate(Real source)
    {
        // Assume source is time since last update
        mTime += source;
        // Wrap
        while (mTime >= mSeqTime) mTime -= mSeqTime;
        while (mTime < 0) mTime += mSeqTime;

        // Return parametric
        return mTime / mSeqTime;
    }
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setTime(Real timeVal)
	{
		mTime = timeVal;
	}
	//-----------------------------------------------------------------------
	void AnimationControllerFunction::setSequenceTime(Real seqVal)
	{
		mSeqTime = seqVal;
	}
    //-----------------------------------------------------------------------
    // ScaleControllerFunction
    //-----------------------------------------------------------------------
    ScaleControllerFunction::ScaleControllerFunction(Real factor, bool delta) : ControllerFunction<Real>(delta)
    {
        mScale = factor;
    }
    //-----------------------------------------------------------------------
    Real ScaleControllerFunction::calculate(Real source)
    {
        return getAdjustedInput(source * mScale);

    }
    //-----------------------------------------------------------------------
    // WaveformControllerFunction
    //-----------------------------------------------------------------------
    WaveformControllerFunction::WaveformControllerFunction(WaveformType wType, Real base,  Real frequency, Real phase, Real amplitude, bool delta, Real dutyCycle)
        :ControllerFunction<Real>(delta)
    {
        mWaveType = wType;
        mBase = base;
        mFrequency = frequency;
        mPhase = phase;
        mAmplitude = amplitude;
        mDeltaCount = phase;
		mDutyCycle = dutyCycle;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::getAdjustedInput(Real input)
    {
        Real adjusted = ControllerFunction<Real>::getAdjustedInput(input);

        // If not delta, adjust by phase here
        // (delta inputs have it adjusted at initialisation)
        if (!mDeltaInput)
        {
            adjusted += mPhase;
        }

        return adjusted;
    }
    //-----------------------------------------------------------------------
    Real WaveformControllerFunction::calculate(Real source)
    {
        Real input = getAdjustedInput(source * mFrequency);
        Real output;
        // For simplicity, factor input down to {0,1)
        // Use looped subtract rather than divide / round
        while (input >= 1.0)
            input -= 1.0;
        while (input < 0.0)
            input += 1.0;

        // Calculate output in -1..1 range
        switch (mWaveType)
        {
        case WFT_SINE:
            output = Math::Sin(Radian(input * Math::TWO_PI));
            break;
        case WFT_TRIANGLE:
            if (input < 0.25)
                output = input * 4;
            else if (input >= 0.25 && input < 0.75)
                output = 1.0 - ((input - 0.25) * 4);
            else
                output = ((input - 0.75) * 4) - 1.0;

            break;
        case WFT_SQUARE:
            if (input <= 0.5)
                output = 1.0;
            else
                output = -1.0;
            break;
        case WFT_SAWTOOTH:
            output = (input * 2) - 1;
            break;
        case WFT_INVERSE_SAWTOOTH:
            output = -((input * 2) - 1);
            break;
		case WFT_PWM:
			if( input <= mDutyCycle )
				output = 1.0;
			else
				output = -1.0;
			break;
        }

        // Scale output into 0..1 range and then by base + amplitude
        return mBase + ((output + 1.0) * 0.5 * mAmplitude);

    }
}

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * GARGOYLE_PSCAND: Gargoyle Port Scan Detector
 *
 * main cleanup daemon
 *
 * Copyright (c) 2017, Bayshore Networks, 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:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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 <stdexcept>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "sqlite_wrapper_api.h"
#include "iptables_wrapper_api.h"
#include "singleton.h"
#include "gargoyle_config_vals.h"
#include "config_variables.h"

bool DEBUG = false;

bool validate_ip_addr(std::string ip_addr)
{
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ip_addr.c_str(), &(sa.sin_addr));
    return result != 0;
}

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

    if (geteuid() != 0) {
    	std::cerr << std::endl << "Root privileges are necessary for this to run ..." << std::endl << std::endl;
    	return 1;
    }

    char ip[16];

    if (DEBUG)
    	std::cout << "ARGC " << argc << std::endl;

    if (argc == 2) {

		if (validate_ip_addr(argv[1])) {

			strncpy(ip, argv[1], 15);
			ip[strlen(ip)] = '\0';

		    if (DEBUG)
		    	std::cout << "IP addr: " << ip << std::endl;

			size_t rule_ix = iptables_find_rule_in_chain(GARGOYLE_CHAIN_NAME, ip);

		    if (DEBUG)
		    	std::cout << "RuleIX: " << rule_ix << std::endl;

			if (rule_ix > 0 && ip) {

				// find the host ix for the ip
				int host_ix = get_host_ix(ip);
				if (host_ix > 0) {

					// find the row ix for this host (in detected_hosts table)
					size_t row_ix = get_detected_hosts_row_ix_by_host_ix(host_ix);
					if (row_ix > 0) {

					    if (DEBUG)
					    	std::cout << "Host ix: " << host_ix << std::endl;
						// delete all records for this host_ix from hosts_ports_hits table
						remove_host_ports_all(host_ix);

					    if (DEBUG)
					    	std::cout << "Row ix: " << row_ix << std::endl;
						// delete row from detected_hosts
						remove_detected_host(row_ix);

						int tstamp = (int) time(NULL);

						// add to ignore ip table
						add_host_to_ignore(host_ix, tstamp);

						iptables_delete_rule_from_chain(GARGOYLE_CHAIN_NAME, rule_ix);

						syslog(LOG_INFO | LOG_LOCAL6, "%s-%s=\"%s\" %s=\"%d\"", "manually unblocked", VIOLATOR_SYSLOG, ip, TIMESTAMP_SYSLOG, tstamp);
					}
				}
			}
		}
    }
	return 0;
}
<commit_msg>added a simple usage statement to the unblock prog<commit_after>/*****************************************************************************
 *
 * GARGOYLE_PSCAND: Gargoyle Port Scan Detector
 *
 * main cleanup daemon
 *
 * Copyright (c) 2017, Bayshore Networks, 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:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 * following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 * following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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 <stdexcept>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "sqlite_wrapper_api.h"
#include "iptables_wrapper_api.h"
#include "singleton.h"
#include "gargoyle_config_vals.h"
#include "config_variables.h"

bool DEBUG = false;

bool validate_ip_addr(std::string ip_addr)
{
    struct sockaddr_in sa;
    int result = inet_pton(AF_INET, ip_addr.c_str(), &(sa.sin_addr));
    return result != 0;
}

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

    if (geteuid() != 0) {
    	std::cerr << std::endl << "Root privileges are necessary for this to run ..." << std::endl << std::endl;
    	return 1;
    }

    char ip[16];

    if (DEBUG)
    	std::cout << "ARGC " << argc << std::endl;

    if (argc == 2) {

		if (validate_ip_addr(argv[1])) {

			strncpy(ip, argv[1], 15);
			ip[strlen(ip)] = '\0';

		    if (DEBUG)
		    	std::cout << "IP addr: " << ip << std::endl;

			size_t rule_ix = iptables_find_rule_in_chain(GARGOYLE_CHAIN_NAME, ip);

		    if (DEBUG)
		    	std::cout << "RuleIX: " << rule_ix << std::endl;

			if (rule_ix > 0 && ip) {

				// find the host ix for the ip
				int host_ix = get_host_ix(ip);
				if (host_ix > 0) {

					// find the row ix for this host (in detected_hosts table)
					size_t row_ix = get_detected_hosts_row_ix_by_host_ix(host_ix);
					if (row_ix > 0) {

					    if (DEBUG)
					    	std::cout << "Host ix: " << host_ix << std::endl;
						// delete all records for this host_ix from hosts_ports_hits table
						remove_host_ports_all(host_ix);

					    if (DEBUG)
					    	std::cout << "Row ix: " << row_ix << std::endl;
						// delete row from detected_hosts
						remove_detected_host(row_ix);

						int tstamp = (int) time(NULL);

						// add to ignore ip table
						add_host_to_ignore(host_ix, tstamp);

						iptables_delete_rule_from_chain(GARGOYLE_CHAIN_NAME, rule_ix);

						syslog(LOG_INFO | LOG_LOCAL6, "%s-%s=\"%s\" %s=\"%d\"", "manually unblocked", VIOLATOR_SYSLOG, ip, TIMESTAMP_SYSLOG, tstamp);
					}
				}
			}
		}
    } else {
    	std::cout << std::endl << "Usage: ./gargoyle_pscand_unblockip ip_addr" << std::endl << std::endl;
    }
	return 0;
}
<|endoftext|>


<commit_before>/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "sdkconfig.h"
#include <cmath>

#define ms(x) (x/portTICK_PERIOD_MS)

#define DUMP_VAR_d(x) \
 printf("%s:%d:%s=<%d>\n",__FILE__,__LINE__,#x,x)

#define DUMP_VAR_f(x) \
 printf("%s:%d:%s=<%f>\n",__FILE__,__LINE__,#x,x)

static const int iConstSampleRate = 100;
static const int iConstSampleDelay = 1000/iConstSampleRate;
static const double pi = std::acos(-1);

static char signal(int counter)
{
   double x = 2 * pi * (double)counter/(double)iConstSampleRate;
   double y = sin(x);
   DUMP_VAR_d(counter);
   DUMP_VAR_f(x);
   DUMP_VAR_f(y);
   return y *126;
}

static int gSamplerCounter = 0;

void signal_generator_task(void *pvParameter)
{
    while(true) {
       auto sign = signal(gSamplerCounter++%iConstSampleRate);
       vTaskDelay(ms(iConstSampleDelay));
    }
}

extern "C" void signal_generator_app_main()
{
    xTaskCreate(&signal_generator_task, "signal_generator_task", 2048, NULL, 5, NULL);
}
<commit_msg>Update signal.generator.cpp<commit_after>/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "sdkconfig.h"
#include <cmath>

#define ms(x) (x/portTICK_PERIOD_MS)

#define DUMP_VAR_d(x) \
 printf("%s:%d:%s=<%d>\n",__FILE__,__LINE__,#x,x)

#define DUMP_VAR_f(x) \
 printf("%s:%d:%s=<%f>\n",__FILE__,__LINE__,#x,x)

extern "C" ble_server_notify(char);

static const int iConstSampleRate = 100;
static const int iConstSampleDelay = 1000/iConstSampleRate;
static const double pi = std::acos(-1);

static char signal(int counter)
{
   double x = 2 * pi * (double)counter/(double)iConstSampleRate;
   double y = sin(x);
   DUMP_VAR_d(counter);
   DUMP_VAR_f(x);
   DUMP_VAR_f(y);
   return y *126;
}

static int gSamplerCounter = 0;

void signal_generator_task(void *pvParameter)
{
    while(true) {
       auto sign = signal(gSamplerCounter++%iConstSampleRate);
       ble_server_notify(sign);
       vTaskDelay(ms(iConstSampleDelay));
    }
}

extern "C" void signal_generator_app_main()
{
    xTaskCreate(&signal_generator_task, "signal_generator_task", 2048, NULL, 5, NULL);
}
<|endoftext|>


<commit_before>#ifndef CLUSTERING_SUGGESTER_SUGGESTER_TCC_
#define CLUSTERING_SUGGESTER_SUGGESTER_TCC_

#include "stl_utils.hpp"
#include "containers/priority_queue.hpp"

namespace {

struct priority_t {
    machine_id_t machine_id;

    bool pinned;
    int redundancy_cost;
    float backfill_cost;

    priority_t() { }

    priority_t(machine_id_t _machine_id, bool _pinned,
               int _redundancy_cost, float _backfill_cost)
        : machine_id(_machine_id), pinned(_pinned),
          redundancy_cost(_redundancy_cost), backfill_cost(_backfill_cost)
    { }
};

bool operator<(const priority_t &x, const priority_t &y) {
//CONTINUE:
    //Round 1: Pinnings.
    //F I G H T
    if (x.pinned && !y.pinned) {
        return false;
    } else if (y.pinned && !x.pinned) {
        return true;
    }

    //Round 2: Redundancy.
    //F I G H T
    if (x.redundancy_cost < y.redundancy_cost) {
        return false;
    } else if (y.redundancy_cost < x.redundancy_cost) {
        return true;
    }

    //Round 3: Backfill cost.
    //F I G H T
    if (x.backfill_cost < y.backfill_cost) {
        return false;
    } else if (y.backfill_cost < x.backfill_cost) {
        return true;
    }

    //You Lose!!
    //Continue?
    //(uncomment the below line to continue)
    //goto CONTINUE;
    //5
    //4
    //3
    //2
    //1
    //Last chance:
    //goto CONTINUE;
    //Didn't continue: Game Over
    return false; //They're equal
}

} //anonymous namespace

/* Returns a "score" indicating how expensive it would be to turn the machine
with the given business card into a primary or secondary for the given shard. */

template<class protocol_t>
float estimate_cost_to_get_up_to_date(
        const reactor_business_card_t<protocol_t> &business_card,
        const typename protocol_t::region_t &shard) {
    typedef reactor_business_card_t<protocol_t> rb_t;
    region_map_t<protocol_t, float> costs(shard, 3);
    for (typename rb_t::activity_map_t::const_iterator it = business_card.activities.begin();
            it != business_card.activities.end(); it++) {
        typename protocol_t::region_t intersection = region_intersection(it->second.first, shard);
        if (!region_is_empty(intersection)) {
            int cost;
            if (boost::get<typename rb_t::primary_when_safe_t>(&it->second.second)) {
                cost = 0;
            } else if (boost::get<typename rb_t::primary_t>(&it->second.second)) {
                cost = 0;
            } else if (boost::get<typename rb_t::secondary_up_to_date_t>(&it->second.second)) {
                cost = 1;
            } else if (boost::get<typename rb_t::secondary_without_primary_t>(&it->second.second)) {
                cost = 2;
            } else if (boost::get<typename rb_t::secondary_backfilling_t>(&it->second.second)) {
                cost = 2;
            } else if (boost::get<typename rb_t::nothing_when_safe_t>(&it->second.second)) {
                cost = 3;
            } else if (boost::get<typename rb_t::nothing_when_done_erasing_t>(&it->second.second)) {
                cost = 3;
            } else if (boost::get<typename rb_t::nothing_t>(&it->second.second)) {
                cost = 3;
            } else {
                // I don't know if this is unreachable, but cost would be uninitialized otherwise  - Sam
                // TODO: Is this really unreachable?
                unreachable();
            }
            /* It's ok to just call `set()` instead of trying to find the minimum
            because activities should never overlap. */
            costs.set(intersection, cost);
        }
    }
    float sum = 0;
    int count = 0;
    for (typename region_map_t<protocol_t, float>::iterator it = costs.begin(); it != costs.end(); it++) {
        /* TODO: Scale by how much data is in `it->first` */
        sum += it->second;
        count++;
    }
    return sum / count;
}

inline std::vector<machine_id_t> pick_n_best(priority_queue_t<priority_t> *candidates, int n, const datacenter_id_t &datacenter) {
    std::vector<machine_id_t> result;
    while ((int)result.size() < n) {
        if (candidates->empty()) {
            throw cannot_satisfy_goals_exc_t(strprintf("Didn't have enough unused machines in datacenter %s, we needed %d\n", uuid_to_str(datacenter).c_str(), n));
        } else {
            result.push_back(candidates->pop().machine_id);
        }
    }
    return result;
}

template<class protocol_t>
std::map<machine_id_t, typename blueprint_details::role_t> suggest_blueprint_for_shard(
        const std::map<machine_id_t, reactor_business_card_t<protocol_t> > &directory,
        const datacenter_id_t &primary_datacenter,
        const std::map<datacenter_id_t, int> &datacenter_affinities,
        const typename protocol_t::region_t &shard,
        const std::map<machine_id_t, datacenter_id_t> &machine_data_centers,
        const std::set<machine_id_t> &primary_pinnings,
        const std::set<machine_id_t> &secondary_pinnings,
        std::map<machine_id_t, int> *primary_usage,
        std::map<machine_id_t, int> *secondary_usage) {
    debugf("Suggest blueprint for shards\n");

    std::map<machine_id_t, typename blueprint_details::role_t> sub_blueprint;

    priority_queue_t<priority_t> primary_candidates;
    for (std::map<machine_id_t, datacenter_id_t>::const_iterator it = machine_data_centers.begin();
            it != machine_data_centers.end(); it++) {
        if (it->second == primary_datacenter) {
            bool pinned = !std_contains(primary_pinnings, it->first);

            int redundancy_cost = get_with_default(*primary_usage, it->first, 0);
            debugf("Redundancy cost: %d\n", redundancy_cost);

            float backfill_cost;
            if (std_contains(directory, it->first)) {
                backfill_cost = estimate_cost_to_get_up_to_date(directory.find(it->first)->second, shard);
            } else {
                backfill_cost = 3.0;
            }

            primary_candidates.push(priority_t(it->first, pinned, redundancy_cost, backfill_cost));
        }
    }
    machine_id_t primary = pick_n_best(&primary_candidates, 1, primary_datacenter).front();
    sub_blueprint[primary] = blueprint_details::role_primary;

    //Update primary_usage
    get_with_default(*primary_usage, primary, 0)++;

    for (std::map<datacenter_id_t, int>::const_iterator it = datacenter_affinities.begin(); it != datacenter_affinities.end(); it++) {
        priority_queue_t<priority_t> secondary_candidates;
        for (std::map<machine_id_t, datacenter_id_t>::const_iterator jt = machine_data_centers.begin();
                jt != machine_data_centers.end(); jt++) {
            if (jt->second == it->first && jt->first != primary) {
                bool pinned = std_contains(secondary_pinnings, jt->first);

                int redundancy_cost = get_with_default(*secondary_usage, jt->first, 0);

                float backfill_cost;
                if (std_contains(directory, jt->first)) {
                    backfill_cost = estimate_cost_to_get_up_to_date(directory.find(jt->first)->second, shard);
                } else {
                    backfill_cost = 3.0;
                }

                secondary_candidates.push(priority_t(jt->first, pinned, redundancy_cost, backfill_cost));
            }
        }
        std::vector<machine_id_t> secondaries = pick_n_best(&secondary_candidates, it->second, it->first);
        for (std::vector<machine_id_t>::iterator jt = secondaries.begin(); jt != secondaries.end(); jt++) {
            //Update secondary usage
            get_with_default(*secondary_usage, *jt, 0)++;
            sub_blueprint[*jt] = blueprint_details::role_secondary;
        }
    }

    for (std::map<machine_id_t, datacenter_id_t>::const_iterator it = machine_data_centers.begin();
            it != machine_data_centers.end(); it++) {
        /* This will set the value to `role_nothing` iff the peer is not already
        in the blueprint. */
        sub_blueprint.insert(std::make_pair(it->first, blueprint_details::role_nothing));
    }

    return sub_blueprint;
}

template<class protocol_t>
persistable_blueprint_t<protocol_t> suggest_blueprint(
        const std::map<machine_id_t, reactor_business_card_t<protocol_t> > &directory,
        const datacenter_id_t &primary_datacenter,
        const std::map<datacenter_id_t, int> &datacenter_affinities,
        const std::set<typename protocol_t::region_t> &shards,
        const std::map<machine_id_t, datacenter_id_t> &machine_data_centers,
        const region_map_t<protocol_t, machine_id_t> &primary_pinnings,
        const region_map_t<protocol_t, std::set<machine_id_t> > &secondary_pinnings) {

    typedef region_map_t<protocol_t, machine_id_t> primary_pinnings_map_t;
    typedef region_map_t<protocol_t, std::set<machine_id_t> > secondary_pinnings_map_t;

    persistable_blueprint_t<protocol_t> blueprint;

    //Maps to keep track of how much we're using each machine
    std::map<machine_id_t, int> primary_usage, secondary_usage;
    for (typename std::set<typename protocol_t::region_t>::const_iterator it = shards.begin();
            it != shards.end(); it++) {
        std::set<machine_id_t> machines_shard_primary_is_pinned_to;
        primary_pinnings_map_t primary_masked_map = primary_pinnings.mask(*it);

        for (typename primary_pinnings_map_t::iterator pit  = primary_masked_map.begin();
                                                       pit != primary_masked_map.end();
                                                       ++pit) {
            machines_shard_primary_is_pinned_to.insert(pit->second);
        }

        std::set<machine_id_t> machines_shard_secondary_is_pinned_to;
        secondary_pinnings_map_t secondary_masked_map = secondary_pinnings.mask(*it);

        for (typename secondary_pinnings_map_t::iterator pit  = secondary_masked_map.begin();
                                                         pit != secondary_masked_map.end();
                                                         ++pit) {
            machines_shard_secondary_is_pinned_to.insert(pit->second.begin(), pit->second.end());
        }

        std::map<machine_id_t, typename blueprint_details::role_t> shard_blueprint =
            suggest_blueprint_for_shard(directory, primary_datacenter, datacenter_affinities, *it,
                                        machine_data_centers, machines_shard_primary_is_pinned_to,
                                        machines_shard_secondary_is_pinned_to, &primary_usage,
                                        &secondary_usage);
        for (typename std::map<machine_id_t, typename blueprint_details::role_t>::iterator jt = shard_blueprint.begin();
                jt != shard_blueprint.end(); jt++) {
            blueprint.machines_roles[jt->first][*it] = jt->second;
        }
    }
    return blueprint;
}

#endif /* CLUSTERING_SUGGESTER_SUGGESTER_TCC_ */
<commit_msg>Fixes bugs with suggester not respecting pinnings.<commit_after>#ifndef CLUSTERING_SUGGESTER_SUGGESTER_TCC_
#define CLUSTERING_SUGGESTER_SUGGESTER_TCC_

#include "stl_utils.hpp"
#include "containers/priority_queue.hpp"

namespace {

struct priority_t {
    machine_id_t machine_id;

    bool pinned;
    bool would_rob_secondary;
    int redundancy_cost;
    float backfill_cost;

    priority_t() { }

    priority_t(machine_id_t _machine_id, bool _pinned, bool _would_rob_secondary,
               int _redundancy_cost, float _backfill_cost)
        : machine_id(_machine_id), pinned(_pinned), would_rob_secondary(_would_rob_secondary),
          redundancy_cost(_redundancy_cost), backfill_cost(_backfill_cost)
    { }
};

//It's easier to think about this function if you imagine it as the answer to:
//is y of higher priority than x

bool operator<(const priority_t &x, const priority_t &y) {
//CONTINUE:
    //Round 1: Pinnings.
    //F I G H T
    if (x.pinned && !y.pinned) {
        return false;
    } else if (y.pinned && !x.pinned) {
        return true;
    }

    //Round 2: Would Rob Secondary.
    //F I G H T
    if (x.would_rob_secondary && !y.would_rob_secondary) {
        return true;
    } else if (y.would_rob_secondary && !x.would_rob_secondary) {
        return false;
    }

    //Round 3: Redundancy.
    //F I G H T
    if (x.redundancy_cost < y.redundancy_cost) {
        return false;
    } else if (y.redundancy_cost < x.redundancy_cost) {
        return true;
    }

    //Round 4: Backfill cost.
    //F I G H T
    if (x.backfill_cost < y.backfill_cost) {
        return false;
    } else if (y.backfill_cost < x.backfill_cost) {
        return true;
    }

    //You Lose!!
    //Continue?
    //(uncomment the below line to continue)
    //goto CONTINUE;
    //5
    //4
    //3
    //2
    //1
    //Last chance:
    //goto CONTINUE;
    //Didn't continue: Game Over
    return false; //They're equal
}

} //anonymous namespace

/* Returns a "score" indicating how expensive it would be to turn the machine
with the given business card into a primary or secondary for the given shard. */

template<class protocol_t>
float estimate_cost_to_get_up_to_date(
        const reactor_business_card_t<protocol_t> &business_card,
        const typename protocol_t::region_t &shard) {
    typedef reactor_business_card_t<protocol_t> rb_t;
    region_map_t<protocol_t, float> costs(shard, 3);
    for (typename rb_t::activity_map_t::const_iterator it = business_card.activities.begin();
            it != business_card.activities.end(); it++) {
        typename protocol_t::region_t intersection = region_intersection(it->second.first, shard);
        if (!region_is_empty(intersection)) {
            int cost;
            if (boost::get<typename rb_t::primary_when_safe_t>(&it->second.second)) {
                cost = 0;
            } else if (boost::get<typename rb_t::primary_t>(&it->second.second)) {
                cost = 0;
            } else if (boost::get<typename rb_t::secondary_up_to_date_t>(&it->second.second)) {
                cost = 1;
            } else if (boost::get<typename rb_t::secondary_without_primary_t>(&it->second.second)) {
                cost = 2;
            } else if (boost::get<typename rb_t::secondary_backfilling_t>(&it->second.second)) {
                cost = 2;
            } else if (boost::get<typename rb_t::nothing_when_safe_t>(&it->second.second)) {
                cost = 3;
            } else if (boost::get<typename rb_t::nothing_when_done_erasing_t>(&it->second.second)) {
                cost = 3;
            } else if (boost::get<typename rb_t::nothing_t>(&it->second.second)) {
                cost = 3;
            } else {
                // I don't know if this is unreachable, but cost would be uninitialized otherwise  - Sam
                // TODO: Is this really unreachable?
                unreachable();
            }
            /* It's ok to just call `set()` instead of trying to find the minimum
            because activities should never overlap. */
            costs.set(intersection, cost);
        }
    }
    float sum = 0;
    int count = 0;
    for (typename region_map_t<protocol_t, float>::iterator it = costs.begin(); it != costs.end(); it++) {
        /* TODO: Scale by how much data is in `it->first` */
        sum += it->second;
        count++;
    }
    return sum / count;
}

inline std::vector<machine_id_t> pick_n_best(priority_queue_t<priority_t> *candidates, int n, const datacenter_id_t &datacenter) {
    std::vector<machine_id_t> result;
    while ((int)result.size() < n) {
        if (candidates->empty()) {
            throw cannot_satisfy_goals_exc_t(strprintf("Didn't have enough unused machines in datacenter %s, we needed %d\n", uuid_to_str(datacenter).c_str(), n));
        } else {
            result.push_back(candidates->pop().machine_id);
        }
    }
    return result;
}

template<class protocol_t>
std::map<machine_id_t, typename blueprint_details::role_t> suggest_blueprint_for_shard(
        const std::map<machine_id_t, reactor_business_card_t<protocol_t> > &directory,
        const datacenter_id_t &primary_datacenter,
        const std::map<datacenter_id_t, int> &datacenter_affinities,
        const typename protocol_t::region_t &shard,
        const std::map<machine_id_t, datacenter_id_t> &machine_data_centers,
        const std::set<machine_id_t> &primary_pinnings,
        const std::set<machine_id_t> &secondary_pinnings,
        std::map<machine_id_t, int> *primary_usage,
        std::map<machine_id_t, int> *secondary_usage) {

    std::map<machine_id_t, typename blueprint_details::role_t> sub_blueprint;

    priority_queue_t<priority_t> primary_candidates;
    for (std::map<machine_id_t, datacenter_id_t>::const_iterator it = machine_data_centers.begin();
            it != machine_data_centers.end(); it++) {
        if (it->second == primary_datacenter) {
            bool pinned = std_contains(primary_pinnings, it->first);

            bool would_rob_secondary = std_contains(secondary_pinnings, it->first);

            int redundancy_cost = get_with_default(*primary_usage, it->first, 0);

            float backfill_cost;
            if (std_contains(directory, it->first)) {
                backfill_cost = estimate_cost_to_get_up_to_date(directory.find(it->first)->second, shard);
            } else {
                backfill_cost = 3.0;
            }

            primary_candidates.push(priority_t(it->first, pinned, would_rob_secondary, redundancy_cost, backfill_cost));
        }
    }
    machine_id_t primary = pick_n_best(&primary_candidates, 1, primary_datacenter).front();
    sub_blueprint[primary] = blueprint_details::role_primary;

    //Update primary_usage
    get_with_default(*primary_usage, primary, 0)++;

    for (std::map<datacenter_id_t, int>::const_iterator it = datacenter_affinities.begin(); it != datacenter_affinities.end(); it++) {
        priority_queue_t<priority_t> secondary_candidates;
        for (std::map<machine_id_t, datacenter_id_t>::const_iterator jt = machine_data_centers.begin();
                jt != machine_data_centers.end(); jt++) {
            if (jt->second == it->first && jt->first != primary) {
                bool pinned = std_contains(secondary_pinnings, jt->first);

                int redundancy_cost = get_with_default(*secondary_usage, jt->first, 0);

                bool would_rob_secondary = false; //we're the secondary, we shan't be robbing ourselves

                float backfill_cost;
                if (std_contains(directory, jt->first)) {
                    backfill_cost = estimate_cost_to_get_up_to_date(directory.find(jt->first)->second, shard);
                } else {
                    backfill_cost = 3.0;
                }

                secondary_candidates.push(priority_t(jt->first, pinned, would_rob_secondary, redundancy_cost, backfill_cost));
            }
        }
        std::vector<machine_id_t> secondaries = pick_n_best(&secondary_candidates, it->second, it->first);
        for (std::vector<machine_id_t>::iterator jt = secondaries.begin(); jt != secondaries.end(); jt++) {
            //Update secondary usage
            get_with_default(*secondary_usage, *jt, 0)++;
            sub_blueprint[*jt] = blueprint_details::role_secondary;
        }
    }

    for (std::map<machine_id_t, datacenter_id_t>::const_iterator it = machine_data_centers.begin();
            it != machine_data_centers.end(); it++) {
        /* This will set the value to `role_nothing` iff the peer is not already
        in the blueprint. */
        sub_blueprint.insert(std::make_pair(it->first, blueprint_details::role_nothing));
    }

    return sub_blueprint;
}

template<class protocol_t>
persistable_blueprint_t<protocol_t> suggest_blueprint(
        const std::map<machine_id_t, reactor_business_card_t<protocol_t> > &directory,
        const datacenter_id_t &primary_datacenter,
        const std::map<datacenter_id_t, int> &datacenter_affinities,
        const std::set<typename protocol_t::region_t> &shards,
        const std::map<machine_id_t, datacenter_id_t> &machine_data_centers,
        const region_map_t<protocol_t, machine_id_t> &primary_pinnings,
        const region_map_t<protocol_t, std::set<machine_id_t> > &secondary_pinnings) {

    typedef region_map_t<protocol_t, machine_id_t> primary_pinnings_map_t;
    typedef region_map_t<protocol_t, std::set<machine_id_t> > secondary_pinnings_map_t;

    persistable_blueprint_t<protocol_t> blueprint;

    //Maps to keep track of how much we're using each machine
    std::map<machine_id_t, int> primary_usage, secondary_usage;
    for (typename std::set<typename protocol_t::region_t>::const_iterator it = shards.begin();
            it != shards.end(); it++) {
        std::set<machine_id_t> machines_shard_primary_is_pinned_to;
        primary_pinnings_map_t primary_masked_map = primary_pinnings.mask(*it);

        for (typename primary_pinnings_map_t::iterator pit  = primary_masked_map.begin();
                                                       pit != primary_masked_map.end();
                                                       ++pit) {
            machines_shard_primary_is_pinned_to.insert(pit->second);
        }

        std::set<machine_id_t> machines_shard_secondary_is_pinned_to;
        secondary_pinnings_map_t secondary_masked_map = secondary_pinnings.mask(*it);

        for (typename secondary_pinnings_map_t::iterator pit  = secondary_masked_map.begin();
                                                         pit != secondary_masked_map.end();
                                                         ++pit) {
            machines_shard_secondary_is_pinned_to.insert(pit->second.begin(), pit->second.end());
        }

        std::map<machine_id_t, typename blueprint_details::role_t> shard_blueprint =
            suggest_blueprint_for_shard(directory, primary_datacenter, datacenter_affinities, *it,
                                        machine_data_centers, machines_shard_primary_is_pinned_to,
                                        machines_shard_secondary_is_pinned_to, &primary_usage,
                                        &secondary_usage);
        for (typename std::map<machine_id_t, typename blueprint_details::role_t>::iterator jt = shard_blueprint.begin();
                jt != shard_blueprint.end(); jt++) {
            blueprint.machines_roles[jt->first][*it] = jt->second;
        }
    }
    return blueprint;
}

#endif /* CLUSTERING_SUGGESTER_SUGGESTER_TCC_ */
<|endoftext|>


<commit_before>/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "sdkconfig.h"

void signal_generator_task(void *pvParameter)
{
    while(1) {
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void signal_generator_app_main()
{
    xTaskCreate(&signal_generator_task, "signal_generator_task", 512, NULL, 5, NULL);
}
<commit_msg>Update signal.generator.cpp<commit_after>/* Blink Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "sdkconfig.h"
#include <cmath>

#define ms(x) (x/portTICK_PERIOD_MS)
#define DUMP_VAR_f(x) \
 printf("%s:%d:%s=<%f>",__FILE__,__LINE__,#x,x)

static const int iConstSampleRate = 50;
static const int iConstSampleDelay = 1000/iConstSampleRate;
static const double pi = std::acos(-1);

static char signal(int counter)
{
   double x = 2 pi * (double)counter/(double)50;
   double y = sin(x);
   DUMP_VAR_f(x);
   DUMP_VAR_f(y);
   return y *127;
}

static int gSamplerCounter = 0;

void signal_generator_task(void *pvParameter)
{
    while(true) {
       auto sign = signal(gSamplerCounter++%iConstSampleRate);
       vTaskDelay(ms(iConstSampleDelay));
    }
}

void signal_generator_app_main()
{
    xTaskCreate(&signal_generator_task, "signal_generator_task", 512, NULL, 5, NULL);
}
<|endoftext|>


<commit_before>/*  Sirikata Utilities -- Math Library
 *  BoundingBox.hpp
 *
 *  Copyright (c) 2009, Daniel Reiter Horn
 *  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.
 */
#ifndef _SIRIKATA_BOUNDING_BOX_HPP
#define _SIRIKATA_BOUNDING_BOX_HPP
namespace Sirikata {
template <typename real> class BoundingBox {
    Vector3<real> mMin;
    Vector3f mAcross;
public:
    BoundingBox() {}
    static BoundingBox<real> null() {
        return BoundingBox<real>(Vector3<real>(0,0,0),0);
    }

    BoundingBox(const Vector3<real>&center, float radius){
        mMin=center-Vector3<real>(radius,radius,radius);
        mAcross=Vector3f(2.0*radius,2.0*radius,2.0*radius);
    }
    template <typename flt> BoundingBox(const BoundingBox<flt>&input) {
        mMin=Vector3<real>(input.mMin);
        mAcross=input.mAcross;
    }
    BoundingBox(const Vector3<real>&imin,const Vector3<real>&imax){
        mMin=imin;
        mAcross=Vector3f(imax-imin);
    }

    const Vector3<real> &min()const{
        return mMin;
    }
    const Vector3f& across() const {
        return mAcross;
    }
    Vector3<real> max() const {
        return mMin+Vector3<real>(mAcross);
    }
    Vector3<real> center() const {
        return mMin+Vector3<real>(mAcross * 0.5f);
    }
    BoundingSphere<real> toBoundingSphere() {
        Vector3<real> center=this->center();
        float maxlen=(this->max()-this->center()).lengthSquared();
        float minlen=(this->min()-this->center()).lengthSquared();
        float radius=std::sqrt(minlen<maxlen?maxlen:minlen);
        return BoundingSphere<real>(center,radius);
    }

    BoundingBox<real> merge(const BoundingBox<real>&other) {
        return BoundingBox<real>(min().min(other.min()),
                           max().max(other.max()));
    }
    BoundingBox merge(const Vector3<real>&other) {
        return BoundingBox(min().min(other),
                           max().max(other));
    }
};
}
#endif
<commit_msg>Fill out the BoundingBox class with more useful methods.<commit_after>/*  Sirikata Utilities -- Math Library
 *  BoundingBox.hpp
 *
 *  Copyright (c) 2009, Daniel Reiter Horn
 *  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.
 */
#ifndef _SIRIKATA_BOUNDING_BOX_HPP
#define _SIRIKATA_BOUNDING_BOX_HPP

#define BBOX_CONTAINS_EPSILON 0.0005

namespace Sirikata {
template <typename real> class BoundingBox {
    Vector3<real> mMin;
    Vector3f mAcross;
public:
    BoundingBox() {}
    static BoundingBox<real> null() {
        return BoundingBox<real>(Vector3<real>(0,0,0),0);
    }

    BoundingBox(const Vector3<real>&center, float radius){
        mMin=center-Vector3<real>(radius,radius,radius);
        mAcross=Vector3f(2.0*radius,2.0*radius,2.0*radius);
    }
    template <typename flt> BoundingBox(const BoundingBox<flt>&input) {
        mMin=Vector3<real>(input.mMin);
        mAcross=input.mAcross;
    }
    BoundingBox(const Vector3<real>&imin,const Vector3<real>&imax){
        mMin=imin;
        mAcross=Vector3f(imax-imin);
    }

    const Vector3<real> &min()const{
        return mMin;
    }
    const Vector3f& across() const {
        return mAcross;
    }
    const Vector3f& diag() const {
        return mAcross;
    }
    const Vector3f& extents() const {
        return mAcross;
    }
    Vector3<real> max() const {
        return mMin+Vector3<real>(mAcross);
    }
    Vector3<real> center() const {
        return mMin+Vector3<real>(mAcross * 0.5f);
    }
    BoundingSphere<real> toBoundingSphere() {
        Vector3<real> center=this->center();
        float maxlen=(this->max()-this->center()).lengthSquared();
        float minlen=(this->min()-this->center()).lengthSquared();
        float radius=std::sqrt(minlen<maxlen?maxlen:minlen);
        return BoundingSphere<real>(center,radius);
    }

    BoundingBox<real> merge(const BoundingBox<real>&other) {
        return BoundingBox<real>(min().min(other.min()),
                           max().max(other.max()));
    }
    BoundingBox merge(const Vector3<real>&other) {
        return BoundingBox(min().min(other),
                           max().max(other));
    }

    BoundingBox& mergeIn(const BoundingBox<real>& other) {
        mMin = min().min(other.min());
        Vector3<real> mmax = max().max(other.max());
        mAcross = Vector3f(mmax - mMin);
        return *this;
    }

    BoundingBox& mergeIn(const Vector3<real>& other) {
        mMin = min().min(other);
        Vector3<real> mmax = max().max(other);
        mAcross = Vector3f(mmax - mMin);
        return *this;
    }

    bool contains(const Vector3<real>& point, real eps = BBOX_CONTAINS_EPSILON) const {
        Vector3<real> mmax = max();
        for(int i = 0; i < Vector3<real>::size; i++) {
            if (mMin[i] > point[i] || mmax[i] < point[i]) {
                if ( fabs(mMin[i] - point[i]) > eps &&
                    fabs(mmax[i] - point[i]) > eps )
                {
                    return false;
                }
            }
        }
        return true;
    }

    bool degenerate() const {
        for(int i = 0; i < Vector3<real>::size; i++)
            if (mAcross[i] <= 0) return true;
        return false;
    }

    real volume() const {
        if (degenerate()) return 0.0;
        real vol = 1;
        for(int i = 0; i < Vector3<real>::size; i++)
            vol *= mAcross[i];
        return vol;
    }

    Vector3<real> clamp(const Vector3<real>& v) const {
        return v.max(min()).min(max());
    }

    bool operator==(const BoundingBox& rhs) {
        return (mMin == rhs.mMin && mAcross == rhs.mAcross);
    }
    bool operator!=(const BoundingBox& rhs) {
        return (mMin != rhs.mMin || mAcross != rhs.mAcross);
    }

};

}
#endif
<|endoftext|>


<commit_before>// Tags.cpp
// Copyright (c) 2010, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "Tags.h"
#include "Tag.h"
#include "tinyxml/tinyxml.h"
#include "interface/Tool.h"

bool CTags::CanAdd(HeeksObj* object)
{
	return ((object != NULL) && (object->GetType() == TagType));
}

CTags & CTags::operator= ( const CTags & rhs )
{
	if (this != &rhs)
	{
		ObjList::operator=( rhs );
	}

	return(*this);
}

CTags::CTags( const CTags & rhs ) : ObjList(rhs)
{
}

const wxBitmap &CTags::GetIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/tags.png")));
	return *icon;
}

static CTags* object_for_tools = NULL;

class AddTagTool: public Tool
{
public:
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Add Tag");}

	void Run()
	{
		heeksCAD->CreateUndoPoint();
		CTag* new_object = new CTag();
		object_for_tools->Add(new_object, NULL);
		heeksCAD->Changed();
		heeksCAD->ClearMarkedList();
		heeksCAD->Mark(new_object);
	}
	bool CallChangedOnRun(){return false;}
	wxString BitmapPath(){ return _T("addtag");}
};

static AddTagTool add_tag_tool;

void CTags::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
	object_for_tools = this;
	t_list->push_back(&add_tag_tool);
}

void CTags::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "Tags" );
	root->LinkEndChild( element );
	WriteBaseXML(element);
}

//static
HeeksObj* CTags::ReadFromXMLElement(TiXmlElement* pElem)
{
	CTags* new_object = new CTags;
	new_object->ReadBaseXML(pElem);
	return new_object;
}
<commit_msg>Fixed SEGFAULT at Tags.cpp:50 caused by NULL object_for_tools<commit_after>// Tags.cpp
// Copyright (c) 2010, Dan Heeks
// This program is released under the BSD license. See the file COPYING for details.

#include "stdafx.h"
#include "Tags.h"
#include "Tag.h"
#include "tinyxml/tinyxml.h"
#include "interface/Tool.h"

bool CTags::CanAdd(HeeksObj* object)
{
	return ((object != NULL) && (object->GetType() == TagType));
}

CTags & CTags::operator= ( const CTags & rhs )
{
	if (this != &rhs)
	{
		ObjList::operator=( rhs );
	}

	return(*this);
}

CTags::CTags( const CTags & rhs ) : ObjList(rhs)
{
}

const wxBitmap &CTags::GetIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/tags.png")));
	return *icon;
}

static CTags* object_for_tools = NULL;

class AddTagTool: public Tool
{
public:
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Add Tag");}

	void Run()
	{
      if (object_for_tools) { // jcoffland: object_for_tools can be NULL
		heeksCAD->CreateUndoPoint();
		CTag* new_object = new CTag();
		object_for_tools->Add(new_object, NULL);
		heeksCAD->Changed();
		heeksCAD->ClearMarkedList();
		heeksCAD->Mark(new_object);
      }
	}
	bool CallChangedOnRun(){return false;}
	wxString BitmapPath(){ return _T("addtag");}
};

static AddTagTool add_tag_tool;

void CTags::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
	object_for_tools = this;
	t_list->push_back(&add_tag_tool);
}

void CTags::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "Tags" );
	root->LinkEndChild( element );
	WriteBaseXML(element);
}

//static
HeeksObj* CTags::ReadFromXMLElement(TiXmlElement* pElem)
{
	CTags* new_object = new CTags;
	new_object->ReadBaseXML(pElem);
	return new_object;
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2006, MassaRoddel, Arvid Norberg
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 the author 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.

*/

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/shared_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/peer_connection.hpp"
#include "libtorrent/bt_peer_connection.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent.hpp"
#include "libtorrent/extensions.hpp"

#include "libtorrent/extensions/ut_pex.hpp"

namespace libtorrent { namespace
{
	const char extension_name[] = "ut_pex";

	enum
	{
		extension_index = 1,
		max_peer_entries = 100
	};

	struct ut_pex_plugin: torrent_plugin
	{
		ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(0) {}

		virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection* pc);

		std::vector<char>& get_ut_pex_msg()
		{
			return m_ut_pex_msg;
		}

		// the second tick of the torrent
		// each minute the new lists of "added" + "added.f" and "dropped"
		// are calculated here and the pex message is created
		// each peer connection will use this message
		// max_peer_entries limits the packet size
		virtual void tick()
		{
			if (++m_1_minute < 60) return;

			m_1_minute = 0;
			std::list<tcp::endpoint> cs;
			for (torrent::peer_iterator i = m_torrent.begin()
				, end(m_torrent.end()); i != end; ++i)
			{
				// don't send out peers that we haven't connected to
				// (that have connected to us)
				if (!i->second->is_local()) continue;
				// don't send out peers that we haven't successfully connected to
				if (i->second->connecting()) continue;
				cs.push_back(i->first);
			}
			std::list<tcp::endpoint> added_peers, dropped_peers;

			std::set_difference(cs.begin(), cs.end(), m_old_peers.begin()
				, m_old_peers.end(), std::back_inserter(added_peers));
			std::set_difference(m_old_peers.begin(), m_old_peers.end()
				, cs.begin(), cs.end(), std::back_inserter(dropped_peers));
			m_old_peers = cs;

			unsigned int num_peers = max_peer_entries;

			std::string pla, pld, plf;
			std::back_insert_iterator<std::string> pla_out(pla);
			std::back_insert_iterator<std::string> pld_out(pld);
			std::back_insert_iterator<std::string> plf_out(plf);

			// TODO: use random selection in case added_peers.size() > num_peers
			for (std::list<tcp::endpoint>::const_iterator i = added_peers.begin()
				, end(added_peers.end());i != end; ++i)
			{
				if (!i->address().is_v4()) continue;
				detail::write_endpoint(*i, pla_out);
				// no supported flags to set yet
				// 0x01 - peer supports encryption
				detail::write_uint8(0, plf_out);

				if (--num_peers == 0) break;
			}

			num_peers = max_peer_entries;
			// TODO: use random selection in case dropped_peers.size() > num_peers
			for (std::list<tcp::endpoint>::const_iterator i = dropped_peers.begin()
				, end(dropped_peers.end());i != end; ++i)
			{
				if (!i->address().is_v4()) continue;
				detail::write_endpoint(*i, pld_out);

				if (--num_peers == 0) break;
			}

			entry pex(entry::dictionary_t);
			pex["added"] = pla;
			pex["dropped"] = pld;
			pex["added.f"] = plf;

			m_ut_pex_msg.clear();
			bencode(std::back_inserter(m_ut_pex_msg), pex);
		}

	private:
		torrent& m_torrent;

		std::list<tcp::endpoint> m_old_peers;
		int m_1_minute;
		std::vector<char> m_ut_pex_msg;
	};

	struct ut_pex_peer_plugin : peer_plugin
	{
		ut_pex_peer_plugin(torrent& t, peer_connection& pc, ut_pex_plugin& tp)
			: m_torrent(t)
			, m_pc(pc)
			, m_tp(tp)
			, m_1_minute(0)
			, m_message_index(0)
		{}

		virtual void add_handshake(entry& h)
		{
			entry& messages = h["m"];
			messages[extension_name] = extension_index;
		}

		virtual bool on_extension_handshake(entry const& h)
		{
			entry const& messages = h["m"];

			if (entry const* index = messages.find_key(extension_name))
			{
				m_message_index = index->integer();
				return true;
			}
			else
			{
				m_message_index = 0;
				return false;
			}
		}

		virtual bool on_extended(int length, int msg, buffer::const_interval body)
		{
			if (msg != extension_index) return false;
			if (m_message_index == 0) return false;

			if (length > 500 * 1024)
				throw protocol_error("ut peer exchange message larger than 500 kB");

			if (body.left() < length) return true;

			// in case we are a seed we do not use the peers
			// from the pex message to prevent us from
			// overloading ourself
			if (m_torrent.is_seed()) return true;

			entry Pex = bdecode(body.begin, body.end);
			entry* PeerList = Pex.find_key("added");

			if (!PeerList) return true;
			std::string const& peers = PeerList->string();
			int num_peers = peers.length() / 6;
			char const* in = peers.c_str();

			peer_id pid;
			pid.clear();
			policy& p = m_torrent.get_policy();
			for (int i = 0; i < num_peers; ++i)
			{
				tcp::endpoint adr = detail::read_v4_endpoint<tcp::endpoint>(in);
				if (!m_torrent.connection_for(adr)) p.peer_from_tracker(adr, pid);
			}
			return true;
		}

		// the peers second tick
		// every minute we send a pex message
		virtual void tick()
		{
			if (!m_message_index) return;	// no handshake yet
			if (++m_1_minute <= 60) return;

			send_ut_peer_list();
			m_1_minute = 0;
		}

	private:

		void send_ut_peer_list()
		{
			std::vector<char>& pex_msg = m_tp.get_ut_pex_msg();

			buffer::interval i = m_pc.allocate_send_buffer(6 + pex_msg.size());

			detail::write_uint32(1 + 1 + pex_msg.size(), i.begin);
			detail::write_uint8(bt_peer_connection::msg_extended, i.begin);
			detail::write_uint8(m_message_index, i.begin);
			std::copy(pex_msg.begin(), pex_msg.end(), i.begin);
			i.begin += pex_msg.size();

			assert(i.begin == i.end);
			m_pc.setup_send();
		}

		torrent& m_torrent;
		peer_connection& m_pc;
		ut_pex_plugin& m_tp;
		int m_1_minute;
		int m_message_index;
	};

	boost::shared_ptr<peer_plugin> ut_pex_plugin::new_connection(peer_connection* pc)
	{
		return boost::shared_ptr<peer_plugin>(new ut_pex_peer_plugin(m_torrent
			, *pc, *this));
	}
}}

namespace libtorrent
{

	boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent* t)
	{
		if (t->torrent_file().priv())
		{
			return boost::shared_ptr<torrent_plugin>();
		}
		return boost::shared_ptr<torrent_plugin>(new ut_pex_plugin(*t));
	}

}

<commit_msg>fixed typo<commit_after>/*

Copyright (c) 2006, MassaRoddel, Arvid Norberg
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 the author 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.

*/

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/shared_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/peer_connection.hpp"
#include "libtorrent/bt_peer_connection.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent.hpp"
#include "libtorrent/extensions.hpp"

#include "libtorrent/extensions/ut_pex.hpp"

namespace libtorrent { namespace
{
	const char extension_name[] = "ut_pex";

	enum
	{
		extension_index = 1,
		max_peer_entries = 100
	};

	struct ut_pex_plugin: torrent_plugin
	{
		ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(0) {}

		virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection* pc);

		std::vector<char>& get_ut_pex_msg()
		{
			return m_ut_pex_msg;
		}

		// the second tick of the torrent
		// each minute the new lists of "added" + "added.f" and "dropped"
		// are calculated here and the pex message is created
		// each peer connection will use this message
		// max_peer_entries limits the packet size
		virtual void tick()
		{
			if (++m_1_minute < 60) return;

			m_1_minute = 0;
			std::list<tcp::endpoint> cs;
			for (torrent::peer_iterator i = m_torrent.begin()
				, end(m_torrent.end()); i != end; ++i)
			{
				// don't send out peers that we haven't connected to
				// (that have connected to us)
				if (!i->second->is_local()) continue;
				// don't send out peers that we haven't successfully connected to
				if (i->second->is_connecting()) continue;
				cs.push_back(i->first);
			}
			std::list<tcp::endpoint> added_peers, dropped_peers;

			std::set_difference(cs.begin(), cs.end(), m_old_peers.begin()
				, m_old_peers.end(), std::back_inserter(added_peers));
			std::set_difference(m_old_peers.begin(), m_old_peers.end()
				, cs.begin(), cs.end(), std::back_inserter(dropped_peers));
			m_old_peers = cs;

			unsigned int num_peers = max_peer_entries;

			std::string pla, pld, plf;
			std::back_insert_iterator<std::string> pla_out(pla);
			std::back_insert_iterator<std::string> pld_out(pld);
			std::back_insert_iterator<std::string> plf_out(plf);

			// TODO: use random selection in case added_peers.size() > num_peers
			for (std::list<tcp::endpoint>::const_iterator i = added_peers.begin()
				, end(added_peers.end());i != end; ++i)
			{
				if (!i->address().is_v4()) continue;
				detail::write_endpoint(*i, pla_out);
				// no supported flags to set yet
				// 0x01 - peer supports encryption
				detail::write_uint8(0, plf_out);

				if (--num_peers == 0) break;
			}

			num_peers = max_peer_entries;
			// TODO: use random selection in case dropped_peers.size() > num_peers
			for (std::list<tcp::endpoint>::const_iterator i = dropped_peers.begin()
				, end(dropped_peers.end());i != end; ++i)
			{
				if (!i->address().is_v4()) continue;
				detail::write_endpoint(*i, pld_out);

				if (--num_peers == 0) break;
			}

			entry pex(entry::dictionary_t);
			pex["added"] = pla;
			pex["dropped"] = pld;
			pex["added.f"] = plf;

			m_ut_pex_msg.clear();
			bencode(std::back_inserter(m_ut_pex_msg), pex);
		}

	private:
		torrent& m_torrent;

		std::list<tcp::endpoint> m_old_peers;
		int m_1_minute;
		std::vector<char> m_ut_pex_msg;
	};

	struct ut_pex_peer_plugin : peer_plugin
	{
		ut_pex_peer_plugin(torrent& t, peer_connection& pc, ut_pex_plugin& tp)
			: m_torrent(t)
			, m_pc(pc)
			, m_tp(tp)
			, m_1_minute(0)
			, m_message_index(0)
		{}

		virtual void add_handshake(entry& h)
		{
			entry& messages = h["m"];
			messages[extension_name] = extension_index;
		}

		virtual bool on_extension_handshake(entry const& h)
		{
			entry const& messages = h["m"];

			if (entry const* index = messages.find_key(extension_name))
			{
				m_message_index = index->integer();
				return true;
			}
			else
			{
				m_message_index = 0;
				return false;
			}
		}

		virtual bool on_extended(int length, int msg, buffer::const_interval body)
		{
			if (msg != extension_index) return false;
			if (m_message_index == 0) return false;

			if (length > 500 * 1024)
				throw protocol_error("ut peer exchange message larger than 500 kB");

			if (body.left() < length) return true;

			// in case we are a seed we do not use the peers
			// from the pex message to prevent us from
			// overloading ourself
			if (m_torrent.is_seed()) return true;

			entry Pex = bdecode(body.begin, body.end);
			entry* PeerList = Pex.find_key("added");

			if (!PeerList) return true;
			std::string const& peers = PeerList->string();
			int num_peers = peers.length() / 6;
			char const* in = peers.c_str();

			peer_id pid;
			pid.clear();
			policy& p = m_torrent.get_policy();
			for (int i = 0; i < num_peers; ++i)
			{
				tcp::endpoint adr = detail::read_v4_endpoint<tcp::endpoint>(in);
				if (!m_torrent.connection_for(adr)) p.peer_from_tracker(adr, pid);
			}
			return true;
		}

		// the peers second tick
		// every minute we send a pex message
		virtual void tick()
		{
			if (!m_message_index) return;	// no handshake yet
			if (++m_1_minute <= 60) return;

			send_ut_peer_list();
			m_1_minute = 0;
		}

	private:

		void send_ut_peer_list()
		{
			std::vector<char>& pex_msg = m_tp.get_ut_pex_msg();

			buffer::interval i = m_pc.allocate_send_buffer(6 + pex_msg.size());

			detail::write_uint32(1 + 1 + pex_msg.size(), i.begin);
			detail::write_uint8(bt_peer_connection::msg_extended, i.begin);
			detail::write_uint8(m_message_index, i.begin);
			std::copy(pex_msg.begin(), pex_msg.end(), i.begin);
			i.begin += pex_msg.size();

			assert(i.begin == i.end);
			m_pc.setup_send();
		}

		torrent& m_torrent;
		peer_connection& m_pc;
		ut_pex_plugin& m_tp;
		int m_1_minute;
		int m_message_index;
	};

	boost::shared_ptr<peer_plugin> ut_pex_plugin::new_connection(peer_connection* pc)
	{
		return boost::shared_ptr<peer_plugin>(new ut_pex_peer_plugin(m_torrent
			, *pc, *this));
	}
}}

namespace libtorrent
{

	boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent* t)
	{
		if (t->torrent_file().priv())
		{
			return boost::shared_ptr<torrent_plugin>();
		}
		return boost::shared_ptr<torrent_plugin>(new ut_pex_plugin(*t));
	}

}

<|endoftext|>


<commit_before>/*
** Author(s):
**  - Cedric GESTES <gestes@aldebaran-robotics.com>
**
** Copyright (C) 2010, 2012 Aldebaran Robotics
*/

#include <iostream>
#include <string>
#include <map>

#include <qi/os.hpp>
#include <qimessaging/session.hpp>
#include <qimessaging/transport.hpp>
#include <qimessaging/object.hpp>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

static int uniqueReqId = 200;

void call(const std::string &addr)
{
  qi::Session session;
  session.setName("client.session");
  session.connect(addr);
  session.waitForConnected();

  std::vector<std::string> servs = session.services();
  for (int i = 0; i < servs.size(); ++i)
    std::cout << "service named " << servs[i] << std::endl;

  qi::Object *obj = session.service("serviceTest");

  if (obj == 0)
  {
      std::cerr << "obj == 0" << std::endl;
      return;
  }

  std::string result = obj->call<std::string>("reply", "plaf");

  std::cout << "answer:" << result << std::endl;

  qi::os::sleep(2);

  session.disconnect();
}

int main(int argc, char *argv[])
{
  // declare the program options
  po::options_description desc("Usage:\n  qi masterAddress [options]\nOptions");
  desc.add_options()
      ("help", "Print this help.")
      ("master-address",
       po::value<std::string>()->default_value(std::string("127.0.0.1:5555")),
       "The master address")
      ("gateway-address",
       po::value<std::string>()->default_value(std::string("127.0.0.1:12345")),
       "The gateway address");

  // allow master address to be specified as the first arg
  po::positional_options_description pos;
  pos.add("master-address", 1);

  // parse and store
  po::variables_map vm;
  try
  {
    po::store(po::command_line_parser(argc, argv).
              options(desc).positional(pos).run(), vm);
    po::notify(vm);

    if (vm.count("help"))
    {
      std::cout << desc << "\n";
      return 0;
    }

    if (vm.count("master-address") == 1 &&
        vm.count("gateway-address") == 1)
    {
      std::string masteraddr = vm["master-address"].as<std::string>();
      call(masteraddr);

      std::string gatewayaddr = vm["gateway-address"].as<std::string>();
      call(gatewayaddr);
    }
    else
    {
      std::cout << desc << "\n";
    }
  } catch (const boost::program_options::error&) {
    std::cout << desc << "\n";
  }

  return 0;
}
<commit_msg>Remove useless call to setName from client side.<commit_after>/*
** Author(s):
**  - Cedric GESTES <gestes@aldebaran-robotics.com>
**
** Copyright (C) 2010, 2012 Aldebaran Robotics
*/

#include <iostream>
#include <string>
#include <map>

#include <qi/os.hpp>
#include <qimessaging/session.hpp>
#include <qimessaging/transport.hpp>
#include <qimessaging/object.hpp>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

static int uniqueReqId = 200;

void call(const std::string &addr)
{
  qi::Session session;
  session.connect(addr);
  session.waitForConnected();

  std::vector<std::string> servs = session.services();
  for (int i = 0; i < servs.size(); ++i)
    std::cout << "service named " << servs[i] << std::endl;

  qi::Object *obj = session.service("serviceTest");

  if (obj == 0)
  {
      std::cerr << "obj == 0" << std::endl;
      return;
  }

  std::string result = obj->call<std::string>("reply", "plaf");

  std::cout << "answer:" << result << std::endl;

  qi::os::sleep(2);

  session.disconnect();
}

int main(int argc, char *argv[])
{
  // declare the program options
  po::options_description desc("Usage:\n  qi masterAddress [options]\nOptions");
  desc.add_options()
      ("help", "Print this help.")
      ("master-address",
       po::value<std::string>()->default_value(std::string("127.0.0.1:5555")),
       "The master address")
      ("gateway-address",
       po::value<std::string>()->default_value(std::string("127.0.0.1:12345")),
       "The gateway address");

  // allow master address to be specified as the first arg
  po::positional_options_description pos;
  pos.add("master-address", 1);

  // parse and store
  po::variables_map vm;
  try
  {
    po::store(po::command_line_parser(argc, argv).
              options(desc).positional(pos).run(), vm);
    po::notify(vm);

    if (vm.count("help"))
    {
      std::cout << desc << "\n";
      return 0;
    }

    if (vm.count("master-address") == 1 &&
        vm.count("gateway-address") == 1)
    {
      std::string masteraddr = vm["master-address"].as<std::string>();
      call(masteraddr);

      std::string gatewayaddr = vm["gateway-address"].as<std::string>();
      call(gatewayaddr);
    }
    else
    {
      std::cout << desc << "\n";
    }
  } catch (const boost::program_options::error&) {
    std::cout << desc << "\n";
  }

  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "version.h"

#include <stdlib.h>

#include "util.h"

const char* kNinjaVersion = "1.7.0.git";

void ParseVersion(const string& version, int* major, int* minor) {
  size_t end = version.find('.');
  *major = atoi(version.substr(0, end).c_str());
  *minor = 0;
  if (end != string::npos) {
    size_t start = end + 1;
    end = version.find('.', start);
    *minor = atoi(version.substr(start, end).c_str());
  }
}

void CheckNinjaVersion(const string& version) {
  int bin_major, bin_minor;
  ParseVersion(kNinjaVersion, &bin_major, &bin_minor);
  int file_major, file_minor;
  ParseVersion(version, &file_major, &file_minor);

  if (bin_major > file_major) {
    Warning("ninja executable version (%s) greater than build file "
            "ninja_required_version (%s); versions may be incompatible.",
            kNinjaVersion, version.c_str());
    return;
  }

  if ((bin_major == file_major && bin_minor < file_minor) ||
      bin_major < file_major) {
    Fatal("ninja version (%s) incompatible with build file "
          "ninja_required_version version (%s).",
          kNinjaVersion, version.c_str());
  }
}
<commit_msg>mark this 1.7.1.git<commit_after>// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "version.h"

#include <stdlib.h>

#include "util.h"

const char* kNinjaVersion = "1.7.1.git";

void ParseVersion(const string& version, int* major, int* minor) {
  size_t end = version.find('.');
  *major = atoi(version.substr(0, end).c_str());
  *minor = 0;
  if (end != string::npos) {
    size_t start = end + 1;
    end = version.find('.', start);
    *minor = atoi(version.substr(start, end).c_str());
  }
}

void CheckNinjaVersion(const string& version) {
  int bin_major, bin_minor;
  ParseVersion(kNinjaVersion, &bin_major, &bin_minor);
  int file_major, file_minor;
  ParseVersion(version, &file_major, &file_minor);

  if (bin_major > file_major) {
    Warning("ninja executable version (%s) greater than build file "
            "ninja_required_version (%s); versions may be incompatible.",
            kNinjaVersion, version.c_str());
    return;
  }

  if ((bin_major == file_major && bin_minor < file_minor) ||
      bin_major < file_major) {
    Fatal("ninja version (%s) incompatible with build file "
          "ninja_required_version version (%s).",
          kNinjaVersion, version.c_str());
  }
}
<|endoftext|>


<commit_before>/*******************************************************************//*
 * Several useful utility functions wrapped in a namespace
 *
 * @author      Brandon To
 * @version     1.0
 * @since       2015-02-18
 * @modified    2015-02-18
 *********************************************************************/
#include "Util.h"

#include <cstdio>
#include <libgen.h>

#ifdef _WIN32
    #include <windows.h>
#endif

#ifdef linux
    #include <unistd.h>
#endif

namespace Util
{
    std::string fix_path(std::string path)
    {
#ifdef _WIN32
        // Creates a path to the binary location
        char buf[256];
        GetModuleFileName(NULL, buf, sizeof(buf)-1);
        std::string binaryLocation = dirname(buf);
        return binaryLocation + "/../" + path;
#endif

#ifdef linux
        // Creates a path to the binary location
        char buf[256];
        readlink("/proc/self/exe", buf, sizeof(buf)-1);
        std::string binaryLocation = dirname(buf);
        return binaryLocation + "/" + path;
#endif
    }
}
<commit_msg>Fixed compilation of Util.cpp in Visual Studio<commit_after>/*******************************************************************//*
 * Several useful utility functions wrapped in a namespace
 *
 * @author      Brandon To
 * @version     1.0
 * @since       2015-02-18
 * @modified    2015-02-18
 *********************************************************************/
#include "Util.h"

#include <cstdio>

#ifdef _WIN32
    #include <windows.h>
#endif

#ifdef linux
    #include <unistd.h>
    #include <libgen.h>
#endif

#ifdef _WIN32
std::string dirname(const std::string& fname)
{
    size_t pos = fname.find_last_of("\\/");
    return (std::string::npos == pos)
        ? ""
        : fname.substr(0, pos);
}
#endif

namespace Util
{
    std::string fix_path(std::string path)
    {
#ifdef _WIN32
        // Creates a path to the binary location
        char buf[256];
        GetModuleFileName(NULL, buf, sizeof(buf)-1);
        std::string binaryLocation = dirname(buf);
        return binaryLocation + "/../" + path;
#endif

#ifdef linux
        // Creates a path to the binary location
        char buf[256];
        readlink("/proc/self/exe", buf, sizeof(buf)-1);
        std::string binaryLocation = dirname(buf);
        return binaryLocation + "/" + path;
#endif
    }
}
<|endoftext|>