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

	BMessage reply;
	status_t status = B_OK;

	if (!fUserMode) {
		// Request the data from the user's daemon, too
		Session* session = FindSession(user);
		if (session != NULL) {
			BMessage request(B_GET_LAUNCH_TARGETS);
			status = request.AddInt32("user", 0);
			if (status == B_OK) {
				status = session->Daemon().SendMessage(&request,
					&reply);
			}
			if (status == B_OK)
				status = reply.what;
		} else
			status = B_NAME_NOT_FOUND;
	}

	if (status == B_OK) {
		TargetMap::const_iterator iterator = fTargets.begin();
		for (; iterator != fTargets.end(); iterator++)
			reply.AddString("target", iterator->first);
	}

	reply.what = status;
	message->SendReply(&reply);
}
Example #2
0
void
LaunchDaemon::_HandleStopLaunchJob(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

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

	Job* job = FindJob(name);
	if (job == 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;
	}

	_StopJob(job, message->GetBool("force"));

	BMessage reply((uint32)B_OK);
	message->SendReply(&reply);
}
Example #3
0
void
LaunchDaemon::_HandleGetLaunchData(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

	BMessage reply((uint32)B_OK);
	bool launchJob = true;

	Job* job = FindJob(get_leaf(message->GetString("name")));
	if (job == NULL) {
		Session* session = FindSession(user);
		if (session != NULL) {
			// Forward request to user launch_daemon
			if (session->Daemon().SendMessage(message) == B_OK)
				return;
		}
		reply.what = B_NAME_NOT_FOUND;
	} else if (job->IsService() && !job->IsLaunched()) {
		if (job->InitCheck() == B_NO_INIT || !job->CheckCondition(*this)) {
			// The job exists, but cannot be started yet, as its
			// conditions are not met; don't make it available yet
			// TODO: we may not want to initialize jobs with conditions
			// that aren't met yet
			reply.what = B_NO_INIT;
		} else if (job->Event() != NULL) {
			if (!Events::TriggerDemand(job->Event())) {
				// The job is not triggered by demand; we cannot start it now
				reply.what = B_NO_INIT;
			} else {
				// The job has already been triggered, don't launch it again
				launchJob = false;
			}
		}
	} else
		launchJob = false;

	bool ownsMessage = false;
	if (reply.what == B_OK) {
		// Launch the job if it hasn't been launched already
		if (launchJob)
			_LaunchJob(job, TRIGGER_DEMAND);

		DetachCurrentMessage();
		status_t result = job->HandleGetLaunchData(message);
		if (result == B_OK) {
			// Replying is delegated to the job.
			return;
		}

		ownsMessage = true;
		reply.what = result;
	}

	message->SendReply(&reply);
	if (ownsMessage)
		delete message;
}
Example #4
0
void
LaunchDaemon::_ForwardEventMessage(uid_t user, BMessage* message)
{
	if (fUserMode)
		return;

	// Forward event to user launch_daemon(s)
	if (user == 0) {
		for (SessionMap::iterator iterator = fSessions.begin();
				iterator != fSessions.end(); iterator++) {
			Session* session = iterator->second;
			session->Daemon().SendMessage(message);
				// ignore reply
		}
	} else {
		Session* session = FindSession(user);
		if (session != NULL)
			session->Daemon().SendMessage(message);
	}
}
Example #5
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);
}
Example #6
0
void
LaunchDaemon::_HandleGetLaunchJobs(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

	const char* targetName = message->GetString("target");

	BMessage reply;
	status_t status = B_OK;

	if (!fUserMode) {
		// Request the data from the user's daemon, too
		Session* session = FindSession(user);
		if (session != NULL) {
			BMessage request(B_GET_LAUNCH_JOBS);
			status = request.AddInt32("user", 0);
			if (status == B_OK && targetName != NULL)
				status = request.AddString("target", targetName);
			if (status == B_OK) {
				status = session->Daemon().SendMessage(&request,
					&reply);
			}
			if (status == B_OK)
				status = reply.what;
		} else
			status = B_NAME_NOT_FOUND;
	}

	if (status == B_OK) {
		JobMap::const_iterator iterator = fJobs.begin();
		for (; iterator != fJobs.end(); iterator++) {
			Job* job = iterator->second;
			if (targetName != NULL && (job->Target() == NULL
					|| job->Target()->Title() != targetName)) {
				continue;
			}
			reply.AddString("job", iterator->first);
		}
	}

	reply.what = status;
	message->SendReply(&reply);
}
Example #7
0
void
LaunchDaemon::_HandleGetLaunchData(BMessage* message)
{
	uid_t user = _GetUserID(message);
	if (user < 0)
		return;

	BMessage reply((uint32)B_OK);
	bool launchJob = true;

	Job* job = FindJob(get_leaf(message->GetString("name")));
	if (job == NULL) {
		Session* session = FindSession(user);
		if (session != NULL) {
			// Forward request to user launch_daemon
			if (session->Daemon().SendMessage(message) == B_OK)
				return;
		}
		reply.what = B_NAME_NOT_FOUND;
	} else if (!job->IsLaunched()) {
		if (job->InitCheck() == B_NO_INIT || !job->CheckCondition(*this)) {
			// The job exists, but cannot be started yet, as its
			// conditions are not met; don't make it available yet
			// TODO: we may not want to initialize jobs with conditions
			// that aren't met yet
			reply.what = B_NO_INIT;
		} else if (job->Event() != NULL) {
			if (!Events::TriggerDemand(job->Event())) {
				// The job is not triggered by demand; we cannot start it now
				reply.what = B_NO_INIT;
			} else {
				// The job has already been triggered, don't launch it again
				launchJob = false;
			}
		}
	}

	if (reply.what == B_OK) {
		// If the job has not been launched yet, we'll pass on our
		// team here. The rationale behind this is that this team
		// will temporarily own the synchronous reply ports.
		reply.AddInt32("team", job->Team() < 0
			? current_team() : job->Team());

		PortMap::const_iterator iterator = job->Ports().begin();
		for (; iterator != job->Ports().end(); iterator++) {
			BString name;
			if (iterator->second.HasString("name"))
				name << iterator->second.GetString("name") << "_";
			name << "port";

			reply.AddInt32(name.String(),
				iterator->second.GetInt32("port", -1));
		}

		// Launch the job if it hasn't been launched already
		if (launchJob)
			_LaunchJob(job);
	}
	message->SendReply(&reply);
}