• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <chrono>
16 #include <dirent.h>
17 #include <fcntl.h>
18 #include <sys/mount.h>
19 #include <sys/stat.h>
20 #include <sys/statvfs.h>
21 
22 #include "applypatch/partition_record.h"
23 #include "flashd/flashd.h"
24 #include "log/log.h"
25 #include "misc_info/misc_info.h"
26 #include "package/pkg_manager.h"
27 #include "securec.h"
28 #include "updater/updater.h"
29 #include "updater/updater_const.h"
30 #include "updater_ui.h"
31 #include "utils.h"
32 
33 namespace Updater {
34 using namespace Hpackage;
35 using namespace Updater::Utils;
36 
DeleteUpdaterPath(const std::string & path)37 bool DeleteUpdaterPath(const std::string &path)
38 {
39     auto pDir = std::unique_ptr<DIR, decltype(&closedir)>(opendir(path.c_str()), closedir);
40     if (pDir == nullptr) {
41         LOG(INFO) << "Can not open dir";
42         return true;
43     }
44     struct dirent *dp = nullptr;
45     while ((dp = readdir(pDir.get())) != nullptr) {
46         std::string currentName(dp->d_name);
47         if (currentName[0] != '.' && (currentName.compare("log") != 0) &&
48             (currentName.compare(UPDATER_RESULT_FILE) != 0) &&
49             (currentName.compare(UPDATER_LOCALE_FILE) != 0)) {
50             std::string tmpName(path);
51             tmpName.append("/" + currentName);
52             if (IsDirExist(tmpName)) {
53                 DeleteUpdaterPath(tmpName);
54             }
55 #ifndef UPDATER_UT
56             remove(tmpName.c_str());
57 #endif
58         }
59     }
60     return true;
61 }
62 
ClearMisc()63 bool ClearMisc()
64 {
65     struct UpdateMessage cleanBoot {};
66     if (!WriteUpdaterMiscMsg(cleanBoot)) {
67         LOG(ERROR) << "ClearMisc clear boot message to misc failed";
68         return false;
69     }
70     auto miscBlockDev = GetBlockDeviceByMountPoint(MISC_PATH);
71     if (miscBlockDev.empty()) {
72         LOG(INFO) << "cannot get block device of partition";
73         miscBlockDev = MISC_FILE;
74     }
75     LOG(INFO) << "ClearMisc::misc path : " << miscBlockDev;
76     auto fp = std::unique_ptr<FILE, decltype(&fclose)>(fopen(miscBlockDev.c_str(), "rb+"), fclose);
77     if (fp == nullptr) {
78         LOG(ERROR) << "WriteVersionCode fopen failed" << " : " << strerror(errno);
79         return false;
80     }
81     if (fseek(fp.get(), PARTITION_RECORD_OFFSET, SEEK_SET) != 0) {
82         LOG(ERROR) << "ClearMisc fseek failed";
83         return false;
84     }
85     off_t clearOffset = 0;
86     if (fwrite(&clearOffset, sizeof(off_t), 1, fp.get()) != 1) {
87         LOG(ERROR) << "ClearMisc write misc initOffset 0 failed" << " : " << strerror(errno);
88         return false;
89     }
90 
91     struct PartitionRecordInfo cleanPartition {};
92     for (size_t tmpOffset = 0; tmpOffset < PARTITION_UPDATER_RECORD_MSG_SIZE; tmpOffset +=
93         sizeof(PartitionRecordInfo)) {
94         if (fseek(fp.get(), PARTITION_RECORD_START + tmpOffset, SEEK_SET) != 0) {
95             LOG(ERROR) << "ClearMisc fseek failed";
96             return false;
97         }
98         if (fwrite(&cleanPartition, sizeof(PartitionRecordInfo), 1, fp.get()) != 1) {
99             LOG(ERROR) << "ClearMisc write misc cleanPartition failed" << " : " << strerror(errno);
100             return false;
101         }
102     }
103     return true;
104 }
105 
IsSDCardExist(const std::string & sdcardPath)106 bool IsSDCardExist(const std::string &sdcardPath)
107 {
108     // Record system error codes.
109     int save_errno = errno;
110     struct stat st {};
111     if (stat(sdcardPath.c_str(), &st) < 0) {
112         return false;
113     } else {
114         errno = save_errno;
115         return true;
116     }
117 }
118 
PostUpdater(bool clearMisc)119 void PostUpdater(bool clearMisc)
120 {
121     STAGE(UPDATE_STAGE_BEGIN) << "PostUpdater";
122     std::string updaterLogPath = UPDATER_LOG;
123     std::string stageLogPath = UPDATER_STAGE_LOG;
124     std::string errorCodePath = ERROR_CODE_PATH;
125 
126     (void)SetupPartitions();
127     // clear update misc partition.
128     if (clearMisc) {
129         UPDATER_ERROR_CHECK_NOT_RETURN(ClearMisc() == true, "PostUpdater clear misc failed");
130     }
131     if (!access(COMMAND_FILE, 0)) {
132         UPDATER_ERROR_CHECK_NOT_RETURN(unlink(COMMAND_FILE) == 0, "Delete command failed");
133     }
134 
135     // delete updater tmp files
136     if (access(UPDATER_PATH, 0) == 0 && access(SDCARD_CARD_PATH, 0) != 0) {
137         UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(UPDATER_PATH), "DeleteUpdaterPath failed");
138     }
139     if (!access(SDCARD_CARD_PATH, 0)) {
140         UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(SDCARD_CARD_PATH), "Delete sdcard path failed");
141     }
142     if (access(Flashd::FLASHD_FILE_PATH, 0) == 0) {
143         UPDATER_ERROR_CHECK_NOT_RETURN(DeleteUpdaterPath(Flashd::FLASHD_FILE_PATH), "DeleteUpdaterPath failed");
144     }
145 
146     // save logs
147     bool ret = CopyUpdaterLogs(TMP_LOG, updaterLogPath);
148     UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy updater log failed!");
149     ret = CopyUpdaterLogs(TMP_ERROR_CODE_PATH, errorCodePath);
150     UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy error code log failed!");
151     ret = CopyUpdaterLogs(Flashd::FLASHD_HDC_LOG_PATH, UPDATER_HDC_LOG);
152     UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy error hdc log failed!");
153 
154     mode_t mode = 0640;
155     chmod(updaterLogPath.c_str(), mode);
156     chmod(UPDATER_HDC_LOG, mode);
157     chmod(errorCodePath.c_str(), mode);
158     STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdater";
159     ret = CopyUpdaterLogs(TMP_STAGE_LOG, stageLogPath);
160     chmod(stageLogPath.c_str(), mode);
161     UPDATER_ERROR_CHECK_NOT_RETURN(ret, "Copy stage log failed!");
162 }
163 
ParseParams(int argc,char ** argv)164 std::vector<std::string> ParseParams(int argc, char **argv)
165 {
166     struct UpdateMessage boot {};
167     // read from misc
168     if (!ReadUpdaterMiscMsg(boot)) {
169         LOG(ERROR) << "ReadUpdaterMessage MISC_FILE failed!";
170     }
171     // if boot.update is empty, read from command.The Misc partition may have dirty data,
172     // so strlen(boot.update) is not used, which can cause system exceptions.
173     if (boot.update[0] == '\0' && !access(COMMAND_FILE, 0)) {
174         if (!ReadUpdaterMessage(COMMAND_FILE, boot)) {
175             LOG(ERROR) << "ReadUpdaterMessage COMMAND_FILE failed!";
176         }
177     }
178     STAGE(UPDATE_STAGE_OUT) << "Init Params: " << boot.update;
179     std::vector<std::string> parseParams(argv, argv + argc);
180     boot.update[sizeof(boot.update) - 1] = '\0';
181     std::vector<std::string> parseParams1 = Utils::SplitString(boot.update, "\n");
182     parseParams.insert(parseParams.end(), parseParams1.begin(), parseParams1.end());
183     return parseParams;
184 }
185 
GetBootMode(int & mode)186 int GetBootMode(int &mode)
187 {
188 #ifndef UPDATER_UT
189     mode = BOOT_UPDATER;
190 #else
191     mode = BOOT_FLASHD;
192 #endif
193     struct UpdateMessage boot {};
194     // read from misc
195     bool ret = ReadUpdaterMiscMsg(boot);
196     if (!ret) {
197         return -1;
198     }
199 
200     LOG(INFO) << "GetBootMode, boot.update" << boot.update;
201     if (strncmp(boot.update, "boot_flash", strlen("boot_flash")) == 0) {
202         mode = BOOT_FLASHD;
203     }
204     return 0;
205 }
206 } // namespace Updater
207