<commit_before>#include "tidyup_actions/actionExecutorDetectObjects.h"
#include <pluginlib/class_list_macros.h>
#include <tidyup_msgs/RequestObjectsGraspability.h>
#include "tidyup_utils/planning_scene_interface.h"

PLUGINLIB_DECLARE_CLASS(tidyup_actions, action_executor_detect_objects,
        tidyup_actions::ActionExecutorDetectObjects,
        continual_planning_executive::ActionExecutorInterface)

namespace tidyup_actions
{
    void ActionExecutorDetectObjects::initialize(const std::deque<std::string> & arguments)
    {
        ActionExecutorService<tidyup_msgs::DetectGraspableObjects>::initialize(arguments);
        requestGraspability = false;
        string graspabilityServiceName = "/learned_grasping/request_objects_graspability";
        tidyLocationName = "table1";

        if (arguments.size() >= 3)
        {
            if (arguments[2] == "NULL")
            {
                requestGraspability = false;
            } else {
                graspabilityServiceName = arguments[2];
            }
        }
        if (arguments.size() >= 4)
        {
            tidyLocationName = arguments[3];
        }

        ROS_ASSERT(_nh);
        if(requestGraspability) {
            serviceClientGraspability = _nh->serviceClient<tidyup_msgs::RequestObjectsGraspability>(
                    graspabilityServiceName);
            if(!serviceClientGraspability) {
                ROS_FATAL("Could not initialize service for RequestObjectsGraspability.");
            }
        }
    }

    bool ActionExecutorDetectObjects::fillGoal(tidyup_msgs::DetectGraspableObjects::Request & goal,
            const DurativeAction & a, const SymbolicState & current)
    {
        if(!PlanningSceneInterface::instance()->resetPlanningScene())   // FIXME try anyways?
            ROS_ERROR("%s: PlanningScene reset failed.", __PRETTY_FUNCTION__);

        ROS_ASSERT(a.parameters.size() == 1);
        goal.static_object = findStaticObjectForLocation(a.parameters[0], current);
        return true;
    }

    void ActionExecutorDetectObjects::updateState(bool success,
            tidyup_msgs::DetectGraspableObjects::Response & response,
            const DurativeAction & a, SymbolicState & current)
    {
        ROS_INFO("DetectObjects returned result");
        if(success) {
            ROS_INFO("DetectObjects succeeded.");
            ROS_ASSERT(a.parameters.size() == 1);
            std::string location = a.parameters[0];
            current.setBooleanPredicate("searched", location, true);
            current.setBooleanPredicate("recent-detected-objects", location, true);

            std::vector<tidyup_msgs::GraspableObject>& objects = response.objects;
            if(requestGraspability && false) {
                ROS_INFO("Requesting graspability.");
                tidyup_msgs::RequestObjectsGraspability request;
                request.request.objects = objects;
                if(!serviceClientGraspability.call(request)) {
                    ROS_ERROR("Failed to call RequestObjectsGraspability service.");
                } else {
                    objects = request.response.objects;
                }
            }

            // find correct static object and set the "on" predicate
            string static_object = findStaticObjectForLocation(location, current);
            ROS_ASSERT(static_object != "");

            // remove objects form state, which were previously detected from this location
            Predicate p;
            p.name = "on";
            p.parameters.push_back("object");
            p.parameters.push_back(static_object);
            pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> objectRange =
                    current.getTypedObjects().equal_range("movable_object");
            for (SymbolicState::TypedObjectConstIterator objectIterator = objectRange.first;
                    objectIterator != objectRange.second; objectIterator++)
            {
                string object = objectIterator->second;
                p.parameters[0] = object;
                string detection_location;
                if (current.hasObjectFluent(p, &detection_location))
                {
                    if (location == detection_location)
                    {
                        current.removeObject(object, true);
                    }
                }
            }

            for(std::vector<tidyup_msgs::GraspableObject>::iterator it = objects.begin(); it != objects.end(); it++)
            {
                tidyup_msgs::GraspableObject & object = *it;
                current.addObject(object.name, "movable_object");
                if(object.pose.header.frame_id.empty()) {
                    ROS_ERROR("DetectGraspableObjects returned empty frame_id for object: %s", object.name.c_str());
                    object.pose.header.frame_id = "INVALID_FRAME_ID";
                }
                current.addObject(object.pose.header.frame_id, "frameid");
                current.addObject(object.name, "pose");
                current.setObjectFluent("frame-id", object.name, object.pose.header.frame_id);
                current.setNumericalFluent("x", object.name, object.pose.pose.position.x);
                current.setNumericalFluent("y", object.name, object.pose.pose.position.y);
                current.setNumericalFluent("z", object.name, object.pose.pose.position.z);
                current.setNumericalFluent("qx", object.name, object.pose.pose.orientation.x);
                current.setNumericalFluent("qy", object.name, object.pose.pose.orientation.y);
                current.setNumericalFluent("qz", object.name, object.pose.pose.orientation.z);
                current.setNumericalFluent("qw", object.name, object.pose.pose.orientation.w);
                current.setNumericalFluent("timestamp", object.name, object.pose.header.stamp.toSec());
                current.setBooleanPredicate("on", object.name + " " + static_object, true);
                //current.setObjectFluent("object-detected-from", object.name, location);
                // tidy-location: (tidy-location ?o ?s)
                current.setBooleanPredicate("tidy-location", object.name + " " + tidyLocationName, true);

                // add graspable predicates from current location
                if(requestGraspability || true)
                {
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " left_arm",
                           object.reachable_left_arm);
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " right_arm",
                           object.reachable_right_arm);
                }
                else
                {
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " left_arm", true);
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " right_arm", true);
                }
            }

            std::set<std::string> wipeGoalNames;
            for(std::vector<tidyup_msgs::WipeGoal>::iterator it = response.wipe_goals.begin(); it != response.wipe_goals.end(); it++) {
                tidyup_msgs::WipeGoal & wg = *it;
                wipeGoalNames.insert(wg.name);

                // add/update this wipe goal
                current.addObject(wg.name, "wipe_point");   // this should never hurt, even if it's in there
                if(wg.spot.header.frame_id.empty()) {
                    ROS_ERROR("DetectGraspableObjects returned empty frame_id for wipe goal: %s", wg.name.c_str());
                    wg.spot.header.frame_id = "INVALID_FRAME_ID";
                }
                current.addObject(wg.spot.header.frame_id, "frameid");
                current.setObjectFluent("frame-id", wg.name, wg.spot.header.frame_id);
                current.setNumericalFluent("x", wg.name, wg.spot.point.x);
                current.setNumericalFluent("y", wg.name, wg.spot.point.y);
                current.setNumericalFluent("z", wg.name, wg.spot.point.z);
                current.setNumericalFluent("timestamp", wg.name, wg.spot.header.stamp.toSec());
                // if not known, set initially false
                Predicate wipedPred;
                wipedPred.name = "wiped";
                wipedPred.parameters.push_back(wg.name);
                bool wiped;
                if(!current.hasBooleanPredicate(wipedPred, &wiped)) {   // only set if unknown
                    current.setBooleanPredicate("wiped", wg.name, false);
                }
                current.setBooleanPredicate("wipe-point-on", wg.name + " " + static_object, true);
            }

            // remove all the wipe goals at this static object that were not send in this detection
            // (i.e. that are not in wipeGoalNames)
            pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> wipePointRange =
                current.getTypedObjects().equal_range("wipe_point");
            std::set<std::string> nonMatchedWipePoints;
            for(SymbolicState::TypedObjectConstIterator objectIterator = wipePointRange.first;
                    objectIterator != wipePointRange.second; objectIterator++) {
                // first check if this object is a wipe-point-on static_object
                Predicate p;
                p.name = "wipe-point-on";
                string object = objectIterator->second;
                p.parameters.push_back(object);
                p.parameters.push_back(static_object);

                bool wpOn = false;
                if(!current.hasBooleanPredicate(p, &wpOn))
                    continue;
                if(!wpOn)
                    continue;

                // it is on static_object, next check if it was contained in this detection
                if(wipeGoalNames.find(object) == wipeGoalNames.end()) {
                    nonMatchedWipePoints.insert(object);
                }
            }
            for(std::set<std::string>::iterator it = nonMatchedWipePoints.begin(); it != nonMatchedWipePoints.end(); it++) {
                ROS_WARN("Removing non matched wipe point: %s.", it->c_str());
                current.removeObject(*it, false);    // FIXME: do not remove the predicates
                // this will remember that we wiped a spot, when we for some reason manage
                // to find it again
            }

            if(!PlanningSceneInterface::instance()->resetPlanningScene())   // FIXME try anyways?
              ROS_ERROR("%s: PlanningScene reset failed.", __PRETTY_FUNCTION__);
        }
    }

    std::string ActionExecutorDetectObjects::findStaticObjectForLocation(const std::string& location, const SymbolicState & current) const
    {
        Predicate p;
        string static_object;
        p.name = "static-object-at-location";
        p.parameters.push_back("object");
        p.parameters.push_back(location);
        pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> objectRange =
                current.getTypedObjects().equal_range("static_object");
        for (SymbolicState::TypedObjectConstIterator objectIterator = objectRange.first;
                objectIterator != objectRange.second; objectIterator++)
        {
            string object = objectIterator->second;
            p.parameters[0] = object;
            bool value = false;
            if (current.hasBooleanPredicate(p, &value))
            {
                if (value)
                {
                    static_object = object;
                    break;
                }
            }
        }
        return static_object;
    }

};

