• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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