Exemple #1
0
void daemon_pipe::exec()
{
    CHECK(!m_specs.empty(), "no procs to execute");

    SignalBlocker signals;

    // LockFile will be unlocked on destruction; don't do this until
    // after the ProcHarvester is destroyed
    LockFile lock;

    // ProcHarvester will wait for all children on destruction. Since we want
    // all the FDs to get closed before that happens, this must be instantiated
    // before the FileMap.
    ProcHarvester harvester(&signals.m_sigset);

    // build a map of all the files we're going to need to open, and whether
    // we need to read or write from them
    FileMap files;
    for(std::vector<daemon_proc_spec_ptr>::iterator i = m_specs.begin(), end = m_specs.end(); i != end; ++i)
    {
        Proc &proc(harvester.addProc(*i));

        if((*i)->m_stdin)
            proc.m_stdin = files.get((*i)->m_stdin, true, false);
        if((*i)->m_stdout)
            proc.m_stdout = files.get((*i)->m_stdout, false, true);
        if((*i)->m_stderr)
            proc.m_stderr = files.get((*i)->m_stderr, false, true);
    }

    if(!m_lockFile.empty())
        lock.open(m_lockFile);

    std::vector<File *>::const_iterator file = files.m_files.begin(),
                                        end = files.m_files.end();
    for(; file != end; ++file)
        (*file)->open();

    int pgid = 0;
    for(std::vector<ProcPtr>::iterator i = harvester.m_procs.begin(), end = harvester.m_procs.end(); i != end; ++i)
    {
        Proc &proc = **i;
        proc.m_blockedSignals = &signals;
        proc.m_newPGID = pgid;
        int pid = proc.safe_fork_exec();
        if(pgid == 0)
            pgid = pid;
    }
}
Exemple #2
0
void daemon_pipe::try_error_write(const std::string &input)
{
    // keep signals blocked even inside our catch, so we can't
    // get SIGPIPE from the fwrite
    SignalBlocker signals;

    try
    {
        CHECK(m_specs.size() == 1, "specs must have 1 element");
        const daemon_proc_spec_ptr &procSpec = m_specs[0];

        {
            ProcHarvester harvester(&signals.m_sigset);

            file_spec_ptr pipe_spec(new file_spec);
            File file(pipe_spec);
            file.open();
            file.m_writeSide->setNonBlock();

            Proc &proc(harvester.addProc(procSpec));

            proc.m_stdin = &file;
            proc.m_blockedSignals = &signals;
            proc.m_newPGID = 0;
            proc.safe_fork_exec();
            file.m_readSide->reset();

            int ret = ::write(file.m_writeSide->get(), input.c_str(), input.length());
            CHECK(ret >= 0, "write failed: %m");

            file.m_writeSide->reset();
        }
        if(!(procSpec->finished() &&
                WIFEXITED(procSpec->getStatus()) &&
                WEXITSTATUS(procSpec->getStatus()) == 0))
            throw failure("proc failed");
    }
    catch(failure &f)
    {
        writeN(STDERR_FILENO, input.c_str(), input.length());
    }
}
bool ConsoleCommandParserResource::performParsing (const NetworkId & userId, const StringVector_t & argv, const String_t & originalCommand, String_t & result, const CommandParser * node)
{
	NOT_NULL (node);
	UNREF (userId);

	UNREF(originalCommand);

	//-----------------------------------------------------------------

	if (isCommand( argv [0], "activate"))
	{
		CachedNetworkId harvester(Unicode::wideToNarrow (argv[1]));

		ServerObject* harvesterObject = safe_cast<ServerObject*>(harvester.getObject());
		if (harvesterObject == NULL)
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);
			return true;
		}

		Controller *const controller = harvesterObject->getController();
		NOT_NULL(controller);
		controller->appendMessage(static_cast<int>(CM_activateInstallation),0.0f,new MessageQueueActivateInstallation(), GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_SERVER);
		result += getErrorMessage(argv[0], ERR_SUCCESS);
	}
		
	else if (isCommand( argv [0], "harvest"))
	{
		CachedNetworkId harvester(Unicode::wideToNarrow (argv[1]));

		ServerObject* harvesterObject = safe_cast<ServerObject*>(harvester.getObject());
		if (harvesterObject == NULL)
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);
			return true;
		}
			//TODO:  Make all of these into function calls instead of sending messages

		Controller *const controller = harvesterObject->getController();
		NOT_NULL(controller);
		controller->appendMessage(static_cast<int>(CM_installationHarvest),0.0f,new MessageQueueInstallationHarvest(), GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_SERVER); 
		result += getErrorMessage(argv[0], ERR_SUCCESS);
	}
	
	else if (isCommand( argv [0], "discardHopper"))
	{
		CachedNetworkId harvester(Unicode::wideToNarrow (argv[1]));
		
		HarvesterInstallationObject* harvesterObject = dynamic_cast<HarvesterInstallationObject*>(harvester.getObject());
		if (!harvesterObject)
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);
			return true;
		}
		harvesterObject->discardAllHopperContents ();

		result += getErrorMessage(argv[0], ERR_SUCCESS);
	}

	else if (isCommand( argv [0], "deactivate"))
	{
		CachedNetworkId harvester(Unicode::wideToNarrow (argv[1]));

		ServerObject* harvesterObject = safe_cast<ServerObject*>(harvester.getObject());
		if (harvesterObject == NULL)
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);
			return true;
		}
		Controller *const controller = harvesterObject->getController();
		NOT_NULL(controller);
		controller->appendMessage(static_cast<int>(CM_deactivateInstallation),0.0f,new MessageQueueDeactivateInstallation(), GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_SERVER);
		result += getErrorMessage(argv[0], ERR_SUCCESS);
	}

	else if (isCommand( argv [0], "tree"))
	{
		ServerUniverse & universe = ServerUniverse::getInstance();
		ResourceClassObject * root = 0;

		if (argv.size () > 1)
			root = universe.getResourceClassByName (Unicode::wideToNarrow (argv [1]));
		else
			root = universe.getResourceTreeRoot();

		if (root)
		{
			std::string temp;
			root->debugOutput(temp);
			result += Unicode::narrowToWide(temp);
			result += getErrorMessage(argv[0], ERR_SUCCESS);
		}
		else
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);
		
	}
	
	else if (isCommand( argv [0], "pools"))
	{
		PlanetObject* planet=ServerUniverse::getInstance().getPlanetByName(Unicode::wideToNarrow(argv[1]));
		if (planet)
		{
			std::string temp;
			planet->debugOutputPools(temp);
			result += Unicode::narrowToWide(temp);
			result += getErrorMessage(argv[0], ERR_SUCCESS);
		}
		else
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
		}
	}

	else if (isCommand( argv [0], "name"))
	{
		NetworkId resourceId(Unicode::wideToNarrow (argv[1]));
		ResourceTypeObject * const resource = ServerUniverse::getInstance().getResourceTypeById(resourceId);
		if (resource)
		{
			resource->setName(Unicode::wideToNarrow(argv[2]));
			result += getErrorMessage(argv[0], ERR_SUCCESS);
		}
		else
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
		}
	}

	else if (isCommand( argv [0], "viewcontainer"))
	{
		CachedNetworkId contId (Unicode::wideToNarrow (argv[1]));
		ResourceContainerObject* container=dynamic_cast<ResourceContainerObject*>(contId.getObject());
		if (container)
		{
			result += Unicode::narrowToWide(container->debugPrint()+'\n');
			result += getErrorMessage(argv[0], ERR_SUCCESS);
		}
		else
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
		}
	}

	else if (isCommand( argv [0], "addtocontainer"))
	{
		NetworkId const contId (Unicode::wideToNarrow (argv[1]));
		ResourceContainerObject * const container = dynamic_cast<ResourceContainerObject*>(NetworkIdManager::getObjectById(contId));
		std::string const & resourcePath = Unicode::wideToNarrow(argv[2]);
		ResourceTypeObject * const resType = ServerUniverse::getInstance().getResourceTypeByName(resourcePath);
		int const amount = strtol(Unicode::wideToNarrow (argv[3]).c_str (), NULL, 10);
		NetworkId const source(Unicode::wideToNarrow (argv[4]));
		
		if (container && resType)
		{
			if (container->addResource(CachedNetworkId(resType->getNetworkId()),amount, source))
				result += getErrorMessage(argv[0], ERR_SUCCESS);
			else
				result += getErrorMessage(argv[0], ERR_INVALID_CONTAINER_TRANSFER);
		}
		else
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
		}
	}

	else if (isCommand( argv [0], "fillcontainer"))
	{
		NetworkId contId (Unicode::wideToNarrow (argv[1]));
		ResourceContainerObject* container=dynamic_cast<ResourceContainerObject*>(NetworkIdManager::getObjectById(contId));
		if (container != NULL)
		{
			NetworkId sourceId;
			if (argv.size() >= 3)
				sourceId = NetworkId(Unicode::wideToNarrow (argv[2]));

			if (container->addResource(container->getResourceType(), 
				container->getMaxQuantity() - container->getQuantity(), 
				sourceId))
			{
				result += getErrorMessage(argv[0], ERR_SUCCESS);
			}
			else
				result += getErrorMessage(argv[0], ERR_INVALID_CONTAINER_TRANSFER);
		}
		else
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
	}

	else if (isCommand( argv [0], "recycle"))
	{
		NetworkId contId (Unicode::wideToNarrow (argv[1]));
		ResourceContainerObject* container=dynamic_cast<ResourceContainerObject*>(NetworkIdManager::getObjectById(contId));
		if (container != NULL)
		{
			if (container->debugRecycle())
					result += getErrorMessage(argv[0], ERR_SUCCESS);
			else
				result += Unicode::narrowToWide("The resource in the container could not be recycled.\n");
		}
		else
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
	}

	else if (isCommand( argv [0], "removefromcontainer"))
	{
		CachedNetworkId contId (Unicode::wideToNarrow (argv[1]));
		ResourceContainerObject* container=dynamic_cast<ResourceContainerObject*>(contId.getObject());
		ResourceTypeObject *resType=ServerUniverse::getInstance().getResourceTypeByName(Unicode::wideToNarrow(argv[2]));
		int amount=strtol(Unicode::wideToNarrow (argv[3]).c_str (), NULL, 10);
		
		if (container && resType)
		{
			NetworkId sourcePlayer(NetworkId::cms_invalid);

			typedef std::vector<std::pair<NetworkId, int> > SourcesType;
			SourcesType sources;
			if (container->removeResource(resType->getNetworkId(),amount,&sources))
			{
				char buffer[50];
				for(SourcesType::iterator i=sources.begin(); i!=sources.end(); ++i)
				{
					IGNORE_RETURN(snprintf(buffer,50,"%i",i->second));
					result += Unicode::narrowToWide(std::string("Removed ") + buffer + " resources harvested by player " + i->first.getValueString() + '\n');
				}
				result += getErrorMessage(argv[0], ERR_SUCCESS);
			}
			else
				result += getErrorMessage(argv[0], ERR_INVALID_CONTAINER_TRANSFER);
		}
		else
		{
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
		}
	}

	else if (isCommand( argv [0], "getSurveyList"))
	{
		std::string parentResourceClassName(Unicode::wideToNarrow(argv[1]));
		CachedNetworkId tool(Unicode::wideToNarrow (argv[2]));

		SurveySystem::getInstance().requestResourceListForSurvey(userId, tool, parentResourceClassName);
		result += getErrorMessage(argv[0], ERR_SUCCESS);
	}
	
	else if (isCommand( argv [0], "survey"))
	{
		const std::string       parentResourceClassName   (Unicode::wideToNarrow(argv[1]));
		const std::string       resourceTypeName          (Unicode::wideToNarrow(argv[2]));
		const int               surveyRange             = strtol(Unicode::wideToNarrow(argv[3]).c_str(),NULL,10);
		const int               numPoints               = strtol(Unicode::wideToNarrow(argv[4]).c_str(),NULL,10);
		const Object *          player                  = NetworkIdManager::getObjectById(userId);

		if (player)
		{
			SurveySystem::getInstance().requestSurvey(userId, parentResourceClassName, resourceTypeName, player->getPosition_w(), surveyRange, numPoints);
			result += getErrorMessage(argv[0], ERR_SUCCESS);
		}
		else
			result += getErrorMessage(argv [0], ERR_INVALID_OBJECT);
	}

	else if (isCommand( argv [0], "deplete"))
	{
		NetworkId resourceId (Unicode::wideToNarrow (argv[1]));
		if (ServerUniverse::getInstance().manualDepleteResource(resourceId))
			result += getErrorMessage(argv[0], ERR_SUCCESS);
		else
			result += getErrorMessage (argv [0], ERR_INVALID_OBJECT);	
	}
	
	return true;
}	// ConsoleCommandParserResource::performParsing