103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Copyright (C) 2016 The Android Open Source Project 303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Licensed under the Apache License, Version 2.0 (the "License"); 503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// you may not use this file except in compliance with the License. 603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// You may obtain a copy of the License at 703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// http://www.apache.org/licenses/LICENSE-2.0 903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 1003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Unless required by applicable law or agreed to in writing, software 1103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// distributed under the License is distributed on an "AS IS" BASIS, 1203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// See the License for the specific language governing permissions and 1403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// limitations under the License. 1503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// 1603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 1703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <xz.h> 1803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 1903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <string> 2003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <vector> 2103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 2203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/command_line.h> 2303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/logging.h> 2403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <base/strings/string_split.h> 2540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <base/strings/stringprintf.h> 2640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/asynchronous_signal_handler.h> 2703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <brillo/flag_helper.h> 2840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/make_unique_ptr.h> 2903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include <brillo/message_loops/base_message_loop.h> 3040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/streams/file_stream.h> 3140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include <brillo/streams/stream.h> 3203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 3303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/boot_control.h" 3440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include "update_engine/common/error_code_utils.h" 3503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/hardware.h" 3603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/prefs.h" 3740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo#include "update_engine/common/subprocess.h" 3803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/terminator.h" 3903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/common/utils.h" 4003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo#include "update_engine/update_attempter_android.h" 4103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 4203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymousing std::string; 4303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymousing std::vector; 4440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymousing update_engine::UpdateStatus; 4503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 463295102ed64107f966d4cf8bfe733bb936646630Alex Deymonamespace { 473295102ed64107f966d4cf8bfe733bb936646630Alex Deymo// The root directory used for temporary files in update_engine_sideload. 483295102ed64107f966d4cf8bfe733bb936646630Alex Deymoconst char kSideloadRootTempDir[] = "/tmp/update_engine_sideload"; 493295102ed64107f966d4cf8bfe733bb936646630Alex Deymo} // namespace 503295102ed64107f966d4cf8bfe733bb936646630Alex Deymo 5103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymonamespace chromeos_update_engine { 5203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymonamespace { 5303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 5403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymovoid SetupLogging() { 5503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo string log_file; 5603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo logging::LoggingSettings log_settings; 5703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.lock_log = logging::DONT_LOCK_LOG_FILE; 5803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.delete_old = logging::APPEND_TO_OLD_LOG_FILE; 5903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.log_file = nullptr; 6003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo log_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 6103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 6203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo logging::InitLogging(log_settings); 6303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} 6403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 6503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymoclass SideloadDaemonState : public DaemonStateInterface, 6603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo public ServiceObserverInterface { 6703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo public: 6840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo explicit SideloadDaemonState(brillo::StreamPtr status_stream) 6940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo : status_stream_(std::move(status_stream)) { 7003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // Add this class as the only observer. 7103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo observers_.insert(this); 7203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 7303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo ~SideloadDaemonState() override = default; 7403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 7503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // DaemonStateInterface overrides. 7603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo bool StartUpdater() override { return true; } 7703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void AddObserver(ServiceObserverInterface* observer) override {} 7803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void RemoveObserver(ServiceObserverInterface* observer) override {} 7903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo const std::set<ServiceObserverInterface*>& service_observers() override { 8003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return observers_; 8103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 8203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 8303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // ServiceObserverInterface overrides. 8403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void SendStatusUpdate(int64_t last_checked_time, 8503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo double progress, 8640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo UpdateStatus status, 8703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo const string& new_version, 8803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo int64_t new_size) override { 8940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (status_ != status && (status == UpdateStatus::DOWNLOADING || 9040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo status == UpdateStatus::FINALIZING)) { 9140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // Split the progress bar in two parts for the two stages DOWNLOADING and 9240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // FINALIZING. 9340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus(base::StringPrintf( 9440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo "ui_print Step %d/2", status == UpdateStatus::DOWNLOADING ? 1 : 2)); 9540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus(base::StringPrintf("progress 0.5 0")); 9640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 9740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (status_ != status || fabs(progress - progress_) > 0.005) { 9840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus(base::StringPrintf("set_progress %.lf", progress)); 9940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 10040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo progress_ = progress; 10103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo status_ = status; 10203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 10303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 10403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo void SendPayloadApplicationComplete(ErrorCode error_code) override { 10540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (error_code != ErrorCode::kSuccess) { 10640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo ReportStatus( 10740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo base::StringPrintf("ui_print Error applying update: %d (%s)", 10840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo error_code, 10940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo utils::ErrorCodeToString(error_code).c_str())); 11040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 11103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo error_code_ = error_code; 11203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo brillo::MessageLoop::current()->BreakLoop(); 11303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 11403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 11503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // Getters. 11640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo UpdateStatus status() { return status_; } 11703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo ErrorCode error_code() { return error_code_; } 11803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 11903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo private: 12040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // Report a status message in the status_stream_, if any. These messages 12140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // should conform to the specification defined in the Android recovery. 12240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo void ReportStatus(const string& message) { 12340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo if (!status_stream_) 12440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo return; 12540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo string status_line = message + "\n"; 12640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo status_stream_->WriteAllBlocking( 12740a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo status_line.data(), status_line.size(), nullptr); 12840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo } 12940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo 13003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo std::set<ServiceObserverInterface*> observers_; 13140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo brillo::StreamPtr status_stream_; 13203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 13303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // The last status and error code reported. 13440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo UpdateStatus status_{UpdateStatus::IDLE}; 13503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo ErrorCode error_code_{ErrorCode::kSuccess}; 13640a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo double progress_{-1.}; 13703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo}; 13803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 13903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo// Apply an update payload directly from the given payload URI. 14003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymobool ApplyUpdatePayload(const string& payload, 14103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo int64_t payload_offset, 14203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo int64_t payload_size, 14340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo const vector<string>& headers, 14440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo int64_t status_fd) { 14503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo brillo::BaseMessageLoop loop; 14603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo loop.SetAsCurrent(); 14703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 14840a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo // Setup the subprocess handler. 14940a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo brillo::AsynchronousSignalHandler handler; 15040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo handler.Init(); 15140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo Subprocess subprocess; 15240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo subprocess.Init(&handler); 15340a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo 15440a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo SideloadDaemonState sideload_daemon_state( 15540a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo brillo::FileStream::FromFileDescriptor(status_fd, true, nullptr)); 15603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 15703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // During the sideload we don't access the prefs persisted on disk but instead 15803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // use a temporary memory storage. 15903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo MemoryPrefs prefs; 16003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 16103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo std::unique_ptr<BootControlInterface> boot_control = 16203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo boot_control::CreateBootControl(); 16303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo if (!boot_control) { 16403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo LOG(ERROR) << "Error initializing the BootControlInterface."; 16503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return false; 16603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 16703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 16803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo std::unique_ptr<HardwareInterface> hardware = hardware::CreateHardware(); 16903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo if (!hardware) { 17003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo LOG(ERROR) << "Error initializing the HardwareInterface."; 17103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return false; 17203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo } 17303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 17403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo UpdateAttempterAndroid update_attempter( 17503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo &sideload_daemon_state, &prefs, boot_control.get(), hardware.get()); 17603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo update_attempter.Init(); 17703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 17803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo TEST_AND_RETURN_FALSE(update_attempter.ApplyPayload( 17903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo payload, payload_offset, payload_size, headers, nullptr)); 18003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 18103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo loop.Run(); 18240a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo return sideload_daemon_state.status() == UpdateStatus::UPDATED_NEED_REBOOT; 18303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} 18403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 18503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} // namespace 18603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} // namespace chromeos_update_engine 18703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 18803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymoint main(int argc, char** argv) { 18903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_string(payload, 19003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "file:///data/payload.bin", 19103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "The URI to the update payload to use."); 19203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_int64( 19303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo offset, 0, "The offset in the payload where the CrAU update starts. "); 19403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_int64(size, 19503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 0, 19603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "The size of the CrAU part of the payload. If 0 is passed, it " 19703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "will be autodetected."); 19803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo DEFINE_string(headers, 19903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "", 20003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo "A list of key-value pairs, one element of the list per line."); 20140a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo DEFINE_int64(status_fd, -1, "A file descriptor to notify the update status."); 20203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo chromeos_update_engine::Terminator::Init(); 20403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo chromeos_update_engine::SetupLogging(); 20503a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo brillo::FlagHelper::Init(argc, argv, "Update Engine Sideload"); 20603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo LOG(INFO) << "Update Engine Sideloading starting"; 20803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 20903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo // xz-embedded requires to initialize its CRC-32 table once on startup. 21003a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo xz_crc32_init(); 21103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 2123295102ed64107f966d4cf8bfe733bb936646630Alex Deymo // When called from recovery, /data is not accessible, so we need to use 2133295102ed64107f966d4cf8bfe733bb936646630Alex Deymo // /tmp for temporary files. 2143295102ed64107f966d4cf8bfe733bb936646630Alex Deymo chromeos_update_engine::utils::SetRootTempDir(kSideloadRootTempDir); 2153295102ed64107f966d4cf8bfe733bb936646630Alex Deymo 21603a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo vector<string> headers = base::SplitString( 21703a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo FLAGS_headers, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); 21803a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 21903a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo if (!chromeos_update_engine::ApplyUpdatePayload( 22040a017db5df92ab7f9c3dcd73cd736a645931c93Alex Deymo FLAGS_payload, FLAGS_offset, FLAGS_size, headers, FLAGS_status_fd)) 22103a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return 1; 22203a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo 22303a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo return 0; 22403a4de7dc77b058987fc0670f4f67ba10ff31bc8Alex Deymo} 225