<commit_msg>fixed redetection in actionExecutorDetectObjects<commit_after>#include "tidyup_actions/actionExecutorDetectObjects.h"
#include <pluginlib/class_list_macros.h>
#include <tidyup_msgs/RequestObjectsGraspability.h>
#include "tidyup_utils/planning_scene_interface.h"

PLUGINLIB_DECLARE_CLASS(tidyup_actions, action_executor_detect_objects,
        tidyup_actions::ActionExecutorDetectObjects,
        continual_planning_executive::ActionExecutorInterface)

namespace tidyup_actions
{
    void ActionExecutorDetectObjects::initialize(const std::deque<std::string> & arguments)
    {
        ActionExecutorService<tidyup_msgs::DetectGraspableObjects>::initialize(arguments);
        requestGraspability = false;
        string graspabilityServiceName = "/learned_grasping/request_objects_graspability";
        tidyLocationName = "table1";

        if (arguments.size() >= 3)
        {
            if (arguments[2] == "NULL")
            {
                requestGraspability = false;
            } else {
                graspabilityServiceName = arguments[2];
            }
        }
        if (arguments.size() >= 4)
        {
            tidyLocationName = arguments[3];
        }

        ROS_ASSERT(_nh);
        if(requestGraspability) {
            serviceClientGraspability = _nh->serviceClient<tidyup_msgs::RequestObjectsGraspability>(
                    graspabilityServiceName);
            if(!serviceClientGraspability) {
                ROS_FATAL("Could not initialize service for RequestObjectsGraspability.");
            }
        }
    }

    bool ActionExecutorDetectObjects::fillGoal(tidyup_msgs::DetectGraspableObjects::Request & goal,
            const DurativeAction & a, const SymbolicState & current)
    {
        if(!PlanningSceneInterface::instance()->resetPlanningScene())   // FIXME try anyways?
            ROS_ERROR("%s: PlanningScene reset failed.", __PRETTY_FUNCTION__);

        ROS_ASSERT(a.parameters.size() == 1);
        goal.static_object = findStaticObjectForLocation(a.parameters[0], current);
        return true;
    }

    void ActionExecutorDetectObjects::updateState(bool success,
            tidyup_msgs::DetectGraspableObjects::Response & response,
            const DurativeAction & a, SymbolicState & current)
    {
        ROS_INFO("DetectObjects returned result");
        if(success) {
            ROS_INFO("DetectObjects succeeded.");
            ROS_ASSERT(a.parameters.size() == 1);
            std::string location = a.parameters[0];
            current.setBooleanPredicate("searched", location, true);
            current.setBooleanPredicate("recent-detected-objects", location, true);

            std::vector<tidyup_msgs::GraspableObject>& objects = response.objects;
            if(requestGraspability && false) {
                ROS_INFO("Requesting graspability.");
                tidyup_msgs::RequestObjectsGraspability request;
                request.request.objects = objects;
                if(!serviceClientGraspability.call(request)) {
                    ROS_ERROR("Failed to call RequestObjectsGraspability service.");
                } else {
                    objects = request.response.objects;
                }
            }

            // find correct static object and set the "on" predicate
            string static_object = findStaticObjectForLocation(location, current);
            ROS_ASSERT(static_object != "");

            // remove objects form state, which were previously detected from this location
            Predicate p;
            p.name = "on";
            p.parameters.push_back("object");
            p.parameters.push_back(static_object);
            pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> objectRange =
                    current.getTypedObjects().equal_range("movable_object");
            for (SymbolicState::TypedObjectConstIterator objectIterator = objectRange.first;
                    objectIterator != objectRange.second; objectIterator++)
            {
                string object = objectIterator->second;
                p.parameters[0] = object;
                bool onStatic = false;
                if(current.hasBooleanPredicate(p, &onStatic))
                {
                    if(onStatic) {
                        current.removeObject(object, true);
                    }
                }
            }

            for(std::vector<tidyup_msgs::GraspableObject>::iterator it = objects.begin(); it != objects.end(); it++)
            {
                tidyup_msgs::GraspableObject & object = *it;
                current.addObject(object.name, "movable_object");
                if(object.pose.header.frame_id.empty()) {
                    ROS_ERROR("DetectGraspableObjects returned empty frame_id for object: %s", object.name.c_str());
                    object.pose.header.frame_id = "INVALID_FRAME_ID";
                }
                current.addObject(object.pose.header.frame_id, "frameid");
                current.addObject(object.name, "pose");
                current.setObjectFluent("frame-id", object.name, object.pose.header.frame_id);
                current.setNumericalFluent("x", object.name, object.pose.pose.position.x);
                current.setNumericalFluent("y", object.name, object.pose.pose.position.y);
                current.setNumericalFluent("z", object.name, object.pose.pose.position.z);
                current.setNumericalFluent("qx", object.name, object.pose.pose.orientation.x);
                current.setNumericalFluent("qy", object.name, object.pose.pose.orientation.y);
                current.setNumericalFluent("qz", object.name, object.pose.pose.orientation.z);
                current.setNumericalFluent("qw", object.name, object.pose.pose.orientation.w);
                current.setNumericalFluent("timestamp", object.name, object.pose.header.stamp.toSec());
                current.setBooleanPredicate("on", object.name + " " + static_object, true);
                //current.setObjectFluent("object-detected-from", object.name, location);
                // tidy-location: (tidy-location ?o ?s)
                current.setBooleanPredicate("tidy-location", object.name + " " + tidyLocationName, true);

                // add graspable predicates from current location
                if(requestGraspability || true)
                {
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " left_arm",
                           object.reachable_left_arm);
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " right_arm",
                           object.reachable_right_arm);
                }
                else
                {
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " left_arm", true);
                    current.setBooleanPredicate("graspable-from", object.name + " " + location + " right_arm", true);
                }
            }

            std::set<std::string> wipeGoalNames;
            for(std::vector<tidyup_msgs::WipeGoal>::iterator it = response.wipe_goals.begin(); it != response.wipe_goals.end(); it++) {
                tidyup_msgs::WipeGoal & wg = *it;
                wipeGoalNames.insert(wg.name);

                // add/update this wipe goal
                current.addObject(wg.name, "wipe_point");   // this should never hurt, even if it's in there
                if(wg.spot.header.frame_id.empty()) {
                    ROS_ERROR("DetectGraspableObjects returned empty frame_id for wipe goal: %s", wg.name.c_str());
                    wg.spot.header.frame_id = "INVALID_FRAME_ID";
                }
                current.addObject(wg.spot.header.frame_id, "frameid");
                current.setObjectFluent("frame-id", wg.name, wg.spot.header.frame_id);
                current.setNumericalFluent("x", wg.name, wg.spot.point.x);
                current.setNumericalFluent("y", wg.name, wg.spot.point.y);
                current.setNumericalFluent("z", wg.name, wg.spot.point.z);
                current.setNumericalFluent("timestamp", wg.name, wg.spot.header.stamp.toSec());
                // if not known, set initially false
                Predicate wipedPred;
                wipedPred.name = "wiped";
                wipedPred.parameters.push_back(wg.name);
                bool wiped;
                if(!current.hasBooleanPredicate(wipedPred, &wiped)) {   // only set if unknown
                    current.setBooleanPredicate("wiped", wg.name, false);
                }
                current.setBooleanPredicate("wipe-point-on", wg.name + " " + static_object, true);
            }

            // remove all the wipe goals at this static object that were not send in this detection
            // (i.e. that are not in wipeGoalNames)
            pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> wipePointRange =
                current.getTypedObjects().equal_range("wipe_point");
            std::set<std::string> nonMatchedWipePoints;
            for(SymbolicState::TypedObjectConstIterator objectIterator = wipePointRange.first;
                    objectIterator != wipePointRange.second; objectIterator++) {
                // first check if this object is a wipe-point-on static_object
                Predicate p;
                p.name = "wipe-point-on";
                string object = objectIterator->second;
                p.parameters.push_back(object);
                p.parameters.push_back(static_object);

                bool wpOn = false;
                if(!current.hasBooleanPredicate(p, &wpOn))
                    continue;
                if(!wpOn)
                    continue;

                // it is on static_object, next check if it was contained in this detection
                if(wipeGoalNames.find(object) == wipeGoalNames.end()) {
                    nonMatchedWipePoints.insert(object);
                }
            }
            for(std::set<std::string>::iterator it = nonMatchedWipePoints.begin(); it != nonMatchedWipePoints.end(); it++) {
                ROS_WARN("Removing non matched wipe point: %s.", it->c_str());
                current.removeObject(*it, false);    // FIXME: do not remove the predicates
                // this will remember that we wiped a spot, when we for some reason manage
                // to find it again
            }

            if(!PlanningSceneInterface::instance()->resetPlanningScene())   // FIXME try anyways?
              ROS_ERROR("%s: PlanningScene reset failed.", __PRETTY_FUNCTION__);
        }
    }

    std::string ActionExecutorDetectObjects::findStaticObjectForLocation(const std::string& location, const SymbolicState & current) const
    {
        Predicate p;
        string static_object;
        p.name = "static-object-at-location";
        p.parameters.push_back("object");
        p.parameters.push_back(location);
        pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> objectRange =
                current.getTypedObjects().equal_range("static_object");
        for (SymbolicState::TypedObjectConstIterator objectIterator = objectRange.first;
                objectIterator != objectRange.second; objectIterator++)
        {
            string object = objectIterator->second;
            p.parameters[0] = object;
            bool value = false;
            if (current.hasBooleanPredicate(p, &value))
            {
                if (value)
                {
                    static_object = object;
                    break;
                }
            }
        }
        return static_object;
    }

};

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <boost/tokenizer.hpp> //Boost tokenizer
#include <unistd.h> // Fork()
#include <sys/types.h> // Wait()
#include <sys/wait.h> // Wait()
#include <vector>
#include <stdio.h> //Perror()
#include <errno.h> // Perror()
#include <algorithm>

