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
UpdateFn(const char * name,State * state,int argc,Expr * argv[])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
Register_librecovery_updater_htc()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