1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <dlfcn.h>
16 #include <iostream>
17 #include "fs_manager/mount.h"
18 #include "misc_info/misc_info.h"
19 #include "securec.h"
20 #include "updater/updater_const.h"
21 #include "parameter.h"
22 #include "utils.h"
23 #include "utils_fs.h"
24
25 using namespace std;
26 using namespace Updater;
27
28 constexpr const char *HANDLE_MISC_LIB = "libupdater_handle_misc.z.so";
29 constexpr const char *NOTIFY_MISC_INFO = "NotifyWriteMiscInfo";
30 constexpr const char *HANDLE_MISC_LIB_PATH = "/system/lib64/libupdater_handle_misc.z.so";
31 constexpr const char *LIB_PATH = "/system/lib64/";
32
PrintPrompts()33 static void PrintPrompts()
34 {
35 cout << "Please input correct command, examples :" << endl;
36 cout << "bin : write_updater bin /data/updater/update.bin" <<endl;
37 cout << "updater : write_updater updater /data/updater/updater.zip" << endl;
38 cout << "factory_reset : write_updater user_factory_reset" << endl;
39 cout << "sdcard_update : write_updater sdcard_update" << endl;
40 cout << "clear command : write_updater clear" << endl;
41 cout << "updater_para : write_updater updater_para" << endl;
42 cout << "intral_update : write_updater ota_intral_update /data/updater/updater.zip" << endl;
43 cout << "subpkg_update : write_updater subpkg_update" << endl;
44 cout << "notify_update : write_updater notify_update" << endl;
45 }
46
ExceptionBin(int argc,char ** argv,UpdateMessage & boot)47 static int ExceptionBin(int argc, char **argv, UpdateMessage &boot)
48 {
49 if (argc < BINARY_MAX_ARGS) {
50 cout << "Please input correct updater command!" << endl;
51 return -1;
52 }
53 if (argv[WRITE_SECOND_CMD] != nullptr) {
54 // 加入新字段
55 if (snprintf_s(boot.update, sizeof(boot.update), sizeof(boot.update) - 1, "--update_bin=%s",
56 argv[WRITE_SECOND_CMD]) == -1) {
57 cout << "WriteUpdaterMessage snprintf_s failed!" << endl;
58 return -1;
59 }
60 }
61 return 0;
62 }
63
WriteUpdaterLanguage(UpdaterPara & para)64 static int WriteUpdaterLanguage(UpdaterPara ¶)
65 {
66 char language[MAX_PARA_SIZE + 1] {};
67 int res = GetParameter("persist.global.locale", "", language, MAX_PARA_SIZE);
68 if (res <= 0) {
69 cout << "Get persist.global.locale parameter failed" << endl;
70 res = GetParameter("const.global.locale", "", language, MAX_PARA_SIZE);
71 if (res <= 0) {
72 cout << "Get const.global.locale parameter failed" << endl;
73 return -1;
74 }
75 }
76 (void)memset_s(para.language, MAX_PARA_SIZE, 0, MAX_PARA_SIZE);
77 res = memcpy_s(para.language, MAX_PARA_SIZE, language, sizeof(language) - 1);
78 para.language[MAX_PARA_SIZE - 1] = '\0';
79 if (res != 0) {
80 cout << "memcpy_s para.language failed" << endl;
81 return -1;
82 }
83 return 0;
84 }
85
WriteUpdaterVersionSuffix(UpdaterPara & para)86 static int WriteUpdaterVersionSuffix(UpdaterPara ¶)
87 {
88 char osVersionSuffix[MAX_PARA_SIZE + 1] {};
89 int res = GetParameter("const.settings.os_version_suffix", "", osVersionSuffix, MAX_PARA_SIZE);
90 if (res < 0) {
91 cout << "Get const.settings.os_version_suffix parameter failed" << endl;
92 return -1;
93 }
94 (void)memset_s(para.osVersionSuffix, MAX_PARA_SIZE, 0, MAX_PARA_SIZE);
95 res = memcpy_s(para.osVersionSuffix, MAX_PARA_SIZE, osVersionSuffix, sizeof(osVersionSuffix) - 1);
96 para.osVersionSuffix[MAX_PARA_SIZE - 1] = '\0';
97 if (res != 0) {
98 cout << "memcpy_s para.osVersionSuffix failed" << endl;
99 return -1;
100 }
101 return 0;
102 }
103
ExceptionUpdater(int argc,char ** argv,UpdateMessage & boot)104 static int ExceptionUpdater(int argc, char **argv, UpdateMessage &boot)
105 {
106 if (argc < BINARY_MAX_ARGS) {
107 cout << "Please input correct updater command!" << endl;
108 return -1;
109 }
110 if (argv[WRITE_SECOND_CMD] != nullptr) {
111 if (snprintf_s(boot.update, sizeof(boot.update), sizeof(boot.update) - 1, "--update_package=%s",
112 argv[WRITE_SECOND_CMD]) == -1) {
113 cout << "WriteUpdaterMessage snprintf_s failed!" << endl;
114 return -1;
115 }
116 }
117 return 0;
118 }
119
WriteUpdaterPara(int argc,UpdaterPara & para)120 static int WriteUpdaterPara(int argc, UpdaterPara ¶)
121 {
122 if (argc != 2) { // 2 : Not 2 is an invalid input
123 cout << "please input correct updater command!" << endl;
124 return -1;
125 }
126 if (!ReadUpdaterParaMisc(para)) {
127 cout << "ReadUpdaterParaMisc failed" << endl;
128 return -1;
129 }
130 int resLanguage = WriteUpdaterLanguage(para);
131 int resVersionSuffix = WriteUpdaterVersionSuffix(para);
132 if (!WriteUpdaterParaMisc(para)) {
133 cout << "WriteUpdaterParaMisc failed!" << endl;
134 return -1;
135 }
136 if (resLanguage != 0 || resVersionSuffix != 0) {
137 cout << "WriteUpdaterLanguage or WriteUpdaterVersionSuffix fail" << endl;
138 return -1;
139 }
140 return 0;
141 }
142
HandleMiscInfo(int argc,char ** argv)143 static void HandleMiscInfo(int argc, char **argv)
144 {
145 if (!Utils::IsFileExist(HANDLE_MISC_LIB_PATH)) {
146 return;
147 }
148 auto handle = Utils::LoadLibrary(HANDLE_MISC_LIB, LIB_PATH);
149 if (handle == nullptr) {
150 cout << "load libupdater_handle_misc fail";
151 return;
152 }
153 auto getFunc = (void(*)(int, char **))Utils::GetFunction(handle, NOTIFY_MISC_INFO);
154 if (getFunc == nullptr) {
155 cout << "getFunc is nullptr";
156 Utils::CloseLibrary(handle);
157 return;
158 }
159 getFunc(argc, argv);
160 Utils::CloseLibrary(handle);
161 }
162
HandleCommand(int argc,char ** argv,struct UpdateMessage & boot,struct UpdaterPara & para)163 static int HandleCommand(int argc, char** argv, struct UpdateMessage& boot, struct UpdaterPara& para)
164 {
165 if (strcmp(argv[1], "bin") == 0) {
166 // 执行流式bin文件升级
167 return ExceptionBin(argc, argv, boot);
168 } else if (strcmp(argv[1], "updater") == 0) {
169 return ExceptionUpdater(argc, argv, boot);
170 } else if (strcmp(argv[1], "user_factory_reset") == 0) {
171 if (strncpy_s(boot.update, sizeof(boot.update), "--user_wipe_data", sizeof(boot.update) - 1) != 0) {
172 cout << "strncpy_s failed!" << endl;
173 return -1;
174 }
175 } else if (strcmp(argv[1], "boot_flash") == 0) {
176 if (strncpy_s(boot.update, sizeof(boot.update), "boot_flash", sizeof(boot.update) - 1) != 0) {
177 cout << "strncpy_s failed!" << endl;
178 return -1;
179 }
180 } else if (strcmp(argv[1], "clear") == 0) {
181 cout << "clear misc" << endl;
182 } else if (strcmp(argv[1], "sdcard_update") == 0) {
183 if (strncpy_s(boot.update, sizeof(boot.update), "--sdcard_update", sizeof(boot.update) - 1) != 0) {
184 cout << "strncpy_s failed!" << endl;
185 return -1;
186 }
187 } else if (strcmp(argv[1], "ota_intral_update") == 0) {
188 if (ExceptionUpdater(argc, argv, boot) == -1 ||
189 strcat_s(boot.update, sizeof(boot.update), "\n--ota_intral_update") != 0) {
190 return -1;
191 }
192 } else if (strcmp(argv[1], "subpkg_update") == 0) {
193 if (strncpy_s(boot.update, sizeof(boot.update), "--subpkg_update", sizeof(boot.update) - 1) != 0) {
194 cout << "strncpy_s failed!" << endl;
195 return -1;
196 }
197 } else if (strcmp(argv[1], "updater_para") == 0) {
198 return WriteUpdaterPara(argc, para) != 0 ? -1 : 0;
199 } else if (strcmp(argv[1], "notify_update") == 0) {
200 return 0;
201 } else {
202 cout << "Please input correct command!" << endl;
203 return -1;
204 }
205 return 0;
206 }
207
main(int argc,char ** argv)208 int main(int argc, char **argv)
209 {
210 if (argc == 1) {
211 PrintPrompts();
212 return -1;
213 }
214 const std::string miscFile = "/dev/block/by-name/misc";
215 struct UpdateMessage boot {};
216 struct UpdaterPara para {};
217
218 int cmdResult = HandleCommand(argc, argv, boot, para);
219 if (cmdResult == -1) {
220 cout << "HandleCommand failed!" << endl;
221 return -1;
222 }
223 if (strcmp(argv[1], "notify_update") != 0) {
224 bool ret = WriteUpdaterMessage(miscFile, boot);
225 if (!ret) {
226 cout << "WriteUpdaterMessage failed!" << endl;
227 return -1;
228 }
229 }
230 HandleMiscInfo(argc, argv);
231 _exit(-1);
232 return 0;
233 }
234