using namespace std;
using namespace boost;

// Chose to write function comparing c-strings rather than copy to string then compare
// Used for checking exit command
bool cStringEqual(char* c1, char* c2)
{
	int i;
	for(i = 0; c1[i] != '\0' && c2[i] != '\0'; ++i)
	{
		if(c1[i] != c2[i])
		{
			return false;
		}
	}
	if(c1[i] != '\0' || c2[i] != '\0')
	{
		return false;
	}
	return true;
}

int main()
{
	while(true) //Shell runs until the exit command
	{
		cout << "$ "; // Prints command prompt
		string commandLine;
		getline(cin, commandLine);

		// Accounts for comments by removing parts that are comments
		// TODO: Account for escape character + comment (\#)
		if(commandLine.find(" #") != string::npos)
		{
			commandLine = commandLine.substr(commandLine.find(" #"));
		}

		// Finds locations of connectors; a && b, && has a location of 3
		vector<unsigned int> connectorLocs;
		unsigned int marker = 0; // Marks location to start find() from
		while(commandLine.find("&&", marker) != string::npos)//loc != string::npos)
		{
			connectorLocs.push_back(commandLine.find("&&", marker));
			marker = commandLine.find("&&", marker) + 2;//loc + 2; // Starts searching after "&&"
		}
		marker = 0;
		while(commandLine.find("||", marker) != string::npos)
		{
			connectorLocs.push_back(commandLine.find("||", marker));
			marker = commandLine.find("||", marker) + 2; // Starts searching after "||"
		}
		marker = 0;
		while(commandLine.find(";", marker) != string::npos)
		{
			connectorLocs.push_back(commandLine.find(";", marker));
			marker =  commandLine.find(";", marker)+ 1; // Starts searching after ";"
		}
		connectorLocs.push_back(0); // Will be sorted and put in beginning
		sort(connectorLocs.begin(), connectorLocs.end()); // Sorted to find each subcommand substring
		connectorLocs.push_back(commandLine.size()); // One past end index will act like connector

		// Runs through subcommands and runs each one
		// Works for connectors with nothing between them (tokenizer will have "" => syntax error, which is expected)
		// # of subcommands == # of connectors - 1 (including 0, one-past-end)
		for(unsigned int i = 0; i < connectorLocs.size() - 1; ++i)
		{
			int offset = 0;
			if(commandLine.at(connectorLocs.at(i)) == '&' || commandLine.at(connectorLocs.at(i)) == '|')
			{
				offset = 2;
			}
			else
			{
				if(commandLine.at(connectorLocs.at(i)) == ';')
				{
					offset = 1;
				}
			}

			//cout << commandLine.at(connectorLocs.at(i)) << endl; // DEBUGGING
			//cout << offset << endl; // DEBUGGING

			// For parsing line of commands; delimiter is whitespace, each token will be a command or an argument
			vector<char*> args;
			char_separator<char> sep(" ");
			string subcommand = commandLine.substr(connectorLocs.at(i) + offset, connectorLocs.at(i+1) - connectorLocs.at(i) - offset);
			//typedef tokenizer<char_separator<char>> tokenizer; // Used to use this
			//cout << "sub: " << subcommand << endl; // DEBUGGING
			tokenizer<char_separator<char>> tok(subcommand, sep);
			// First token is the command, other tokens are the arguments
			for(auto iter = tok.begin(); iter != tok.end(); ++iter)
			{
				// cout << "tok: " << *iter << endl; // DEBUGGING
				args.push_back(const_cast<char*> (iter->c_str()));
			}
			args.push_back(NULL); // NULL terminating at the end of vector/array

			char* exitCString = const_cast<char*> ("exit");

			//cout << cStringEqual(args.at(0), exitCString) << endl;
			if(cStringEqual(args.at(0), exitCString)) // if command is exit, exit shell
			{
				exit(0);
			}

			// Executes commands/takes care of errors
			int pid = fork();
			if(pid == -1) // If fork fails
			{
				perror("Fork error");
				exit(1);
			}
			else
			{
				if(pid == 0) // Child process
				{
					execvp(args.at(0), &args.at(0));
					// Following don't run if execvp succeeds
					perror("Command execution error");
					_exit(1);
				}
				else // Parent process
				{
					int status; // Status isn't used but might use in future?
					int waitVar = wait(&status);
					if(waitVar == -1) // If child process has error
					{
						perror("Child process error");
						// exits if next connector is && or one-past-end element
						// continues if next connector is ; or ||

					}
					else
					{
						int exitStatus = WEXITSTATUS(status); // Checks whether returns 0/1 when exiting
						if(exitStatus == 1) // If unsuccessful command
						{
							if(connectorLocs.at(i+1) < commandLine.size() &&
								commandLine.at(connectorLocs.at(i+1)) == '&')
							{
								//cout << commandLine.at(connectorLocs.at(i+1)) << endl; // DEBUGGING
								break;
							}
						}
						else
						{
							if(connectorLocs.at(i+1) < commandLine.size() &&
								commandLine.at(connectorLocs.at(i+1)) == '|')
							{
								//cout << commandLine.at(connectorLocs.at(i+1)) << endl; // DEBUGGING
								break;
							}
						}
					}
				}
			}
		}
	}
	return 0;
}
<commit_msg>Bugfixes<commit_after>#include <iostream>
#include <string>
#include <boost/tokenizer.hpp> //Boost tokenizer
#include <unistd.h> // Fork()
#include <sys/types.h> // Wait()
#include <sys/wait.h> // Wait()
#include <vector>
#include <stdio.h> //Perror()
#include <errno.h> // Perror()
#include <algorithm>

using namespace std;
using namespace boost;

// Chose to write function comparing c-strings rather than copy to string then compare
// Used for checking exit command
bool cStringEqual(char* c1, char* c2)
{
	int i;
	for(i = 0; c1[i] != '\0' && c2[i] != '\0'; ++i)
	{
		if(c1[i] != c2[i])
		{
			return false;
		}
	}
	if(c1[i] != '\0' || c2[i] != '\0')
	{
		return false;
	}
	return true;
}

