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); }
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); }
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; }
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); } }
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::_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); }
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); }