1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <errno.h> 18 #include <stdarg.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <sys/stat.h> 23 #include <unistd.h> 24 25 #include "edify/expr.h" 26 #include "firmware.h" 27 #include "mincrypt/sha.h" 28 #include "minzip/Zip.h" 29 #include "mtdutils/mounts.h" 30 #include "updater/updater.h" 31 32 Value* UpdateFn(const char* name, State* state, int argc, Expr* argv[]) { 33 if (argc != 7) { 34 return ErrorAbort(state, "%s() expects 7 args, got %d", name, argc); 35 } 36 37 char* type = strrchr(name, '_'); 38 if (type == NULL || *(type+1) == '\0') { 39 return ErrorAbort(state, "%s() couldn't get type from function name", 40 name); 41 } 42 ++type; 43 44 Value* image; 45 Value* width_string; 46 Value* height_string; 47 Value* bpp_string; 48 Value* busy; 49 Value* fail; 50 Value* expected_sha1_string; 51 if (ReadValueArgs(state, argv, 7, &image, 52 &width_string, &height_string, &bpp_string, 53 &busy, &fail, &expected_sha1_string) < 0) { 54 return NULL; 55 } 56 57 // close the package 58 ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip; 59 mzCloseZipArchive(za); 60 ((UpdaterInfo*)(state->cookie))->package_zip = NULL; 61 62 // Try to unmount /cache. If we fail (because we're running in an 63 // older recovery that still has the package file open), try to 64 // remount it read-only. If that fails, abort. 65 sync(); 66 scan_mounted_volumes(); 67 MountedVolume* vol = find_mounted_volume_by_mount_point("/cache"); 68 int result = unmount_mounted_volume(vol); 69 if (result != 0) { 70 printf("%s(): failed to unmount cache (%d: %s)\n", 71 name, result, strerror(errno)); 72 73 result = remount_read_only(vol); 74 if (result != 0) { 75 printf("%s(): failed to remount cache (%d: %s)\n", 76 name, result, strerror(errno)); 77 return StringValue(strdup("")); 78 } else { 79 printf("%s(): remounted cache\n", name); 80 } 81 sync(); 82 } else { 83 printf("%s(): unmounted cache\n", name); 84 } 85 86 int width = 0, height = 0, bpp = 0; 87 88 if (width_string->type != VAL_STRING || 89 (width = strtol(width_string->data, NULL, 10)) == 0) { 90 printf("%s(): bad width argument", name); 91 } 92 if (height_string->type != VAL_STRING || 93 (height = strtol(height_string->data, NULL, 10)) == 0) { 94 printf("%s(): bad height argument", name); 95 } 96 if (bpp_string->type != VAL_STRING || 97 (bpp = strtol(bpp_string->data, NULL, 10)) == 0) { 98 printf("%s(): bad bpp argument", name); 99 } 100 101 if (image->type != VAL_BLOB) { 102 printf("image argument is not blob (is type %d)\n", image->type); 103 goto done; 104 } 105 106 uint8_t expected_sha1[SHA_DIGEST_SIZE]; 107 char* data = expected_sha1_string->data; 108 if (expected_sha1_string->type != VAL_STRING || 109 strlen(data) != SHA_DIGEST_SIZE*2) { 110 printf("%s(): bad expected_sha1 argument", name); 111 goto done; 112 } 113 printf("expected sha1 is: "); 114 int i; 115 for (i = 0; i < SHA_DIGEST_SIZE; ++i) { 116 char temp = data[i*2+2]; 117 data[i*2+2] = '\0'; 118 expected_sha1[i] = strtol(data+i*2, NULL, 16); 119 data[i*2+2] = temp; 120 printf("%02x", expected_sha1[i]); 121 } 122 printf("\n"); 123 124 install_firmware_update( 125 type, 126 image->data, 127 image->size, 128 width, height, bpp, 129 busy->size > 0 ? busy->data : NULL, 130 fail->size > 0 ? fail->data : NULL, 131 "/tmp/recovery.log", 132 expected_sha1); 133 printf("%s: install_firmware_update returned!\n", name); 134 135 done: 136 FreeValue(image); 137 FreeValue(width_string); 138 FreeValue(height_string); 139 FreeValue(bpp_string); 140 FreeValue(busy); 141 FreeValue(fail); 142 // install_firmware_update should reboot. If it returns, it failed. 143 return StringValue(strdup("")); 144 } 145 146 void Register_librecovery_updater_htc() { 147 fprintf(stderr, "installing HTC updater extensions\n"); 148 149 RegisterFunction("htc.install_radio", UpdateFn); 150 RegisterFunction("htc.install_hboot", UpdateFn); 151 } 152