int main()
{
	while(true) //Shell runs until the exit command
	{
		cout << "$ "; // Prints command prompt
		string commandLine;
		getline(cin, commandLine);

		// Accounts for comments by removing parts that are comments
		if(commandLine.find(" #") != string::npos)
		{
			commandLine = commandLine.substr(commandLine.find(" #"));
		}

		// Finds locations of connectors; a && b, && has a location of 3
		vector<unsigned int> connectorLocs;
		unsigned int marker = 0; // Marks location to start find() from
		while(commandLine.find("&&", marker) != string::npos)//loc != string::npos)
		{
			connectorLocs.push_back(commandLine.find("&&", marker));
			marker = commandLine.find("&&", marker) + 2;//loc + 2; // Starts searching after "&&"
		}
		marker = 0;
		while(commandLine.find("||", marker) != string::npos)
		{
			connectorLocs.push_back(commandLine.find("||", marker));
			marker = commandLine.find("||", marker) + 2; // Starts searching after "||"
		}
		marker = 0;
		while(commandLine.find(";", marker) != string::npos)
		{
			connectorLocs.push_back(commandLine.find(";", marker));
			marker =  commandLine.find(";", marker)+ 1; // Starts searching after ";"
		}
		connectorLocs.push_back(0); // Will be sorted and put in beginning
		sort(connectorLocs.begin(), connectorLocs.end()); // Sorted to find each subcommand substring
		connectorLocs.push_back(commandLine.size()); // One past end index will act like connector

		// Runs through subcommands and runs each one
		// Works for connectors with nothing between them (tokenizer will have "" => syntax error, which is expected)
		// # of subcommands == # of connectors - 1 (including 0, one-past-end)
		for(unsigned int i = 0; i < connectorLocs.size() - 1; ++i)
		{
			int offset = 0; // Tells how much offset for connectors (&&, ||, ;)
			if(commandLine.at(connectorLocs.at(i)) == '&' || commandLine.at(connectorLocs.at(i)) == '|')
			{
				offset = 2;
			}
			else
			{
				if(commandLine.at(connectorLocs.at(i)) == ';')
				{
					offset = 1;
				}
			}

			//cout << commandLine.at(connectorLocs.at(i)) << endl; // DEBUGGING
			//cout << offset << endl; // DEBUGGING

			// For parsing line of commands; delimiter is whitespace, each token will be a command or an argument
			vector<string> strArgs;
			char_separator<char> sep(" ");
			// FOLLOWING LINE WILL BREAK IF USED DIRECTLY IN TOKENIZER
			string subcommand = commandLine.substr(connectorLocs.at(i) + offset, connectorLocs.at(i+1) - connectorLocs.at(i) - offset);
			//typedef tokenizer<char_separator<char>> tokenizer; // Used to use this
			//cout << "sub: " << subcommand << endl; // DEBUGGING
			tokenizer<char_separator<char>> tok(subcommand, sep);
			// First token is the command, other tokens are the arguments
			for(auto iter = tok.begin(); iter != tok.end(); ++iter)
			{
				//cout << "tok: " << *iter << endl; // DEBUGGING
				strArgs.push_back(*iter);
			}

			// Copy strArgs to vector of c-strings
			// NEED TO DO IT THIS WAY OR THERE'S ISSUES WITH POINTERS
			vector<char*> args;
			for(auto str : strArgs)
			{
				args.push_back(const_cast<char*> (str.c_str()));
			}
			args.push_back(NULL); // NULL terminating at the end of vector/array

			char* exitCString = const_cast<char*> ("exit");

			//cout << cStringEqual(args.at(0), exitCString) << endl; // DEBUGGING
			if(cStringEqual(args.at(0), exitCString)) // if command is exit, exit shell
			{
				exit(0);
			}

			// Executes commands/takes care of errors
			int pid = fork();
			if(pid == -1) // If fork fails
			{
				perror("Fork error");
				exit(1);
			}
			else
			{
				if(pid == 0) // Child process
				{
					execvp(args.at(0), &(args[0]));
					// Following don't run if execvp succeeds
					perror("Command execution error");
					_exit(1);
				}
				else // Parent process
				{
					int status; // Status isn't used but might use in future?
					int waitVar = wait(&status);
					if(waitVar == -1) // If child process has error
					{
						perror("Child process error");
						// exits if next connector is && or one-past-end element
						// continues if next connector is ; or ||

					}
					else
					{
						int exitStatus = WEXITSTATUS(status); // Checks whether returns 0/1 when exiting
						if(exitStatus == 1) // If unsuccessful command
						{
							if(connectorLocs.at(i+1) < commandLine.size() &&
								commandLine.at(connectorLocs.at(i+1)) == '&')
							{
								//cout << commandLine.at(connectorLocs.at(i+1)) << endl; // DEBUGGING
								break;
							}
						}
						else
						{
							if(connectorLocs.at(i+1) < commandLine.size() &&
								commandLine.at(connectorLocs.at(i+1)) == '|')
							{
								//cout << commandLine.at(connectorLocs.at(i+1)) << endl; // DEBUGGING
								break;
							}
						}
					}
				}
			}
		}
	}
	return 0;
}
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#ifndef __MEDIA_CONFIG_HPP__
#define __MEDIA_CONFIG_HPP__

#include <gst/sdp/gstsdpmessage.h>
#include <glibmm.h>

#define DEFAULT_CONFIG_FILE "/etc/kurento/kurento.conf"

#define SERVER_GROUP "Server"
#define SDP_PATTERN_KEY "sdpPattern"

#define WEB_RTC_END_POINT_GROUP "WebRtcEndPoint"
#define WEB_RTC_END_POINT_STUN_SERVER_ADDRESS_KEY "stunServerAddress"
#define WEB_RTC_END_POINT_STUN_SERVER_PORT_KEY "stunServerPort"
#define WEB_RTC_END_POINT_TURN_URL_KEY "turnURL"
#define WEB_RTC_END_POINT_PEM_CERTIFICATE_KEY "pemCertificate"

#define STUN_SERVER_ADDRESS "77.72.174.167"
#define STUN_SERVER_PORT 0

#define HTTP_SERVICE_GROUP "HttpEPServer"
#define HTTP_SERVICE_ADDRESS "serverAddress"
#define HTTP_SERVICE_PORT "serverPort"
#define HTTP_SERVICE_ANNOUNCED_ADDRESS "announcedAddress"

#define HTTP_DEFAULT_PORT 9091

#define HTTP_EP_SERVER_SERVICE_PORT ((MEDIA_SERVER_SERVICE_PORT) + 1)

#endif /* __MEDIA_CONFIG_HPP__ */
<commit_msg>Fix default configuration file path<commit_after>/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#ifndef __MEDIA_CONFIG_HPP__
#define __MEDIA_CONFIG_HPP__

#include <gst/sdp/gstsdpmessage.h>
#include <glibmm.h>

#define DEFAULT_CONFIG_FILE "/etc/kurento-media-server/kurento-media-server.conf"

#define SERVER_GROUP "Server"
#define SDP_PATTERN_KEY "sdpPattern"

#define WEB_RTC_END_POINT_GROUP "WebRtcEndPoint"
#define WEB_RTC_END_POINT_STUN_SERVER_ADDRESS_KEY "stunServerAddress"
#define WEB_RTC_END_POINT_STUN_SERVER_PORT_KEY "stunServerPort"
#define WEB_RTC_END_POINT_TURN_URL_KEY "turnURL"
#define WEB_RTC_END_POINT_PEM_CERTIFICATE_KEY "pemCertificate"

#define STUN_SERVER_ADDRESS "77.72.174.167"
#define STUN_SERVER_PORT 0

#define HTTP_SERVICE_GROUP "HttpEPServer"
#define HTTP_SERVICE_ADDRESS "serverAddress"
#define HTTP_SERVICE_PORT "serverPort"
#define HTTP_SERVICE_ANNOUNCED_ADDRESS "announcedAddress"

#define HTTP_DEFAULT_PORT 9091

#define HTTP_EP_SERVER_SERVICE_PORT ((MEDIA_SERVER_SERVICE_PORT) + 1)

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


