示例#1
0
void
LaunchDaemon::_HandleGetLaunchTargetInfo(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

	const char* name = message->GetString("name");
	Target* target = FindTarget(name);
	if (target == NULL && !fUserMode) {
		_ForwardEventMessage(user, message);
		return;
	}

	BMessage info(uint32(target != NULL ? B_OK : B_NAME_NOT_FOUND));
	if (target != NULL) {
		_GetBaseJobInfo(target, info);

		for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();
				iterator++) {
			Job* job = iterator->second;
			if (job->Target() == target)
				info.AddString("job", job->Name());
		}
	}
	message->SendReply(&info);
}
示例#2
0
/*!	Initializes all jobs for the specified target (may be \c NULL).
	Jobs that cannot be initialized, and those that never will be due to
	conditions, will be removed from the list.
*/
void
LaunchDaemon::_InitJobs(Target* target)
{
	for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();) {
		Job* job = iterator->second;
		JobMap::iterator remove = iterator++;

		if (job->Target() != target)
			continue;

		status_t status = B_NO_INIT;
		if (job->IsEnabled()) {
			// Filter out jobs that have a constant and failing condition
			if (job->Condition() == NULL || !job->Condition()->IsConstant(*this)
				|| job->Condition()->Test(*this)) {
				std::set<BString> dependencies;
				status = job->Init(*this, dependencies);
				if (status == B_OK && job->Event() != NULL)
					status = job->Event()->Register(*this);
			}
		}

		if (status != B_OK) {
			if (status != B_NO_INIT) {
				// TODO: log error
				debug_printf("Init \"%s\" failed: %s\n", job->Name(),
					strerror(status));
			}

			// Remove jobs that won't be used later on
			fJobs.erase(remove);
			delete job;
		}
	}
}
示例#3
0
void
LaunchDaemon::_HandleLaunchTarget(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

	const char* name = message->GetString("target");
	const char* baseName = message->GetString("base target");

	Target* target = FindTarget(name);
	if (target == NULL && baseName != NULL) {
		Target* baseTarget = FindTarget(baseName);
		if (baseTarget != NULL) {
			target = new Target(name);

			// Copy all jobs with the base target into the new target
			for (JobMap::iterator iterator = fJobs.begin();
					iterator != fJobs.end();) {
				Job* job = iterator->second;
				iterator++;

				if (job->Target() == baseTarget) {
					Job* copy = new Job(*job);
					copy->SetTarget(target);

					fJobs.insert(std::make_pair(copy->Name(), copy));
				}
			}
		}
	}
	if (target == NULL) {
		Session* session = FindSession(user);
		if (session != NULL) {
			// Forward request to user launch_daemon
			if (session->Daemon().SendMessage(message) == B_OK)
				return;
		}

		BMessage reply(B_NAME_NOT_FOUND);
		message->SendReply(&reply);
		return;
	}

	BMessage data;
	if (message->FindMessage("data", &data) == B_OK)
		target->AddData(data.GetString("name"), data);

	_LaunchJobs(target);
}
示例#4
0
Job::Job(const Job& other)
    :
    BaseJob(other.Name()),
    fEnabled(other.IsEnabled()),
    fService(other.IsService()),
    fCreateDefaultPort(other.CreateDefaultPort()),
    fLaunching(other.IsLaunching()),
    fInitStatus(B_NO_INIT),
    fTeam(-1),
    fDefaultPort(-1),
    fToken((uint32)B_PREFERRED_TOKEN),
    fLaunchStatus(B_NO_INIT),
    fTarget(other.Target()),
    fPendingLaunchDataReplies(0, false)
{
    mutex_init(&fLaunchStatusLock, "launch status lock");

    fCondition = other.fCondition;
    // TODO: copy events
    //fEvent = other.fEvent;
    fEnvironment = other.fEnvironment;
    fSourceFiles = other.fSourceFiles;

    for (int32 i = 0; i < other.Arguments().CountStrings(); i++)
        AddArgument(other.Arguments().StringAt(i));

    for (int32 i = 0; i < other.Requirements().CountStrings(); i++)
        AddRequirement(other.Requirements().StringAt(i));

    PortMap::const_iterator constIterator = other.Ports().begin();
    for (; constIterator != other.Ports().end(); constIterator++) {
        fPortMap.insert(
            std::make_pair(constIterator->first, constIterator->second));
    }

    PortMap::iterator iterator = fPortMap.begin();
    for (; iterator != fPortMap.end(); iterator++)
        iterator->second.RemoveData("port");
}
示例#5
0
void
LaunchDaemon::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case B_SYSTEM_OBJECT_UPDATE:
		{
			int32 opcode = message->GetInt32("opcode", 0);
			team_id team = (team_id)message->GetInt32("team", -1);
			if (opcode != B_TEAM_DELETED || team < 0)
				break;

			MutexLocker locker(fTeamsLock);

			TeamMap::iterator found = fTeams.find(team);
			if (found != fTeams.end()) {
				Job* job = found->second;
				TRACE("Job %s ended!\n", job->Name());
				job->TeamDeleted();

				if (job->IsService()) {
					// TODO: take restart throttle into account
					// TODO: don't restart on shutdown
					_LaunchJob(job);
				}
			}
			break;
		}
		case B_SOME_APP_LAUNCHED:
		{
			team_id team = (team_id)message->GetInt32("be:team", -1);
			Job* job = NULL;

			MutexLocker locker(fTeamsLock);

			TeamMap::iterator found = fTeams.find(team);
			if (found != fTeams.end()) {
				job = found->second;
				locker.Unlock();
			} else {
				locker.Unlock();

				// Find job by name instead
				const char* signature = message->GetString("be:signature");
				job = FindJob(get_leaf(signature));
				if (job != NULL) {
					TRACE("Updated default port of untracked team %d, %s\n",
						(int)team, signature);
				}
			}

			if (job != NULL) {
				// Update port info
				app_info info;
				status_t status = be_roster->GetRunningAppInfo(team, &info);
				if (status == B_OK && info.port != job->DefaultPort()) {
					TRACE("Update default port for %s to %d\n", job->Name(),
						(int)info.port);
					job->SetDefaultPort(info.port);
				}
			}
			break;
		}

		case B_GET_LAUNCH_DATA:
			_HandleGetLaunchData(message);
			break;

		case B_LAUNCH_TARGET:
			_HandleLaunchTarget(message);
			break;
		case B_LAUNCH_JOB:
			_HandleLaunchJob(message);
			break;
		case B_ENABLE_LAUNCH_JOB:
			_HandleEnableLaunchJob(message);
			break;
		case B_STOP_LAUNCH_JOB:
			_HandleStopLaunchJob(message);
			break;

		case B_LAUNCH_SESSION:
			_HandleLaunchSession(message);
			break;
		case B_REGISTER_SESSION_DAEMON:
			_HandleRegisterSessionDaemon(message);
			break;

		case B_REGISTER_LAUNCH_EVENT:
			_HandleRegisterLaunchEvent(message);
			break;
		case B_UNREGISTER_LAUNCH_EVENT:
			_HandleUnregisterLaunchEvent(message);
			break;
		case B_NOTIFY_LAUNCH_EVENT:
			_HandleNotifyLaunchEvent(message);
			break;
		case B_RESET_STICKY_LAUNCH_EVENT:
			_HandleResetStickyLaunchEvent(message);
			break;

		case B_GET_LAUNCH_TARGETS:
			_HandleGetLaunchTargets(message);
			break;
		case B_GET_LAUNCH_TARGET_INFO:
			_HandleGetLaunchTargetInfo(message);
			break;
		case B_GET_LAUNCH_JOBS:
			_HandleGetLaunchJobs(message);
			break;
		case B_GET_LAUNCH_JOB_INFO:
			_HandleGetLaunchJobInfo(message);
			break;

		case kMsgEventTriggered:
		{
			// An internal event has been triggered.
			// Check if its job can be launched now.
			const char* name = message->GetString("owner");
			if (name == NULL)
				break;

			Job* job = FindJob(name);
			if (job != NULL) {
				_LaunchJob(job);
				break;
			}

			Target* target = FindTarget(name);
			if (target != NULL) {
				_LaunchJobs(target);
				break;
			}
			break;
		}

		default:
			BServer::MessageReceived(message);
			break;
	}
}