archive_patch_helper.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file. 4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/setup/archive_patch_helper.h" 6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/file_util.h" 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/logging.h" 9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/installer/util/lzma_util.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "courgette/courgette.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/bspatch/mbspatch.h" 12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 13ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace installer { 14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 15ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochArchivePatchHelper::ArchivePatchHelper(const base::FilePath& working_directory, 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& compressed_archive, 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& patch_source, 18ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& target) 19ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : working_directory_(working_directory), 20ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch compressed_archive_(compressed_archive), 21ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch patch_source_(patch_source), 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch target_(target) {} 23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochArchivePatchHelper::~ArchivePatchHelper() {} 25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// static 27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ArchivePatchHelper::UncompressAndPatch( 28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& working_directory, 29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& compressed_archive, 30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& patch_source, 31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const base::FilePath& target) { 32ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ArchivePatchHelper instance(working_directory, compressed_archive, 33ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch patch_source, target); 34ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return (instance.Uncompress(NULL) && 35ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch (instance.EnsemblePatch() || instance.BinaryPatch())); 36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ArchivePatchHelper::Uncompress(base::FilePath* last_uncompressed_file) { 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // The target shouldn't already exist. 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(!base::PathExists(target_)); 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // UnPackArchive takes care of logging. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 output_file; 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int32 lzma_result = LzmaUtil::UnPackArchive(compressed_archive_.value(), 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch working_directory_.value(), 46ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch &output_file); 47ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (lzma_result != NO_ERROR) 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch last_uncompressed_file_ = base::FilePath(output_file); 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (last_uncompressed_file) 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch *last_uncompressed_file = last_uncompressed_file_; 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ArchivePatchHelper::EnsemblePatch() { 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (last_uncompressed_file_.empty()) { 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) << "No patch file found in compressed archive."; 59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch courgette::Status result = 63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch courgette::ApplyEnsemblePatch(patch_source_.value().c_str(), 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch last_uncompressed_file_.value().c_str(), 65ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch target_.value().c_str()); 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (result == courgette::C_OK) 67ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 68ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << "Failed to apply patch " << last_uncompressed_file_.value() 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " to file " << patch_source_.value() 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " and generating file " << target_.value() 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " using courgette. err=" << result; 74ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Ensure a partial output is not left behind. 76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::DeleteFile(target_, false); 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool ArchivePatchHelper::BinaryPatch() { 82ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (last_uncompressed_file_.empty()) { 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) << "No patch file found in compressed archive."; 84ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 85ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 86ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int result = ApplyBinaryPatch(patch_source_.value().c_str(), 88ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch last_uncompressed_file_.value().c_str(), 89ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch target_.value().c_str()); 90ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (result == OK) 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return true; 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 93ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch LOG(ERROR) 94ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << "Failed to apply patch " << last_uncompressed_file_.value() 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " to file " << patch_source_.value() 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " and generating file " << target_.value() 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << " using bsdiff. err=" << result; 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Ensure a partial output is not left behind. 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::DeleteFile(target_, false); 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return false; 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 104ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 105ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} // namespace installer 106