<commit_before>/*************************************************************************
 *
 *  $RCSfile: JoinExchange.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: oj $ $Date: 2002-08-19 07:28:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef DBAUI_JOINEXCHANGE_HXX
#define DBAUI_JOINEXCHANGE_HXX

#ifndef DBAUI_DBEXCHANGE_HXX
#include "dbexchange.hxx"
#endif
#ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
#include "TableWindowListBox.hxx"
#endif

#ifndef _TRANSFER_HXX
#include <svtools/transfer.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

namespace dbaui
{
    //==================================================================
    // OJoinExchObj :
    // Zusaetzliche Daten fuer das Erzeugen von Joins in der JoinShell
    //==================================================================

    typedef ::cppu::ImplHelper1< ::com::sun::star::lang::XUnoTunnel > OJoinExchObj_Base;
    class OJoinExchObj
                    :public TransferableHelper
                    ,public OJoinExchObj_Base
    {
        static String           m_sJoinFormat;
        sal_Bool                m_bFirstEntry;

    protected:
        OJoinExchangeData           m_jxdSourceDescription;
        IDragTransferableListener*  m_pDragListener;

        virtual ~OJoinExchObj();
    public:
        OJoinExchObj(const OJoinExchangeData& jxdSource,sal_Bool _bFirstEntry=sal_False);

        // XInterface
        virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL acquire(  ) throw();
        virtual void SAL_CALL release(  ) throw();

        // XUnoTunnel
        virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rIdentifier ) throw(::com::sun::star::uno::RuntimeException);

        void StartDrag( Window* pWindow, sal_Int8 nDragSourceActions, IDragTransferableListener* _pListener );

        static OJoinExchangeData    GetSourceDescription(const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& _rxObject);
        static sal_Bool             isFormatAvailable( const DataFlavorExVector& _rFormats ,SotFormatStringId _nSlotID=SOT_FORMATSTR_ID_SBA_JOIN);

    protected:
        virtual void                AddSupportedFormats();
        virtual sal_Bool            GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
        virtual void                DragFinished( sal_Int8 nDropAction );

        static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
    };
}
#endif // DBAUI_JOINEXCHANGE_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.476); FILE MERGED 2005/09/05 17:34:20 rt 1.5.476.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: JoinExchange.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:29:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_JOINEXCHANGE_HXX
#define DBAUI_JOINEXCHANGE_HXX

#ifndef DBAUI_DBEXCHANGE_HXX
#include "dbexchange.hxx"
#endif
#ifndef DBAUI_TABLEWINDOWLISTBOX_HXX
#include "TableWindowListBox.hxx"
#endif

#ifndef _TRANSFER_HXX
#include <svtools/transfer.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

namespace dbaui
{
    //==================================================================
    // OJoinExchObj :
    // Zusaetzliche Daten fuer das Erzeugen von Joins in der JoinShell
    //==================================================================

    typedef ::cppu::ImplHelper1< ::com::sun::star::lang::XUnoTunnel > OJoinExchObj_Base;
    class OJoinExchObj
                    :public TransferableHelper
                    ,public OJoinExchObj_Base
    {
        static String           m_sJoinFormat;
        sal_Bool                m_bFirstEntry;

    protected:
        OJoinExchangeData           m_jxdSourceDescription;
        IDragTransferableListener*  m_pDragListener;

        virtual ~OJoinExchObj();
    public:
        OJoinExchObj(const OJoinExchangeData& jxdSource,sal_Bool _bFirstEntry=sal_False);

        // XInterface
        virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL acquire(  ) throw();
        virtual void SAL_CALL release(  ) throw();

        // XUnoTunnel
        virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rIdentifier ) throw(::com::sun::star::uno::RuntimeException);

        void StartDrag( Window* pWindow, sal_Int8 nDragSourceActions, IDragTransferableListener* _pListener );

        static OJoinExchangeData    GetSourceDescription(const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& _rxObject);
        static sal_Bool             isFormatAvailable( const DataFlavorExVector& _rFormats ,SotFormatStringId _nSlotID=SOT_FORMATSTR_ID_SBA_JOIN);

    protected:
        virtual void                AddSupportedFormats();
        virtual sal_Bool            GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
        virtual void                DragFinished( sal_Int8 nDropAction );

        static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
    };
}
#endif // DBAUI_JOINEXCHANGE_HXX

<|endoftext|>


<commit_before>/**
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 <iostream>
#include <atscppapi/GlobalPlugin.h>
#include <atscppapi/TransactionPlugin.h>
#include <atscppapi/TransformationPlugin.h>
#include <atscppapi/PluginInit.h>

using namespace atscppapi;
using std::cerr;
using std::endl;
using std::string;

class PostBufferTransformationPlugin : public TransformationPlugin {
public:
  PostBufferTransformationPlugin(Transaction &transaction)
    : TransformationPlugin(transaction, REQUEST_TRANSFORMATION), transaction_(transaction) {
    buffer_.reserve(1024); // not required, this is an optimization to start the buffer at a slightly higher value.
  }

  void consume(const string &data) {
    buffer_.append(data);
  }

  void handleInputComplete() {
    produce(buffer_);
    setOutputComplete();
  }

  virtual ~PostBufferTransformationPlugin() { }

private:
  Transaction &transaction_;
  string buffer_;
};

class GlobalHookPlugin : public GlobalPlugin {
public:
  GlobalHookPlugin() {
    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
  }

  virtual void handleReadRequestHeadersPostRemap(Transaction &transaction) {
    cerr << "Read Request Headers Post Remap" << endl;
    cerr << "Path: " << transaction.getClientRequest().getUrl().getPath() << endl;
    cerr << "Method: " << HTTP_METHOD_STRINGS[transaction.getClientRequest().getMethod()] << endl;
    if (transaction.getClientRequest().getMethod() == HTTP_METHOD_POST) {
      transaction.addPlugin(new PostBufferTransformationPlugin(transaction));
    }

    transaction.resume();
  }
};

void TSPluginInit(int argc ATSCPPAPI_UNUSED, const char *argv[] ATSCPPAPI_UNUSED) {
  new GlobalHookPlugin();
}
<commit_msg>TS-2532 One more compiler warning fix, as per Geffons wishes<commit_after>/**
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 <iostream>
#include <atscppapi/GlobalPlugin.h>
#include <atscppapi/TransactionPlugin.h>
#include <atscppapi/TransformationPlugin.h>
#include <atscppapi/PluginInit.h>

using namespace atscppapi;
using std::cerr;
using std::endl;
using std::string;

class PostBufferTransformationPlugin : public TransformationPlugin {
public:
  PostBufferTransformationPlugin(Transaction &transaction)
    : TransformationPlugin(transaction, REQUEST_TRANSFORMATION), transaction_(transaction) {
    buffer_.reserve(1024); // not required, this is an optimization to start the buffer at a slightly higher value.
    (void)transaction_;
  }

  void consume(const string &data) {
    buffer_.append(data);
  }

  void handleInputComplete() {
    produce(buffer_);
    setOutputComplete();
  }

  virtual ~PostBufferTransformationPlugin() { }

private:
  Transaction &transaction_;
  string buffer_;
};

class GlobalHookPlugin : public GlobalPlugin {
public:
  GlobalHookPlugin() {
    registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP);
  }

  virtual void handleReadRequestHeadersPostRemap(Transaction &transaction) {
    cerr << "Read Request Headers Post Remap" << endl;
    cerr << "Path: " << transaction.getClientRequest().getUrl().getPath() << endl;
    cerr << "Method: " << HTTP_METHOD_STRINGS[transaction.getClientRequest().getMethod()] << endl;
    if (transaction.getClientRequest().getMethod() == HTTP_METHOD_POST) {
      transaction.addPlugin(new PostBufferTransformationPlugin(transaction));
    }

    transaction.resume();
  }
};

void TSPluginInit(int argc ATSCPPAPI_UNUSED, const char *argv[] ATSCPPAPI_UNUSED) {
  new GlobalHookPlugin();
}
<|endoftext|>


<commit_before>#include "../src/libircppclient.hpp"
#include <iostream>
using std::cout;    using std::endl;

int main(int argc, char *argv[])
{
    if (argc < 2) {
        cout << "[Error] at least an address argument is required" << endl;
        return 1;
    }

    irc::config conf;
    conf.address = argv[1];
    conf.port    = (argv[2] ? argv[2] : "6667");
    conf.nick    = "libircppbot";
    conf.user    = "libircppclient";
    conf.ssl     = false;

    conf.nick_pw   = "";
    conf.server_pw = "";

    try {
        irc::client client(conf);
        client.start();
    } catch (const std::exception &e) {
        cout << "Exception thrown: " << e.what() << endl;
    } catch (const boost::system::error_code &e) {
        cout << "Boost error: " << e.message() << endl;
    }
}
<commit_msg>Improved the simple client readability<commit_after>#include "../src/libircppclient.hpp"
#include <iostream>
using std::cout;    using std::endl;
using std::cerr;

int main(int argc, char *argv[])
{
    if (argc < 2) {
        cout << "[Error] at least an address argument is required" << endl;
        return 1;
    }

    irc::config conf;
    conf.address = argv[1];
    conf.port    = (argv[2] ? argv[2] : "6667");
    conf.nick    = "libircppbot";
    conf.user    = "libircppclient";
    conf.ssl     = false;

    conf.nick_pw   = "";
    conf.server_pw = "";

    try {
        irc::client client(conf);
        client.start();
    }

    catch (const std::exception &e) {
        cerr << "Panic! " << e.what() << endl;
        return -1;
    }

    catch (const boost::system::error_code &e) {
        cerr << "Boost error: " << e.message() << endl;
        return -1;
    }

    return 0;
}
<|endoftext|>


<commit_before>//----------------------------  sparse_matrix_iterator_09.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2004 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  sparse_matrix_iterator_09.cc  ---------------------------

// this test, extracted from dof_constraints_09 and
// sparse_matrix_iterator_09, used to fail with aborts

#include "../tests.h"
#include <lac/sparsity_pattern.h>
#include <lac/sparse_matrix.h>
#include <fstream>
#include <iostream>

void test ()
{
                                   // create a sparsity pattern with totally
                                   // empty lines (not even diagonals, since
                                   // not quadratic)
  SparsityPattern sparsity(2,3,1);
  sparsity.add (1,1);
  sparsity.compress ();

                                   // attach a sparse matrix to it
  SparseMatrix<double> A(sparsity);

                                   // and loop over the elements of it
  for (SparseMatrix<double>::const_iterator k=A.begin();
       k!=A.end(); ++k)
    deallog << k->row() << ' ' << k->column() << ' ' << k->value()
            << std::endl;
}

int main ()
{
  std::ofstream logfile("sparse_matrix_iterator_09.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  try
    {
      test ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Exception on processing: " << std::endl
		<< exc.what() << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Unknown exception!" << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      return 1;
    };
}
<commit_msg>.<commit_after>//----------------------------  sparse_matrix_iterator_09.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2004 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  sparse_matrix_iterator_09.cc  ---------------------------

// this test, extracted from dof_constraints_09 and
// sparse_matrix_iterator_09, used to fail with aborts

#include "../tests.h"
#include <lac/sparsity_pattern.h>
#include <lac/sparse_matrix.h>
#include <fstream>
#include <iostream>

void test ()
{
                                   // create a sparsity pattern with totally
                                   // empty lines (not even diagonals, since
                                   // not quadratic)
  SparsityPattern sparsity(4,5,1);
  sparsity.add (1,1);
  sparsity.add (3,1);
  sparsity.compress ();

                                   // attach a sparse matrix to it
  SparseMatrix<double> A(sparsity);

                                   // and loop over the elements of it
  for (SparseMatrix<double>::const_iterator k=A.begin();
       k!=A.end(); ++k)
    deallog << k->row() << ' ' << k->column() << ' ' << k->value()
            << std::endl;
}

int main ()
{
  std::ofstream logfile("sparse_matrix_iterator_09.output");
  deallog.attach(logfile);
  deallog.depth_console(0);

  try
    {
      test ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Exception on processing: " << std::endl
		<< exc.what() << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Unknown exception!" << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      return 1;
    };
}
<|endoftext|>


<commit_before>/*++
Copyright (c) 2014 Microsoft Corporation

Module Name:

    sat_mus.cpp

Abstract:

    Faster MUS extraction based on Belov et.al. HYB (Algorithm 3, 4)

Author:

    Nikolaj Bjorner (nbjorner) 2014-20-7

Notes:

--*/

