/*! 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; } } }
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); }
void LaunchDaemon::_ResolveExternalEvents(ExternalEventSource* event, const BString& name) { for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); iterator++) { Job* job = iterator->second; if (Events::ResolveExternalEvent(job->Event(), name, event->Flags())) event->AddListener(job); } }
void LaunchDaemon::_ResolveRegisteredEvents(RegisteredEvent* event, const BString& name) { for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); iterator++) { Job* job = iterator->second; if (Events::ResolveRegisteredEvent(job->Event(), name)) event->AddListener(job); } }
Job* LaunchDaemon::FindJob(const char* name) const { if (name == NULL) return NULL; JobMap::const_iterator found = fJobs.find(BString(name).ToLower()); if (found != fJobs.end()) return found->second; return NULL; }
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); }
void LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message) { BString name = message.GetString("name"); if (name.IsEmpty()) { // Invalid job description return; } name.ToLower(); Job* job = FindJob(name); if (job == NULL) { job = new (std::nothrow) Job(name); if (job == NULL) return; job->SetService(service); job->SetCreateDefaultPort(service); job->SetTarget(target); } if (message.HasBool("disabled")) job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled())); if (message.HasBool("legacy")) job->SetCreateDefaultPort(!message.GetBool("legacy", !service)); _SetCondition(job, message); _SetEvent(job, message); _SetEnvironment(job, message); BMessage portMessage; for (int32 index = 0; message.FindMessage("port", index, &portMessage) == B_OK; index++) { job->AddPort(portMessage); } if (message.HasString("launch")) { job->Arguments().MakeEmpty(); const char* argument; for (int32 index = 0; message.FindString("launch", index, &argument) == B_OK; index++) { job->AddArgument(argument); } } const char* requirement; for (int32 index = 0; message.FindString("requires", index, &requirement) == B_OK; index++) { job->AddRequirement(requirement); } if (fInitTarget != NULL) job->AddRequirement(fInitTarget->Name()); fJobs.insert(std::make_pair(job->Title(), job)); }
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); }
/*! Adds all jobs for the specified target (may be \c NULL) to the launch queue, except those that are triggered by events that haven't been triggered yet. Unless \a forceNow is true, the target is only launched if its events, if any, have been triggered already, and its conditions are met. */ void LaunchDaemon::_LaunchJobs(Target* target, bool forceNow) { if (!forceNow && target != NULL && (!target->EventHasTriggered() || !target->CheckCondition(*this))) { return; } if (target != NULL && !target->HasLaunched()) { target->SetLaunched(true); _InitJobs(target); } for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end(); iterator++) { Job* job = iterator->second; if (job->Target() == target) _LaunchJob(job); } }
void LaunchDaemon::_AddTargets(BMessage& message) { BMessage targetMessage; for (int32 index = 0; message.FindMessage("target", index, &targetMessage) == B_OK; index++) { const char* name = targetMessage.GetString("name"); if (name == NULL) { // TODO: log error debug_printf("Target has no name, ignoring it!\n"); continue; } Target* target = FindTarget(name); if (target == NULL) { target = new Target(name); _AddTarget(target); } else if (targetMessage.GetBool("reset")) { // Remove all jobs from this target for (JobMap::iterator iterator = fJobs.begin(); iterator != fJobs.end();) { Job* job = iterator->second; JobMap::iterator remove = iterator++; if (job->Target() == target) { fJobs.erase(remove); delete job; } } } _SetCondition(target, targetMessage); _SetEvent(target, targetMessage); _SetEnvironment(target, targetMessage); _AddJobs(target, targetMessage); if (target->Event() != NULL) target->Event()->Register(*this); } }