summaryrefslogtreecommitdiffstats
path: root/applypatch
diff options
context:
space:
mode:
Diffstat (limited to 'applypatch')
-rw-r--r--applypatch/NOTICE41
-rw-r--r--applypatch/applypatch.c64
-rw-r--r--applypatch/applypatch.h4
3 files changed, 88 insertions, 21 deletions
diff --git a/applypatch/NOTICE b/applypatch/NOTICE
new file mode 100644
index 000000000..6156a0ca3
--- /dev/null
+++ b/applypatch/NOTICE
@@ -0,0 +1,41 @@
+Copyright (C) 2009 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+bsdiff.c
+bspatch.c
+
+Copyright 2003-2005 Colin Percival
+All rights reserved
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted providing that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/applypatch/applypatch.c b/applypatch/applypatch.c
index 106091386..00004e9a8 100644
--- a/applypatch/applypatch.c
+++ b/applypatch/applypatch.c
@@ -30,10 +30,16 @@
#include "mtdutils/mtdutils.h"
#include "edify/expr.h"
-int SaveFileContents(const char* filename, FileContents file);
static int LoadPartitionContents(const char* filename, FileContents* file);
-int ParseSha1(const char* str, uint8_t* digest);
static ssize_t FileSink(unsigned char* data, ssize_t len, void* token);
+static int GenerateTarget(FileContents* source_file,
+ const Value* source_patch_value,
+ FileContents* copy_file,
+ const Value* copy_patch_value,
+ const char* source_filename,
+ const char* target_filename,
+ const uint8_t target_sha1[SHA_DIGEST_SIZE],
+ size_t target_size);
static int mtd_partitions_scanned = 0;
@@ -113,11 +119,6 @@ static int compare_size_indices(const void* a, const void* b) {
}
}
-void FreeFileContents(FileContents* file) {
- if (file) free(file->data);
- free(file);
-}
-
// Load the contents of an MTD or EMMC partition into the provided
// FileContents. filename should be a string of the form
// "MTD:<partition_name>:<size_1>:<sha1_1>:<size_2>:<sha1_2>:..." (or
@@ -322,7 +323,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
// Save the contents of the given FileContents object under the given
// filename. Return 0 on success.
-int SaveFileContents(const char* filename, FileContents file) {
+int SaveFileContents(const char* filename, const FileContents* file) {
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC);
if (fd < 0) {
printf("failed to open \"%s\" for write: %s\n",
@@ -330,10 +331,10 @@ int SaveFileContents(const char* filename, FileContents file) {
return -1;
}
- ssize_t bytes_written = FileSink(file.data, file.size, &fd);
- if (bytes_written != file.size) {
+ ssize_t bytes_written = FileSink(file->data, file->size, &fd);
+ if (bytes_written != file->size) {
printf("short write of \"%s\" (%ld bytes of %ld) (%s)\n",
- filename, (long)bytes_written, (long)file.size,
+ filename, (long)bytes_written, (long)file->size,
strerror(errno));
close(fd);
return -1;
@@ -341,11 +342,11 @@ int SaveFileContents(const char* filename, FileContents file) {
fsync(fd);
close(fd);
- if (chmod(filename, file.st.st_mode) != 0) {
+ if (chmod(filename, file->st.st_mode) != 0) {
printf("chmod of \"%s\" failed: %s\n", filename, strerror(errno));
return -1;
}
- if (chown(filename, file.st.st_uid, file.st.st_gid) != 0) {
+ if (chown(filename, file->st.st_uid, file->st.st_gid) != 0) {
printf("chown of \"%s\" failed: %s\n", filename, strerror(errno));
return -1;
}
@@ -471,7 +472,7 @@ int ParseSha1(const char* str, uint8_t* digest) {
// Search an array of sha1 strings for one matching the given sha1.
// Return the index of the match on success, or -1 if no match is
// found.
-int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
+int FindMatchingPatch(uint8_t* sha1, const char** patch_sha1_str,
int num_patches) {
int i;
uint8_t patch_sha1[SHA_DIGEST_SIZE];
@@ -503,6 +504,7 @@ int applypatch_check(const char* filename,
"sha1 sums; checking cache\n", filename);
free(file.data);
+ file.data = NULL;
// If the source file is missing or corrupted, it might be because
// we were killed in the middle of patching it. A copy of it
@@ -631,9 +633,10 @@ int applypatch(const char* source_filename,
FileContents copy_file;
FileContents source_file;
+ copy_file.data = NULL;
+ source_file.data = NULL;
const Value* source_patch_value = NULL;
const Value* copy_patch_value = NULL;
- int made_copy = 0;
// We try to load the target file into the source_file object.
if (LoadFileContents(target_filename, &source_file,
@@ -643,6 +646,7 @@ int applypatch(const char* source_filename,
// has the desired hash, nothing for us to do.
printf("\"%s\" is already target; no patch needed\n",
target_filename);
+ free(source_file.data);
return 0;
}
}
@@ -653,6 +657,7 @@ int applypatch(const char* source_filename,
// Need to load the source file: either we failed to load the
// target file, or we did but it's different from the source file.
free(source_file.data);
+ source_file.data = NULL;
LoadFileContents(source_filename, &source_file,
RETOUCH_DO_MASK);
}
@@ -667,6 +672,7 @@ int applypatch(const char* source_filename,
if (source_patch_value == NULL) {
free(source_file.data);
+ source_file.data = NULL;
printf("source file is bad; trying copy\n");
if (LoadFileContents(CACHE_TEMP_SOURCE, &copy_file,
@@ -685,16 +691,36 @@ int applypatch(const char* source_filename,
if (copy_patch_value == NULL) {
// fail.
printf("copy file doesn't match source SHA-1s either\n");
+ free(copy_file.data);
return 1;
}
}
+ int result = GenerateTarget(&source_file, source_patch_value,
+ &copy_file, copy_patch_value,
+ source_filename, target_filename,
+ target_sha1, target_size);
+ free(source_file.data);
+ free(copy_file.data);
+
+ return result;
+}
+
+static int GenerateTarget(FileContents* source_file,
+ const Value* source_patch_value,
+ FileContents* copy_file,
+ const Value* copy_patch_value,
+ const char* source_filename,
+ const char* target_filename,
+ const uint8_t target_sha1[SHA_DIGEST_SIZE],
+ size_t target_size) {
int retry = 1;
SHA_CTX ctx;
int output;
MemorySinkInfo msi;
FileContents* source_to_use;
char* outname;
+ int made_copy = 0;
// assume that target_filename (eg "/system/app/Foo.apk") is located
// on the same filesystem as its top-level directory ("/system").
@@ -723,7 +749,7 @@ int applypatch(const char* source_filename,
// We still write the original source to cache, in case
// the partition write is interrupted.
- if (MakeFreeSpaceOnCache(source_file.size) < 0) {
+ if (MakeFreeSpaceOnCache(source_file->size) < 0) {
printf("not enough free space on /cache\n");
return 1;
}
@@ -763,7 +789,7 @@ int applypatch(const char* source_filename,
return 1;
}
- if (MakeFreeSpaceOnCache(source_file.size) < 0) {
+ if (MakeFreeSpaceOnCache(source_file->size) < 0) {
printf("not enough free space on /cache\n");
return 1;
}
@@ -782,10 +808,10 @@ int applypatch(const char* source_filename,
const Value* patch;
if (source_patch_value != NULL) {
- source_to_use = &source_file;
+ source_to_use = source_file;
patch = source_patch_value;
} else {
- source_to_use = &copy_file;
+ source_to_use = copy_file;
patch = copy_patch_value;
}
diff --git a/applypatch/applypatch.h b/applypatch/applypatch.h
index a78c89bfe..fb58843ba 100644
--- a/applypatch/applypatch.h
+++ b/applypatch/applypatch.h
@@ -62,9 +62,9 @@ int applypatch_check(const char* filename,
int LoadFileContents(const char* filename, FileContents* file,
int retouch_flag);
-int SaveFileContents(const char* filename, FileContents file);
+int SaveFileContents(const char* filename, const FileContents* file);
void FreeFileContents(FileContents* file);
-int FindMatchingPatch(uint8_t* sha1, char** const patch_sha1_str,
+int FindMatchingPatch(uint8_t* sha1, const char** patch_sha1_str,
int num_patches);
// bsdiff.c