#include "sat_solver.h"
#include "sat_mus.h"

namespace sat {

    mus::mus(solver& s):s(s) {}

    mus::~mus() {}

    void mus::reset() {
        m_core.reset();
        m_mus.reset();
    }

    void mus::set_core() {
        m_core.append(m_mus);
        s.m_core.reset();
        s.m_core.append(m_core);
        m_model.reset();
    }

    lbool mus::operator()() {
        flet<bool> _disable_min(s.m_config.m_minimize_core, false);
        TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
        IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
        reset();
        literal_vector& core = m_core;
        literal_vector& mus = m_mus;
        core.append(s.get_core());

        while (!core.empty()) {
            TRACE("sat",
                  tout << "core: " << core << "\n";
                  tout << "mus:  " << mus  << "\n";);

            if (s.m_cancel) {
                set_core();
                return l_undef;
            }
            literal lit = core.back();
            core.pop_back();
            unsigned sz = mus.size();
            mus.push_back(~lit); // TBD: measure
            mus.append(core);
            lbool is_sat = s.check(mus.size(), mus.c_ptr());
            mus.resize(sz);
            switch (is_sat) {
            case l_undef:
                core.push_back(lit);
                set_core();
                return l_undef;
            case l_true: {
                SASSERT(value_at(lit, s.get_model()) == l_false);
                mus.push_back(lit);
                if (core.empty()) {
                    break;
                }
                sz = core.size();
                core.append(mus);
                measure_mr();
                // rmr();
                core.resize(sz);
                break;
            }
            case l_false:
                literal_vector const& new_core = s.get_core();
                if (new_core.contains(~lit)) {
                    break;
                }
                core.reset();
                for (unsigned i = 0; i < new_core.size(); ++i) {
                    literal lit = new_core[i];
                    if (!mus.contains(lit)) {
                        core.push_back(lit);
                    }
                }
                break;
            }
        }
        TRACE("sat", tout << "new core: " << mus << "\n";);
        set_core();
<<<<<<< HEAD
        IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";);
=======
        IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << m_core << ")\n";);
>>>>>>> 180b0d4ec915c84b770bb609fae4e462118cde50
        return l_true;
    }

    void mus::measure_mr() {
        model const& m2 = s.get_model();
        if (!m_model.empty()) {
            unsigned n = 0;
            for (unsigned i = 0; i < m_model.size(); ++i) {
                if (m2[i] != m_model[i]) ++n;
            }
            std::cout << "model diff: " << n << " out of " << m_model.size() << "\n";
        }
        m_model.reset();
        m_model.append(m2);
    }

    //
    // TBD: eager model rotation allows rotating the same clause
    // several times with respect to different models.
    //
    void mus::rmr() {
        return;
#if 0
        model& model = s.m_model;
        literal lit = m_mus.back();
        literal assumption_lit;
        SASSERT(value_at(lit, model) == l_false);
        // literal is false in current model.
        unsigned sz = m_toswap.size();
        find_swappable(lit);
        unsigned sz1 = m_toswap.size();
        for (unsigned i = sz; i < sz1; ++i) {
            lit = m_toswap[i];
            SASSERT(value_at(lit, model) == l_false);
            model[lit.var()] = ~model[lit.var()];    // swap assignment
            if (has_single_unsat(assumption_lit) && !m_mus.contains(assumption_lit)) {
                m_mus.push_back(assumption_lit);
                rmr();
            }
            model[lit.var()] = ~model[lit.var()];    // swap assignment back
        }
        m_toswap.resize(sz);
#endif
    }

    bool mus::has_single_unsat(literal& assumption_lit) {
        model const& model = s.get_model();
        return false;
    }

    //
    // lit is false in model.
    // find clauses where ~lit occurs, and all other literals
    // are false in model.
    // for each of the probed literals, determine if swapping the
    // assignment falsifies a hard clause, if not, add to m_toswap.
    //

    void mus::find_swappable(literal lit) {
        IF_VERBOSE(3, verbose_stream() << "(sat.mus swap " << lit << ")\n";);
        unsigned sz = m_toswap.size();
        literal lit2, lit3;
        model const& model = s.get_model();
        SASSERT(value_at(lit, model) == l_false);
        watch_list const& wlist = s.get_wlist(lit);
        watch_list::const_iterator it  = wlist.begin();
        watch_list::const_iterator end = wlist.end();
        unsigned num_cand = 0;
        for (; it != end && num_cand <= 1; ++it) {
            switch (it->get_kind()) {
            case watched::BINARY:
                if (it->is_learned()) {
                    break;
                }
                lit2 = it->get_literal();
                if (value_at(lit2, model) == l_true) {
                    break;
                }
                IF_VERBOSE(1, verbose_stream() << "(" << ~lit << " " << lit2 << ") ";);
                TRACE("sat", tout << ~lit << " " << lit2 << "\n";);
                ++num_cand;
                break;
            case watched::TERNARY:
                lit2 = it->get_literal1();
                lit3 = it->get_literal2();
                if (value_at(lit2, model) == l_true) {
                    break;
                }
                if (value_at(lit3, model) == l_true) {
                    break;
                }

                IF_VERBOSE(1, verbose_stream() << "(" << ~lit << " " << lit2 << " " << lit3 << ") ";);
                ++num_cand;
                break;
            case watched::CLAUSE: {
                clause_offset cls_off = it->get_clause_offset();
                clause& c = *(s.m_cls_allocator.get_clause(cls_off));
                if (c.is_learned()) {
                    break;
                }
                ++num_cand;
                IF_VERBOSE(1, verbose_stream() << c << " ";);
                TRACE("sat", tout << c << "\n";);
                break;
            }
            case watched::EXT_CONSTRAINT:
                TRACE("sat", tout << "external constraint - should avoid rmr\n";);
                return;
            }
        }
        if (num_cand > 1) {
            m_toswap.resize(sz);
        }
        else {
            IF_VERBOSE(1, verbose_stream() << "wlist size: " << num_cand << " " << m_core.size() << "\n";);
        }

    }

}

<commit_msg>local updates<commit_after>/*++
Copyright (c) 2014 Microsoft Corporation

Module Name:

    sat_mus.cpp

Abstract:

    Faster MUS extraction based on Belov et.al. HYB (Algorithm 3, 4)

Author:

    Nikolaj Bjorner (nbjorner) 2014-20-7

Notes:

--*/

#include "sat_solver.h"
#include "sat_mus.h"

namespace sat {

    mus::mus(solver& s):s(s) {}

    mus::~mus() {}

    void mus::reset() {
        m_core.reset();
        m_mus.reset();
    }

    void mus::set_core() {
        m_core.append(m_mus);
        s.m_core.reset();
        s.m_core.append(m_core);
        m_model.reset();
    }

    lbool mus::operator()() {
        flet<bool> _disable_min(s.m_config.m_minimize_core, false);
        TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
        IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
        reset();
        literal_vector& core = m_core;
        literal_vector& mus = m_mus;
        core.append(s.get_core());

        while (!core.empty()) {
            TRACE("sat",
                  tout << "core: " << core << "\n";
                  tout << "mus:  " << mus  << "\n";);

            if (s.m_cancel) {
                set_core();
                return l_undef;
            }
            literal lit = core.back();
            core.pop_back();
            unsigned sz = mus.size();
            mus.push_back(~lit); // TBD: measure
            mus.append(core);
            lbool is_sat = s.check(mus.size(), mus.c_ptr());
            mus.resize(sz);
            switch (is_sat) {
            case l_undef:
                core.push_back(lit);
                set_core();
                return l_undef;
            case l_true: {
                SASSERT(value_at(lit, s.get_model()) == l_false);
                mus.push_back(lit);
                if (core.empty()) {
                    break;
                }
                sz = core.size();
                core.append(mus);
                measure_mr();
                // rmr();
                core.resize(sz);
                break;
            }
            case l_false:
                literal_vector const& new_core = s.get_core();
                if (new_core.contains(~lit)) {
                    break;
                }
                core.reset();
                for (unsigned i = 0; i < new_core.size(); ++i) {
                    literal lit = new_core[i];
                    if (!mus.contains(lit)) {
                        core.push_back(lit);
                    }
                }
                break;
            }
        }
        TRACE("sat", tout << "new core: " << mus << "\n";);
        set_core();
        IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";);
        return l_true;
    }

    void mus::measure_mr() {
        model const& m2 = s.get_model();
        if (!m_model.empty()) {
            unsigned n = 0;
            for (unsigned i = 0; i < m_model.size(); ++i) {
                if (m2[i] != m_model[i]) ++n;
            }
            std::cout << "model diff: " << n << " out of " << m_model.size() << "\n";
        }
        m_model.reset();
        m_model.append(m2);
    }

    //
    // TBD: eager model rotation allows rotating the same clause
    // several times with respect to different models.
    //
    void mus::rmr() {
        return;
#if 0
        model& model = s.m_model;
        literal lit = m_mus.back();
        literal assumption_lit;
        SASSERT(value_at(lit, model) == l_false);
        // literal is false in current model.
        unsigned sz = m_toswap.size();
        find_swappable(lit);
        unsigned sz1 = m_toswap.size();
        for (unsigned i = sz; i < sz1; ++i) {
            lit = m_toswap[i];
            SASSERT(value_at(lit, model) == l_false);
            model[lit.var()] = ~model[lit.var()];    // swap assignment
            if (has_single_unsat(assumption_lit) && !m_mus.contains(assumption_lit)) {
                m_mus.push_back(assumption_lit);
                rmr();
            }
            model[lit.var()] = ~model[lit.var()];    // swap assignment back
        }
        m_toswap.resize(sz);
#endif
    }

    bool mus::has_single_unsat(literal& assumption_lit) {
        model const& model = s.get_model();
        return false;
    }

    //
    // lit is false in model.
    // find clauses where ~lit occurs, and all other literals
    // are false in model.
    // for each of the probed literals, determine if swapping the
    // assignment falsifies a hard clause, if not, add to m_toswap.
    //

    void mus::find_swappable(literal lit) {
        IF_VERBOSE(3, verbose_stream() << "(sat.mus swap " << lit << ")\n";);
        unsigned sz = m_toswap.size();
        literal lit2, lit3;
        model const& model = s.get_model();
        SASSERT(value_at(lit, model) == l_false);
        watch_list const& wlist = s.get_wlist(lit);
        watch_list::const_iterator it  = wlist.begin();
        watch_list::const_iterator end = wlist.end();
        unsigned num_cand = 0;
        for (; it != end && num_cand <= 1; ++it) {
            switch (it->get_kind()) {
            case watched::BINARY:
                if (it->is_learned()) {
                    break;
                }
                lit2 = it->get_literal();
                if (value_at(lit2, model) == l_true) {
                    break;
                }
                IF_VERBOSE(1, verbose_stream() << "(" << ~lit << " " << lit2 << ") ";);
                TRACE("sat", tout << ~lit << " " << lit2 << "\n";);
                ++num_cand;
                break;
            case watched::TERNARY:
                lit2 = it->get_literal1();
                lit3 = it->get_literal2();
                if (value_at(lit2, model) == l_true) {
                    break;
                }
                if (value_at(lit3, model) == l_true) {
                    break;
                }

                IF_VERBOSE(1, verbose_stream() << "(" << ~lit << " " << lit2 << " " << lit3 << ") ";);
                ++num_cand;
                break;
            case watched::CLAUSE: {
                clause_offset cls_off = it->get_clause_offset();
                clause& c = *(s.m_cls_allocator.get_clause(cls_off));
                if (c.is_learned()) {
                    break;
                }
                ++num_cand;
                IF_VERBOSE(1, verbose_stream() << c << " ";);
                TRACE("sat", tout << c << "\n";);
                break;
            }
            case watched::EXT_CONSTRAINT:
                TRACE("sat", tout << "external constraint - should avoid rmr\n";);
                return;
            }
        }
        if (num_cand > 1) {
            m_toswap.resize(sz);
        }
        else {
            IF_VERBOSE(1, verbose_stream() << "wlist size: " << num_cand << " " << m_core.size() << "\n";);
        }

    }

}

<|endoftext|>


<commit_before>/*
 * Written by Nitin Kumar Maharana
 * nitin.maharana@gmail.com
 */

//Without using HashMap. O(nlogn) Solution.

struct number{
    int element;
    int index;
};

bool ascending(struct number n1, struct number n2)
{
    return (n1.element < n2.element);
}

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        struct number input[nums.size()];

        for(int i = 0; i < nums.size(); i++)
        {
            input[i].element = nums[i];
            input[i].index = i;
        }

        sort(input, input+nums.size(), ascending);

        int l, r;

        l = 0;
        r = nums.size()-1;

        while(1)
        {
            if(target == (input[l].element+input[r].element))
                break;

            if(target < (input[l].element+input[r].element))
                r--;
            else
                l++;
        }

        vector<int> result(2);

        l = input[l].index + 1;
        r = input[r].index + 1;

        if(l < r)
        {
            result[0] = l;
            result[1] = r;
        }
        else
        {
            result[0] = r;
            result[1] = l;
        }

        return result;
    }
};

//Without using HashMap. O(nlogn) Solution. According to latest modification of question.
class Solution {
    static bool ascending(pair<int, int>& n1, pair<int, int>& n2)
    {
        return (n1.first < n2.first);
    }
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<pair<int, int>> memory;

        for(int i = 0; i < nums.size(); i++)
            memory.push_back(make_pair(nums[i], i));

        sort(memory.begin(), memory.end(), ascending);

        int l, r;
        vector<int> result;

        l = 0;
        r = nums.size()-1;

        while(l < r)
        {
            if((memory[l].first + memory[r].first) == target)
            {
                result.push_back(memory[l].second);
                result.push_back(memory[r].second);
                return result;
            }

            if((memory[l].first + memory[r].first) > target)
                r--;
            else
                l++;
        }

        return result;
    }
};<commit_msg>1. Two Sum - Using HashMap.<commit_after>/*
 * Written by Nitin Kumar Maharana
 * nitin.maharana@gmail.com
 */

//Without using HashMap. O(nlogn) Solution.

struct number{
    int element;
    int index;
};

bool ascending(struct number n1, struct number n2)
{
    return (n1.element < n2.element);
}

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        struct number input[nums.size()];

        for(int i = 0; i < nums.size(); i++)
        {
            input[i].element = nums[i];
            input[i].index = i;
        }

        sort(input, input+nums.size(), ascending);

        int l, r;

        l = 0;
        r = nums.size()-1;

        while(1)
        {
            if(target == (input[l].element+input[r].element))
                break;

            if(target < (input[l].element+input[r].element))
                r--;
            else
                l++;
        }

        vector<int> result(2);

        l = input[l].index + 1;
        r = input[r].index + 1;

        if(l < r)
        {
            result[0] = l;
            result[1] = r;
        }
        else
        {
            result[0] = r;
            result[1] = l;
        }

        return result;
    }
};

//Without using HashMap. O(nlogn) Solution. According to latest modification of question.
class Solution {
    static bool ascending(pair<int, int>& n1, pair<int, int>& n2)
    {
        return (n1.first < n2.first);
    }
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<pair<int, int>> memory;

        for(int i = 0; i < nums.size(); i++)
            memory.push_back(make_pair(nums[i], i));

        sort(memory.begin(), memory.end(), ascending);

        int l, r;
        vector<int> result;

        l = 0;
        r = nums.size()-1;

        while(l < r)
        {
            if((memory[l].first + memory[r].first) == target)
            {
                result.push_back(memory[l].second);
                result.push_back(memory[r].second);
                return result;
            }

            if((memory[l].first + memory[r].first) > target)
                r--;
            else
                l++;
        }

        memory.clear();

        return result;
    }
};

//Using HashMap. Time : O(n), Space : O(n).
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> memory;
        vector<int> result;

        for(int i = 0; i < nums.size(); i++)
        {
            if(memory.find(target-nums[i]) != memory.end())
            {
                result.push_back(memory[target-nums[i]]);
                result.push_back(i);
                return result;
            }

            memory[nums[i]] = i;
        }

        memory.clear();
        return result;
    }
};<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed in accordance with the terms specified in
 *  the LICENSE file found in the root directory of this source tree.
 */

#include <poll.h>

#include <osquery/events.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/logger.h>
#include <osquery/registry_factory.h>

#include "osquery/events/linux/udev.h"

namespace osquery {

static const int kUdevMLatency = 200;

REGISTER(UdevEventPublisher, "event_publisher", "udev");

Status UdevEventPublisher::setUp() {
  // The Setup and Teardown workflows should be protected against races.
  // Just in case let's protect the publisher's resources.
  WriteLock lock(mutex_);

  // Create the udev object.
  handle_ = udev_new();
  if (handle_ == nullptr) {
    return Status(1, "Could not create udev object.");
  }

  // Set up the udev monitor before scanning/polling.
  monitor_ = udev_monitor_new_from_netlink(handle_, "udev");
  if (monitor_ == nullptr) {
    udev_unref(handle_);
    handle_ = nullptr;
    return Status(1, "Could not create udev monitor.");
  }

  udev_monitor_enable_receiving(monitor_);
  return Status::success();
}

void UdevEventPublisher::tearDown() {
  WriteLock lock(mutex_);
  if (monitor_ != nullptr) {
    udev_monitor_unref(monitor_);
    monitor_ = nullptr;
  }

  if (handle_ != nullptr) {
    udev_unref(handle_);
    handle_ = nullptr;
  }
}

Status UdevEventPublisher::run() {
  {
    WriteLock lock(mutex_);
    if (monitor_ == nullptr) {
      return Status(1);
    }
    int fd = udev_monitor_get_fd(monitor_);
    if (fd < 0) {
      LOG(ERROR) << "Could not get udev monitor fd";
      return Status::failure("udev monitor failed");
    }

    struct pollfd fds[1];
    fds[0].fd = fd;
    fds[0].events = POLLIN;

    int selector = ::poll(fds, 1, 1000);
    if (selector == -1 && errno != EINTR && errno != EAGAIN) {
      LOG(ERROR) << "Could not read udev monitor";
      return Status(1, "udev monitor failed.");
    }

    if (selector == 0 || !(fds[0].revents & POLLIN)) {
      // Read timeout.
      return Status::success();
    }

    struct udev_device* device = udev_monitor_receive_device(monitor_);
    if (device == nullptr) {
      LOG(ERROR) << "udev monitor returned invalid device";
      return Status(1, "udev monitor failed.");
    }

    auto ec = createEventContextFrom(device);
    fire(ec);

    udev_device_unref(device);
  }

  pause(std::chrono::milliseconds(kUdevMLatency));
  return Status::success();
}

std::string UdevEventPublisher::getValue(struct udev_device* device,
                                         const std::string& property) {
  auto value = udev_device_get_property_value(device, property.c_str());
  if (value != nullptr) {
    return std::string(value);
  }
  return "";
}

std::string UdevEventPublisher::getAttr(struct udev_device* device,
                                        const std::string& attr) {
  auto value = udev_device_get_sysattr_value(device, attr.c_str());
  if (value != nullptr) {
    return std::string(value);
  }
  return "";
}

UdevEventContextRef UdevEventPublisher::createEventContextFrom(
    struct udev_device* device) {
  auto ec = createEventContext();
  ec->device = device;
  // Map the action string to the eventing enum.
  ec->action = UDEV_EVENT_ACTION_UNKNOWN;
  ec->action_string = std::string(udev_device_get_action(device));
  if (ec->action_string == "add") {
    ec->action = UDEV_EVENT_ACTION_ADD;
  } else if (ec->action_string == "remove") {
    ec->action = UDEV_EVENT_ACTION_REMOVE;
  } else if (ec->action_string == "change") {
    ec->action = UDEV_EVENT_ACTION_CHANGE;
  }

  // Set the subscription-aware variables for the event.
  auto value = udev_device_get_subsystem(device);
  if (value != nullptr) {
    ec->subsystem = std::string(value);
  }

  value = udev_device_get_devnode(device);
  if (value != nullptr) {
    ec->devnode = std::string(value);
  }

  value = udev_device_get_devtype(device);
  if (value != nullptr) {
    ec->devtype = std::string(value);
  }

  value = udev_device_get_driver(device);
  if (value != nullptr) {
    ec->driver = std::string(value);
  }

  return ec;
}

bool UdevEventPublisher::shouldFire(const UdevSubscriptionContextRef& sc,
                                    const UdevEventContextRef& ec) const {
  if (sc->action != UDEV_EVENT_ACTION_ALL) {
    if (sc->action != ec->action) {
      return false;
    }
  }

  if (sc->subsystem.length() != 0 && sc->subsystem != ec->subsystem) {
    return false;
  } else if (sc->devnode.length() != 0 && sc->devnode != ec->devnode) {
    return false;
  } else if (sc->devtype.length() != 0 && sc->devtype != ec->devtype) {
    return false;
  } else if (sc->driver.length() != 0 && sc->driver != ec->driver) {
    return false;
  }

  return true;
}
} // namespace osquery
<commit_msg>udev: Log errno for udev ERROR messages (#6186)<commit_after>/**
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed in accordance with the terms specified in
 *  the LICENSE file found in the root directory of this source tree.
 */

#include <poll.h>

#include <osquery/events.h>
#include <osquery/filesystem/filesystem.h>
#include <osquery/logger.h>
#include <osquery/registry_factory.h>

#include "osquery/events/linux/udev.h"

namespace osquery {

static const int kUdevMLatency = 200;

REGISTER(UdevEventPublisher, "event_publisher", "udev");

Status UdevEventPublisher::setUp() {
  // The Setup and Teardown workflows should be protected against races.
  // Just in case let's protect the publisher's resources.
  WriteLock lock(mutex_);

  // Create the udev object.
  handle_ = udev_new();
  if (handle_ == nullptr) {
    return Status::failure("Could not create udev object");
  }

  // Set up the udev monitor before scanning/polling.
  monitor_ = udev_monitor_new_from_netlink(handle_, "udev");
  if (monitor_ == nullptr) {
    udev_unref(handle_);
    handle_ = nullptr;
    return Status::failure("Could not create udev monitor");
  }

  udev_monitor_enable_receiving(monitor_);
  return Status::success();
}

void UdevEventPublisher::tearDown() {
  WriteLock lock(mutex_);
  if (monitor_ != nullptr) {
    udev_monitor_unref(monitor_);
    monitor_ = nullptr;
  }

  if (handle_ != nullptr) {
    udev_unref(handle_);
    handle_ = nullptr;
  }
}

Status UdevEventPublisher::run() {
  {
    WriteLock lock(mutex_);
    if (monitor_ == nullptr) {
      return Status::failure("udev monitor not set up");
    }
    int fd = udev_monitor_get_fd(monitor_);
    if (fd < 0) {
      LOG(ERROR) << "Could not get udev monitor fd: " << std::strerror(-fd);
      return Status::failure("udev monitor failed");
    }

    struct pollfd fds[1];
    fds[0].fd = fd;
    fds[0].events = POLLIN;

    int selector = ::poll(fds, 1, 1000);
    if (selector == -1 && errno != EINTR && errno != EAGAIN) {
      LOG(ERROR) << "Could not read udev monitor: " << std::strerror(errno);
      return Status::failure("udev monitor failed");
    }

    if (selector == 0 || !(fds[0].revents & POLLIN)) {
      // Read timeout.
      return Status::success();
    }

    struct udev_device* device = udev_monitor_receive_device(monitor_);
    if (device == nullptr) {
      LOG(ERROR) << "udev monitor returned invalid device: "
                 << std::strerror(errno);
      return Status::failure("udev monitor failed");
    }

    auto ec = createEventContextFrom(device);
    fire(ec);

    udev_device_unref(device);
  }

  pause(std::chrono::milliseconds(kUdevMLatency));
  return Status::success();
}

std::string UdevEventPublisher::getValue(struct udev_device* device,
                                         const std::string& property) {
  auto value = udev_device_get_property_value(device, property.c_str());
  if (value != nullptr) {
    return std::string(value);
  }
  return "";
}

std::string UdevEventPublisher::getAttr(struct udev_device* device,
                                        const std::string& attr) {
  auto value = udev_device_get_sysattr_value(device, attr.c_str());
  if (value != nullptr) {
    return std::string(value);
  }
  return "";
}

UdevEventContextRef UdevEventPublisher::createEventContextFrom(
    struct udev_device* device) {
  auto ec = createEventContext();
  ec->device = device;
  // Map the action string to the eventing enum.
  ec->action = UDEV_EVENT_ACTION_UNKNOWN;
  ec->action_string = std::string(udev_device_get_action(device));
  if (ec->action_string == "add") {
    ec->action = UDEV_EVENT_ACTION_ADD;
  } else if (ec->action_string == "remove") {
    ec->action = UDEV_EVENT_ACTION_REMOVE;
  } else if (ec->action_string == "change") {
    ec->action = UDEV_EVENT_ACTION_CHANGE;
  }

  // Set the subscription-aware variables for the event.
  auto value = udev_device_get_subsystem(device);
  if (value != nullptr) {
    ec->subsystem = std::string(value);
  }

  value = udev_device_get_devnode(device);
  if (value != nullptr) {
    ec->devnode = std::string(value);
  }

  value = udev_device_get_devtype(device);
  if (value != nullptr) {
    ec->devtype = std::string(value);
  }

  value = udev_device_get_driver(device);
  if (value != nullptr) {
    ec->driver = std::string(value);
  }

  return ec;
}

bool UdevEventPublisher::shouldFire(const UdevSubscriptionContextRef& sc,
                                    const UdevEventContextRef& ec) const {
  if (sc->action != UDEV_EVENT_ACTION_ALL) {
    if (sc->action != ec->action) {
      return false;
    }
  }

  if (sc->subsystem.length() != 0 && sc->subsystem != ec->subsystem) {
    return false;
  } else if (sc->devnode.length() != 0 && sc->devnode != ec->devnode) {
    return false;
  } else if (sc->devtype.length() != 0 && sc->devtype != ec->devtype) {
    return false;
  } else if (sc->driver.length() != 0 && sc->driver != ec->driver) {
    return false;
  }

  return true;
}
} // namespace osquery
<|endoftext|>