• 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 
16 #include "utils.h"
17 #include <algorithm>
18 #include <cerrno>
19 #include <cstdint>
20 #include <cstdlib>
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <limits>
24 #include <linux/reboot.h>
25 #include <string>
26 #include <sys/reboot.h>
27 #include <sys/stat.h>
28 #include <sys/syscall.h>
29 #include <unistd.h>
30 #include <vector>
31 #include "fs_manager/mount.h"
32 #include "init_reboot.h"
33 #include "log/log.h"
34 #include "misc_info/misc_info.h"
35 #ifdef WITH_SELINUX
36 #include <policycoreutils.h>
37 #include "selinux/selinux.h"
38 #endif
39 #include "package/pkg_manager.h"
40 #include "parameter.h"
41 #include "securec.h"
42 #include "updater/updater_const.h"
43 #include "scope_guard.h"
44 
45 namespace Updater {
46 using namespace Hpackage;
47 
48 namespace Utils {
49 constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4;
50 constexpr int MAX_TIME_SIZE = 20;
51 constexpr size_t PARAM_SIZE = 32;
52 constexpr const char *PREFIX_PARTITION_NODE = "/dev/block/by-name/";
53 constexpr mode_t DEFAULT_DIR_MODE = 0775;
54 constexpr long MAX_FILE_LENGTH = 4096;
55 
56 namespace {
UpdateInfoInMisc(const std::string headInfo,const std::optional<int> message,bool isRemove)57 void UpdateInfoInMisc(const std::string headInfo, const std::optional<int> message, bool isRemove)
58 {
59     if (headInfo.empty()) {
60         return;
61     }
62     std::vector<std::string> args = Utils::ParseParams(0, nullptr);
63     struct UpdateMessage msg {};
64     if (!ReadUpdaterMiscMsg(msg)) {
65         LOG(ERROR) << "SetMessageToMisc read misc failed";
66         return;
67     }
68 
69     (void)memset_s(msg.update, sizeof(msg.update), 0, sizeof(msg.update));
70     for (const auto& arg : args) {
71         if (arg.find(headInfo) == std::string::npos) {
72             if (strncat_s(msg.update, sizeof(msg.update), arg.c_str(), strlen(arg.c_str()) + 1) != EOK) {
73                 LOG(ERROR) << "SetMessageToMisc strncat_s failed";
74                 return;
75             }
76             if (strncat_s(msg.update, sizeof(msg.update), "\n", strlen("\n") + 1) != EOK) {
77                 LOG(ERROR) << "SetMessageToMisc strncat_s failed";
78                 return;
79             }
80         }
81     }
82     char buffer[128] {}; // 128 : set headInfo size
83     if (isRemove) {
84         LOG(INFO) << "remove --" << headInfo << " from misc";
85     } else if (!message.has_value()) {
86         if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "--%s", headInfo.c_str()) == -1) {
87             LOG(ERROR) << "SetMessageToMisc snprintf_s failed";
88             return;
89         }
90     } else {
91         if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "--%s=%d",
92             headInfo.c_str(), message.value()) == -1) {
93             LOG(ERROR) << "SetMessageToMisc snprintf_s failed";
94             return;
95         }
96     }
97     if (strncat_s(msg.update, sizeof(msg.update), buffer, strlen(buffer) + 1) != EOK) {
98         LOG(ERROR) << "SetMessageToMisc strncat_s failed";
99         return;
100     }
101     if (WriteUpdaterMiscMsg(msg) != true) {
102         LOG(ERROR) << "Write command to misc failed.";
103     }
104 }
105 } // namespace
106 
SaveLogs()107 void SaveLogs()
108 {
109     std::string updaterLogPath = std::string(UPDATER_LOG);
110     std::string stageLogPath = std::string(UPDATER_STAGE_LOG);
111 
112     // save logs
113     STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdaterLog";
114     bool ret = CopyUpdaterLogs(TMP_LOG, updaterLogPath);
115     if (!ret) {
116         LOG(ERROR) << "Copy updater log failed!";
117     }
118 
119     mode_t mode = 0660;
120 #ifndef __WIN32
121     SetFileAttributes(updaterLogPath, USER_UPDATE_AUTHORITY, GROUP_UPDATE_AUTHORITY, mode);
122 #endif
123 
124     STAGE(UPDATE_STAGE_SUCCESS) << "PostUpdater";
125     ret = CopyUpdaterLogs(TMP_STAGE_LOG, stageLogPath);
126     chmod(stageLogPath.c_str(), mode);
127     if (!ret) {
128         LOG(ERROR) << "Copy stage log failed!";
129     }
130 }
131 
DeleteFile(const std::string & filename)132 int32_t DeleteFile(const std::string& filename)
133 {
134     if (filename.empty()) {
135         LOG(ERROR) << "Invalid filename";
136         return -1;
137     }
138     if (unlink(filename.c_str()) == -1 && errno != ENOENT) {
139         LOG(ERROR) << "unlink " << filename << " failed";
140         return -1;
141     }
142     return 0;
143 }
144 
SplitString(const std::string & str,const std::string del)145 std::vector<std::string> SplitString(const std::string &str, const std::string del)
146 {
147     std::vector<std::string> result;
148     size_t found = std::string::npos;
149     size_t start = 0;
150     while (true) {
151         found = str.find_first_of(del, start);
152         result.push_back(str.substr(start, found - start));
153         if (found == std::string::npos) {
154             break;
155         }
156         start = found + 1;
157     }
158     return result;
159 }
160 
Trim(const std::string & str)161 std::string Trim(const std::string &str)
162 {
163     if (str.empty()) {
164         LOG(ERROR) << "str is empty";
165         return str;
166     }
167     size_t start = 0;
168     size_t end = str.size() - 1;
169     while (start < str.size()) {
170         if (!isspace(str[start])) {
171             break;
172         }
173         start++;
174     }
175     while (start < end) {
176         if (!isspace(str[end])) {
177             break;
178         }
179         end--;
180     }
181     if (end < start) {
182         return "";
183     }
184     return str.substr(start, end - start + 1);
185 }
186 
ConvertSha256Hex(const uint8_t * shaDigest,size_t length)187 std::string ConvertSha256Hex(const uint8_t* shaDigest, size_t length)
188 {
189     const std::string hexChars = "0123456789abcdef";
190     std::string haxSha256 = "";
191     unsigned int c;
192     for (size_t i = 0; i < length; ++i) {
193         auto d = shaDigest[i];
194         c = (d >> SHIFT_RIGHT_FOUR_BITS) & 0xf;     // last 4 bits
195         haxSha256.push_back(hexChars[c]);
196         haxSha256.push_back(hexChars[d & 0xf]);
197     }
198     return haxSha256;
199 }
200 
SetRebootMisc(const std::string & rebootTarget,const std::string & extData,struct UpdateMessage & msg)201 bool SetRebootMisc(const std::string& rebootTarget, const std::string &extData, struct UpdateMessage &msg)
202 {
203     static const int32_t maxCommandSize = 16;
204     int result = 0;
205     if (rebootTarget == "updater" && strcmp(msg.command, "boot_updater") != 0) {
206         result = strcpy_s(msg.command, maxCommandSize, "boot_updater");
207     } else if (rebootTarget == "flashd" && strcmp(msg.command, "flashd") != 0) {
208         result = strcpy_s(msg.command, maxCommandSize, "boot_flash");
209     } else if (rebootTarget == "bootloader" && strcmp(msg.command, "boot_loader") != 0) {
210         result = strcpy_s(msg.command, maxCommandSize, "boot_loader");
211     }
212     if (result != EOK) {
213         LOG(ERROR) << "reboot set misc strcpy failed";
214         return false;
215     }
216     msg.command[maxCommandSize] = 0;
217     if (extData.empty()) {
218         (void)memset_s(msg.update, sizeof(msg.update), 0, sizeof(msg.update));
219         return true;
220     }
221     if (strcpy_s(msg.update, sizeof(msg.update) - 1, extData.c_str()) != EOK) {
222         LOG(ERROR) << "failed to copy update";
223         return false;
224     }
225     msg.update[sizeof(msg.update) - 1] = 0;
226     return true;
227 }
228 
UpdaterDoReboot(const std::string & rebootTarget,const std::string & rebootReason,const std::string & extData)229 void UpdaterDoReboot(const std::string& rebootTarget, const std::string &rebootReason, const std::string &extData)
230 {
231     LOG(INFO) << ", rebootTarget: " << rebootTarget;
232     LOG(INFO) << ", rebootReason: " << rebootReason;
233     LoadFstab();
234     struct UpdateMessage msg = {};
235     if (rebootTarget.empty()) {
236         if (WriteUpdaterMiscMsg(msg) != true) {
237             LOG(INFO) << "UpdaterDoReboot: WriteUpdaterMessage empty error";
238         }
239     } else {
240         if (!ReadUpdaterMiscMsg(msg)) {
241             LOG(ERROR) << "UpdaterDoReboot read misc failed";
242         }
243         if (!SetRebootMisc(rebootTarget, extData, msg)) {
244             LOG(ERROR) << "UpdaterDoReboot set misc failed";
245         }
246         if (!WriteUpdaterMiscMsg(msg)) {
247             LOG(INFO) << "UpdaterDoReboot: WriteUpdaterMiscMsg error";
248         }
249     }
250     sync();
251 #ifndef UPDATER_UT
252     DoRebootExt(rebootTarget.c_str(), rebootReason.c_str());
253     while (true) {
254         pause();
255     }
256 #else
257     return;
258 #endif
259 }
260 
DoShutdown(const std::string & shutdownReason)261 void DoShutdown(const std::string &shutdownReason)
262 {
263     UpdateMessage msg = {};
264     if (!WriteUpdaterMiscMsg(msg)) {
265         LOG(ERROR) << "DoShutdown: WriteUpdaterMessage empty error";
266         return;
267     }
268     sync();
269     DoRebootExt("shutdown", shutdownReason.c_str());
270 }
271 
GetCertName()272 std::string GetCertName()
273 {
274 #ifndef UPDATER_UT
275     static std::string signingCertName = "/etc/certificate/signing_cert.crt";
276 #ifdef SIGN_ON_SERVER
277     signingCertName = Updater::Utils::ON_SERVER;
278 #endif
279 #else
280     static std::string signingCertName = "/data/updater/src/signing_cert.crt";
281 #endif
282     return signingCertName;
283 }
284 
WriteFully(int fd,const uint8_t * data,size_t size)285 bool WriteFully(int fd, const uint8_t *data, size_t size)
286 {
287     ssize_t written = 0;
288     size_t rest = size;
289 
290     while (rest > 0) {
291         do {
292             written = write(fd, data, rest);
293         } while (written < 0 && errno == EINTR);
294         if (written < 0) {
295             return false;
296         }
297         data += written;
298         rest -= static_cast<size_t>(written);
299         if (rest != 0) {
300             LOG(INFO) << "totalSize =  " << size << ", rest =  " << rest;
301         }
302     }
303     return true;
304 }
305 
ReadFully(int fd,void * data,size_t size)306 bool ReadFully(int fd, void *data, size_t size)
307 {
308     auto p = reinterpret_cast<uint8_t *>(data);
309     size_t remaining = size;
310     while (remaining > 0) {
311         ssize_t sread = read(fd, p, remaining);
312         if (sread == -1) {
313             LOG(ERROR) << "read failed: " << strerror(errno);
314             return false;
315         }
316         if (sread == 0) {
317             LOG(ERROR) << "read reached unexpected EOF";
318             return false;
319         }
320         p += sread;
321         remaining -= static_cast<size_t>(sread);
322     }
323     return true;
324 }
325 
ReadFileToString(int fd,std::string & content)326 bool ReadFileToString(int fd, std::string &content)
327 {
328     struct stat sb {};
329     if (fstat(fd, &sb) != -1 && sb.st_size > 0) {
330         content.resize(static_cast<size_t>(sb.st_size));
331     }
332     ssize_t n;
333     auto remaining = static_cast<size_t>(sb.st_size);
334     auto p = reinterpret_cast<char *>(content.data());
335     while (remaining > 0) {
336         n = read(fd, p, remaining);
337         if (n <= 0) {
338             return false;
339         }
340         p += n;
341         remaining -= static_cast<size_t>(n);
342     }
343     return true;
344 }
345 
ReadStringFromProcFile(const std::string & filePath,std::string & content)346 bool ReadStringFromProcFile(const std::string &filePath, std::string &content)
347 {
348     std::ifstream file(filePath.c_str());
349     if (!file.is_open()) {
350         LOG(ERROR) << "failed to open " << filePath <<  ", err: " << strerror(errno);
351         return false;
352     }
353 
354     file.seekg(0, std::ios::end);
355     const long fileLength = file.tellg();
356     if (fileLength > MAX_FILE_LENGTH) {
357         LOG(ERROR) << "file oversize " << fileLength << ", max is " << MAX_FILE_LENGTH;
358         return false;
359     }
360 
361     content.clear();
362     file.seekg(0, std::ios::beg);
363     std::copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(content));
364     return true;
365 }
366 
WriteStringToFile(int fd,const std::string & content)367 bool WriteStringToFile(int fd, const std::string& content)
368 {
369     const char *p = content.data();
370     size_t remaining = content.size();
371     while (remaining > 0) {
372         ssize_t n = write(fd, p, remaining);
373         if (n == -1) {
374             return false;
375         }
376         p += n;
377         remaining -= static_cast<size_t>(n);
378     }
379     return true;
380 }
381 
SyncFile(const std::string & dst)382 void SyncFile(const std::string &dst)
383 {
384     int fd = open(dst.c_str(), O_RDWR);
385     if (fd < 0) {
386         LOG(ERROR) << "open " << dst << " failed! err " << strerror(errno);
387         return;
388     }
389     fsync(fd);
390     close(fd);
391 }
392 
CopyFile(const std::string & src,const std::string & dest,bool isAppend)393 bool CopyFile(const std::string &src, const std::string &dest, bool isAppend)
394 {
395     char realPath[PATH_MAX + 1] = {0};
396     if (realpath(src.c_str(), realPath) == nullptr) {
397         LOG(ERROR) << src << " get realpath fail";
398         return false;
399     }
400 
401     std::ios_base::openmode mode = isAppend ? std::ios::app | std::ios::out : std::ios_base::out;
402     std::ifstream fin(realPath);
403     std::ofstream fout(dest, mode);
404     if (!fin.is_open() || !fout.is_open()) {
405         return false;
406     }
407 
408     fout << fin.rdbuf();
409     if (fout.fail()) {
410         fout.clear();
411         return false;
412     }
413     fout.flush();
414     fout.close();
415     SyncFile(dest); // no way to get fd from ofstream, so reopen to sync this file
416     return true;
417 }
418 
CopyDir(const std::string & srcPath,const std::string & dstPath)419 bool CopyDir(const std::string &srcPath, const std::string &dstPath)
420 {
421     DIR *dir = opendir(srcPath.c_str());
422     if (dir == nullptr) {
423         LOG(ERROR) << "opendir failed, path: " << srcPath.c_str() << ", err: " << strerror(errno);
424         return false;
425     }
426     ON_SCOPE_EXIT(closedir) {
427         closedir(dir);
428     };
429     bool existFlag = (access(dstPath.c_str(), 0) == 0);
430     if ((!existFlag) && (mkdir(dstPath.c_str(), DEFAULT_DIR_MODE) != 0)) {
431         LOG(ERROR) << "mkdir failed, path: " << dstPath.c_str() << ", err: " << strerror(errno);
432         return false;
433     }
434     ON_SCOPE_EXIT(rmdir) {
435         if (!existFlag) {
436             remove(dstPath.c_str());
437         }
438     };
439     dirent *dirent = nullptr;
440     while ((dirent = readdir(dir)) != nullptr) {
441         if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) {
442             continue;
443         }
444         if (dirent->d_type == DT_DIR) {
445             std::string fullSourcePath = srcPath + dirent->d_name + "/";
446             std::string fullDestPath = dstPath + dirent->d_name + "/";
447             if (!CopyDir(fullSourcePath, fullDestPath)) {
448                 LOG(ERROR) << "copydir failed, fullSourcePath: " << fullSourcePath.c_str()
449                           << ", fullDestPath: " << fullDestPath.c_str();
450                 return false;
451             }
452         } else {
453             std::string fullSourcePath = srcPath + dirent->d_name;
454             std::string fullDestPath = dstPath + dirent->d_name;
455             if (!CopyFile(fullSourcePath, fullDestPath)) {
456                 LOG(ERROR) << "copyfile failed, fullSourcePath: " << fullSourcePath.c_str()
457                           << ", fullDestPath: " << fullDestPath.c_str();
458                 return false;
459             }
460         }
461     }
462     CANCEL_SCOPE_EXIT_GUARD(rmdir);
463     return true;
464 }
465 
GetLocalBoardId()466 std::string GetLocalBoardId()
467 {
468     return "HI3516";
469 }
470 
CreateCompressLogFile(const std::string & pkgName,std::vector<std::pair<std::string,ZipFileInfo>> & files)471 int32_t CreateCompressLogFile(const std::string &pkgName, std::vector<std::pair<std::string, ZipFileInfo>> &files)
472 {
473     PkgInfo pkgInfo;
474     pkgInfo.signMethod = PKG_SIGN_METHOD_NONE;
475     pkgInfo.digestMethod = PKG_SIGN_METHOD_NONE;
476     pkgInfo.pkgType = PKG_PACK_TYPE_ZIP;
477     PkgManager::PkgManagerPtr pkgManager = PkgManager::CreatePackageInstance();
478     if (pkgManager == nullptr) {
479         LOG(ERROR) << "pkgManager is nullptr";
480         return -1;
481     }
482     int32_t ret = pkgManager->CreatePackage(pkgName, GetCertName(), &pkgInfo, files);
483     PkgManager::ReleasePackageInstance(pkgManager);
484     return ret;
485 }
486 
CompressFiles(std::vector<std::string> & files,const std::string & zipFile)487 void CompressFiles(std::vector<std::string> &files, const std::string &zipFile)
488 {
489     (void)DeleteFile(zipFile);
490     std::vector<std::pair<std::string, ZipFileInfo>> zipFiles {};
491     for (auto path : files) {
492         ZipFileInfo file {};
493         file.fileInfo.identity = path.substr(path.find_last_of("/") + 1);
494         file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
495         file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
496         zipFiles.push_back(std::pair<std::string, ZipFileInfo>(path, file));
497     }
498 
499     int32_t ret = CreateCompressLogFile(zipFile, zipFiles);
500     if (ret != 0) {
501         LOG(WARNING) << "CompressFiles failed: " << zipFile;
502         return;
503     }
504     mode_t mode = 0660;
505 #ifndef __WIN32
506     SetFileAttributes(zipFile, USER_UPDATE_AUTHORITY, GROUP_SYS_AUTHORITY, mode);
507 #endif
508 }
509 
CompressLogs(const std::string & logName)510 void CompressLogs(const std::string &logName)
511 {
512     std::vector<std::pair<std::string, ZipFileInfo>> files;
513     // Build the zip file to be packaged
514     std::vector<std::string> testFileNames;
515     std::string realName = logName.substr(logName.find_last_of("/") + 1);
516     std::string logPath = logName.substr(0, logName.find_last_of("/"));
517     testFileNames.push_back(realName);
518     for (auto name : testFileNames) {
519         ZipFileInfo file;
520         file.fileInfo.identity = name;
521         file.fileInfo.packMethod = PKG_COMPRESS_METHOD_ZIP;
522         file.fileInfo.digestMethod = PKG_DIGEST_TYPE_CRC;
523         std::string fileName = logName;
524         files.push_back(std::pair<std::string, ZipFileInfo>(fileName, file));
525     }
526 
527     char realTime[MAX_TIME_SIZE] = {0};
528     auto sysTime = std::chrono::system_clock::now();
529     auto currentTime = std::chrono::system_clock::to_time_t(sysTime);
530     struct tm *localTime = std::localtime(&currentTime);
531     if (localTime != nullptr) {
532         std::strftime(realTime, sizeof(realTime), "%Y%m%d%H%M%S", localTime);
533     }
534     char pkgName[MAX_LOG_NAME_SIZE];
535     if (snprintf_s(pkgName, MAX_LOG_NAME_SIZE, MAX_LOG_NAME_SIZE - 1,
536         "%s/%s_%s.zip", logPath.c_str(), realName.c_str(), realTime) == -1) {
537         return;
538     }
539     int32_t ret = CreateCompressLogFile(pkgName, files);
540     if (ret != 0) {
541         LOG(WARNING) << "CompressLogs failed";
542         return;
543     }
544     mode_t mode = 0660;
545 #ifndef __WIN32
546     SetFileAttributes(pkgName, USER_UPDATE_AUTHORITY, GROUP_SYS_AUTHORITY, mode);
547 #endif
548     sync();
549     if (access(pkgName, 0) != 0) {
550         LOG(ERROR) << "Failed to create zipfile: " << pkgName;
551     } else {
552         (void)DeleteFile(logName);
553     }
554 }
555 
GetFileSize(const std::string & filePath)556 size_t GetFileSize(const std::string &filePath)
557 {
558     size_t ret = 0;
559     std::ifstream ifs(filePath, std::ios::binary | std::ios::in);
560     if (ifs.is_open()) {
561         ifs.seekg(0, std::ios::end);
562         ret = static_cast<size_t>(ifs.tellg());
563     }
564     return ret;
565 }
566 
RestoreconPath(const std::string & path)567 bool RestoreconPath(const std::string &path)
568 {
569     if (MountForPath(path) != 0) {
570         LOG(ERROR) << "MountForPath " << path << " failed!";
571         return false;
572     }
573 #ifdef WITH_SELINUX
574     if (RestoreconRecurse(path.c_str()) == -1) {
575         LOG(WARNING) << "restore " << path << " failed";
576     }
577 #endif // WITH_SELINUX
578     if (UmountForPath(path) != 0) {
579         LOG(WARNING) << "UmountForPath " << path << " failed!";
580     }
581     return true;
582 }
583 
CopyUpdaterLogs(const std::string & sLog,const std::string & dLog)584 bool CopyUpdaterLogs(const std::string &sLog, const std::string &dLog)
585 {
586     std::size_t found = dLog.find_last_of("/");
587     if (found == std::string::npos) {
588         LOG(ERROR) << "Dest filePath error";
589         return false;
590     }
591     std::string destPath = dLog.substr(0, found);
592     if (MountForPath(destPath) != 0) {
593         LOG(WARNING) << "MountForPath /data/log failed!";
594     }
595 
596     if (access(destPath.c_str(), 0) != 0) {
597         if (MkdirRecursive(destPath.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
598             LOG(ERROR) << "MkdirRecursive error!";
599             return false;
600         }
601         #ifdef WITH_SELINUX
602             RestoreconRecurse(UPDATER_PATH);
603         #endif // WITH_SELINUX
604     }
605 
606     if (Utils::GetFileSize(sLog) > MAX_LOG_SIZE) {
607         LOG(ERROR) << "Size bigger for" << sLog;
608         STAGE(UPDATE_STAGE_FAIL) << "Log file error, unable to copy";
609         return false;
610     }
611 
612     while (Utils::GetFileSize(sLog) + GetDirSizeForFile(dLog) > MAX_LOG_DIR_SIZE) {
613         LOG(ERROR) << "Size bigger for" << sLog;
614         STAGE(UPDATE_STAGE_FAIL) << "sLog and dLog file error, unable to copy";
615         if (DeleteOldFile(destPath) != true) {
616             break;
617         }
618     }
619 
620     if (!CopyFile(sLog, dLog, true)) {
621         LOG(ERROR) << "copy log file failed.";
622         return false;
623     }
624     if (GetFileSize(dLog) >= MAX_LOG_SIZE) {
625         LOG(INFO) << "log size greater than 5M!";
626         CompressLogs(dLog);
627     }
628     sync();
629     return true;
630 }
631 
CheckResultFail()632 bool CheckResultFail()
633 {
634     std::ifstream ifs;
635     const std::string resultPath = std::string(UPDATER_PATH) + "/" + std::string(UPDATER_RESULT_FILE);
636     ifs.open(resultPath, std::ios::in);
637     std::string buff;
638     while (ifs.is_open() && getline(ifs, buff)) {
639         if (buff.find("fail|") != std::string::npos) {
640             ifs.close();
641             return true;
642         }
643     }
644     LOG(ERROR) << "open result file failed";
645     return false;
646 }
647 
WriteDumpResult(const std::string & result,const std::string & fileName)648 void WriteDumpResult(const std::string &result, const std::string &fileName)
649 {
650     if (access(UPDATER_PATH, 0) != 0) {
651         if (MkdirRecursive(UPDATER_PATH, 0755) != 0) { // 0755: -rwxr-xr-x
652             LOG(ERROR) << "MkdirRecursive error!";
653             return;
654         }
655     }
656     const std::string resultPath = std::string(UPDATER_PATH) + "/" + fileName;
657     FILE *fp = fopen(resultPath.c_str(), "w+");
658     if (fp == nullptr) {
659         LOG(ERROR) << "open result file failed";
660         return;
661     }
662     char buf[MAX_RESULT_BUFF_SIZE] = "Pass\n";
663     if (sprintf_s(buf, MAX_RESULT_BUFF_SIZE - 1, "%s\n", result.c_str()) < 0) {
664         LOG(WARNING) << "sprintf status fialed";
665     }
666     if (fwrite(buf, 1, strlen(buf) + 1, fp) <= 0) {
667         LOG(WARNING) << "write result file failed, err:" << errno;
668     }
669     if (fclose(fp) != 0) {
670         LOG(WARNING) << "close result file failed";
671     }
672 
673     (void)chown(resultPath.c_str(), USER_ROOT_AUTHORITY, GROUP_UPDATE_AUTHORITY);
674     (void)chmod(resultPath.c_str(), 0660); // 0660: -rw-rw----
675 }
676 
GetDirSize(const std::string & folderPath)677 long long int GetDirSize(const std::string &folderPath)
678 {
679     DIR* dir = opendir(folderPath.c_str());
680     if (dir == nullptr) {
681         LOG(ERROR) << "Failed to open folder: " << folderPath << std::endl;
682         return 0;
683     }
684 
685     struct dirent* entry;
686     long long int totalSize = 0;
687     while ((entry = readdir(dir)) != nullptr) {
688         std::string fileName = entry->d_name;
689         std::string filePath = folderPath + "/" + fileName;
690         struct stat fileStat;
691         if (stat(filePath.c_str(), &fileStat) != 0) {
692             LOG(ERROR) << "Failed to get file status: " << filePath << std::endl;
693             continue;
694         }
695         if (S_ISDIR(fileStat.st_mode)) {
696             if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
697                 continue;
698             }
699             std::string subFolderPath = filePath;
700             totalSize += GetDirSize(subFolderPath);
701         } else {
702             totalSize += fileStat.st_size;
703         }
704     }
705     closedir(dir);
706     return totalSize;
707 }
708 
GetDirSizeForFile(const std::string & filePath)709 long long int GetDirSizeForFile(const std::string &filePath)
710 {
711     std::size_t found = filePath.find_last_of("/");
712     if (found == std::string::npos) {
713         LOG(ERROR) << "filePath error";
714         return -1;
715     }
716     return GetDirSize(filePath.substr(0, found));
717 }
718 
DeleteOldFile(const std::string folderPath)719 bool DeleteOldFile(const std::string folderPath)
720 {
721     DIR* dir = opendir(folderPath.c_str());
722     if (dir == nullptr) {
723         LOG(ERROR) << "Failed to open folder: " << folderPath << std::endl;
724         return false;
725     }
726 
727     struct dirent* entry;
728     std::string oldestFilePath = "";
729     time_t oldestFileTime = std::numeric_limits<time_t>::max();
730     while ((entry = readdir(dir)) != nullptr) {
731         std::string fileName = entry->d_name;
732         std::string filePath = folderPath + "/" + fileName;
733         struct stat fileStat;
734         if (stat(filePath.c_str(), &fileStat) != 0) {
735             LOG(ERROR) << "Failed to get file status: " << filePath;
736             continue;
737         }
738         if (fileName == "." || fileName == "..") {
739             continue;
740         }
741         if (fileStat.st_mtime < oldestFileTime) {
742             oldestFileTime = fileStat.st_mtime;
743             oldestFilePath = filePath;
744         }
745     }
746     closedir(dir);
747     if (oldestFilePath.empty()) {
748         LOG(ERROR) << "Unable to delete file";
749         return false;
750     }
751     size_t size = GetFileSize(oldestFilePath);
752     if (remove(oldestFilePath.c_str()) != 0) {
753         LOG(ERROR) << "Failed to delete file: " << oldestFilePath;
754         return false;
755     }
756     LOG(INFO) << "Delete old file: " << oldestFilePath << " size: " << size;
757     return true;
758 }
759 
ParseParams(int argc,char ** argv)760 std::vector<std::string> ParseParams(int argc, char **argv)
761 {
762     struct UpdateMessage boot {};
763     // read from misc
764     if (!ReadUpdaterMiscMsg(boot)) {
765         LOG(ERROR) << "ReadUpdaterMessage MISC_FILE failed!";
766     }
767     // if boot.update is empty, read from command.The Misc partition may have dirty data,
768     // so strlen(boot.update) is not used, which can cause system exceptions.
769     if (boot.update[0] == '\0' && !access(COMMAND_FILE, 0)) {
770         if (!ReadUpdaterMessage(COMMAND_FILE, boot)) {
771             LOG(ERROR) << "ReadUpdaterMessage COMMAND_FILE failed!";
772         }
773     }
774 
775     boot.update[sizeof(boot.update) - 1] = '\0';
776     std::vector<std::string> parseParams = Utils::SplitString(boot.update, "\n");
777     if (argc != 0 && argv != nullptr) {
778         parseParams.insert(parseParams.begin(), argv, argv + argc);
779     }
780     return parseParams;
781 }
782 
TrimUpdateMode(const std::string & mode)783 std::string TrimUpdateMode(const std::string &mode)
784 {
785     std::string optEqual = "=";
786     std::string modePrefix = "--"; // misc = --update_package=xxxx / --sdcard_update
787     size_t optPos = mode.size();
788     size_t prefixPos = 0;
789     if (mode.empty() || mode == "") {
790         return "";
791     }
792     if (mode.find(optEqual) != std::string::npos) {
793         optPos = mode.find(optEqual);
794     }
795     if (mode.find(modePrefix) != std::string::npos) {
796         prefixPos = mode.find(modePrefix) + modePrefix.size();
797     }
798     if (optPos < prefixPos) {
799         return mode;
800     }
801     return mode.substr(prefixPos, optPos - prefixPos);
802 }
803 
CheckUpdateMode(const std::string & mode)804 bool CheckUpdateMode(const std::string &mode)
805 {
806     std::vector<std::string> args = ParseParams(0, nullptr);
807     for (const auto &arg : args) {
808         if (TrimUpdateMode(arg) == mode) {
809             return true;
810         }
811     }
812     return false;
813 }
814 
DurationToString(std::vector<std::chrono::duration<double>> & durations,std::size_t pkgPosition,int precision)815 std::string DurationToString(std::vector<std::chrono::duration<double>> &durations, std::size_t pkgPosition,
816     int precision)
817 {
818     if (pkgPosition >= durations.size()) {
819         LOG(ERROR) << "pkg position is " << pkgPosition << ", duration's size is " << durations.size();
820         return "0";
821     }
822     std::ostringstream oss;
823     oss << std::fixed << std::setprecision(precision) << durations[pkgPosition].count();
824     return oss.str();
825 }
826 
GetRealPath(const std::string & path)827 std::string GetRealPath(const std::string &path)
828 {
829     char realPath[PATH_MAX + 1] = {0};
830     auto ret = realpath(path.c_str(), realPath);
831     return (ret == nullptr) ? "" : ret;
832 }
833 
GetPartitionRealPath(const std::string & name)834 std::string GetPartitionRealPath(const std::string &name)
835 {
836     return GetRealPath(PREFIX_PARTITION_NODE + name);
837 }
838 
SetMessageToMisc(const std::string & miscCmd,const int message,const std::string headInfo)839 void SetMessageToMisc(const std::string &miscCmd, const int message, const std::string headInfo)
840 {
841     if (headInfo.empty()) {
842         return;
843     }
844     std::vector<std::string> args = ParseParams(0, nullptr);
845     struct UpdateMessage msg {};
846     if (!ReadUpdaterMiscMsg(msg)) {
847         LOG(ERROR) << "SetMessageToMisc read misc failed";
848         return;
849     }
850     (void)memset_s(msg.command, sizeof(msg.command), 0, sizeof(msg.command));
851     if (strncpy_s(msg.command, sizeof(msg.command), miscCmd.c_str(), miscCmd.size() + 1) != EOK) {
852         LOG(ERROR) << "SetMessageToMisc strncpy_s failed";
853         return;
854     }
855     (void)memset_s(msg.update, sizeof(msg.update), 0, sizeof(msg.update));
856     for (const auto& arg : args) {
857         if (arg.find(headInfo) == std::string::npos) {
858             if (strncat_s(msg.update, sizeof(msg.update), arg.c_str(), strlen(arg.c_str()) + 1) != EOK) {
859                 LOG(ERROR) << "SetMessageToMisc strncat_s failed";
860                 return;
861             }
862             if (strncat_s(msg.update, sizeof(msg.update), "\n", strlen("\n") + 1) != EOK) {
863                 LOG(ERROR) << "SetMessageToMisc strncat_s failed";
864                 return;
865             }
866         }
867     }
868     char buffer[128] {}; // 128 : set headInfo size
869     if (headInfo == "sdcard_update") {
870         if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "--%s", headInfo.c_str()) == -1) {
871             LOG(ERROR) << "SetMessageToMisc snprintf_s failed";
872             return;
873         }
874     } else {
875         if (snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "--%s=%d", headInfo.c_str(), message) == -1) {
876             LOG(ERROR) << "SetMessageToMisc snprintf_s failed";
877             return;
878         }
879     }
880     if (strncat_s(msg.update, sizeof(msg.update), buffer, strlen(buffer) + 1) != EOK) {
881         LOG(ERROR) << "SetMessageToMisc strncat_s failed";
882         return;
883     }
884     if (WriteUpdaterMiscMsg(msg) != true) {
885         LOG(ERROR) << "Write command to misc failed.";
886     }
887 }
888 
SetCmdToMisc(const std::string & miscCmd)889 void SetCmdToMisc(const std::string &miscCmd)
890 {
891     struct UpdateMessage msg {};
892     if (!ReadUpdaterMiscMsg(msg)) {
893         LOG(ERROR) << "SetMessageToMisc read misc failed";
894         return;
895     }
896 
897     (void)memset_s(msg.command, sizeof(msg.command), 0, sizeof(msg.command));
898     if (strncpy_s(msg.command, sizeof(msg.command), miscCmd.c_str(), miscCmd.size() + 1) != EOK) {
899         LOG(ERROR) << "SetMessageToMisc strncpy_s failed";
900         return;
901     }
902 
903     if (WriteUpdaterMiscMsg(msg) != true) {
904         LOG(ERROR) << "Write command to misc failed.";
905     }
906 }
907 
AddUpdateInfoToMisc(const std::string headInfo,const std::optional<int> message)908 void AddUpdateInfoToMisc(const std::string headInfo, const std::optional<int> message)
909 {
910     UpdateInfoInMisc(headInfo, message, false);
911 }
912 
RemoveUpdateInfoFromMisc(const std::string & headInfo)913 void RemoveUpdateInfoFromMisc(const std::string &headInfo)
914 {
915     UpdateInfoInMisc(headInfo, std::nullopt, true);
916 }
917 
SetFaultInfoToMisc(const std::string & faultInfo)918 void SetFaultInfoToMisc(const std::string &faultInfo)
919 {
920     struct UpdateMessage msg {};
921     if (!ReadUpdaterMiscMsg(msg)) {
922         LOG(ERROR) << "SetMessageToMisc read misc failed";
923         return;
924     }
925 
926     (void)memset_s(msg.faultinfo, sizeof(msg.faultinfo), 0, sizeof(msg.faultinfo));
927     if (strncpy_s(msg.faultinfo, sizeof(msg.faultinfo), faultInfo.c_str(), faultInfo.size() + 1) != EOK) {
928         LOG(ERROR) << "SetMessageToMisc strncpy_s failed";
929         return;
930     }
931 
932     if (WriteUpdaterMiscMsg(msg) != true) {
933         LOG(ERROR) << "Write fault info to misc failed.";
934     }
935 }
936 
CheckFaultInfo(const std::string & faultInfo)937 bool CheckFaultInfo(const std::string &faultInfo)
938 {
939     struct UpdateMessage msg = {};
940     if (!ReadUpdaterMiscMsg(msg)) {
941         LOG(ERROR) << "read misc data failed";
942         return false;
943     }
944 
945     if (strcmp(msg.faultinfo, faultInfo.c_str()) == 0) {
946         return true;
947     }
948     return false;
949 }
950 
GetTagValInStr(const std::string & str,const std::string & tag,std::string & val)951 void GetTagValInStr(const std::string &str, const std::string &tag, std::string &val)
952 {
953     if (str.find(tag + "=") != std::string::npos) {
954         val = str.substr(str.find("=") + 1, str.size() - str.find("="));
955     }
956 }
957 
IsValidHexStr(const std::string & str)958 bool IsValidHexStr(const std::string &str)
959 {
960     for (const auto &ch : str) {
961         if (isxdigit(ch) == 0) {
962             return false;
963         }
964     }
965     return true;
966 }
967 
TrimString(std::string & str)968 void TrimString(std::string &str)
969 {
970     auto pos = str.find_last_not_of("\r\n");
971     if (pos != std::string::npos) {
972         str.erase(pos + 1, str.size() - pos);
973     }
974 }
975 
IsEsDevice()976 bool IsEsDevice()
977 {
978     char deviceType[PARAM_SIZE + 1] = {0};
979     if (GetParameter("ohos.boot.chiptype", "", deviceType, sizeof(deviceType) - 1) <= 0) {
980         LOG(ERROR) << "get device type failed";
981         return false;
982     }
983     LOG(INFO) << "device type is " << deviceType;
984     if (strstr(deviceType, "_es") == nullptr) {
985         return false;
986     }
987     return true;
988 }
989 
ConvertToUnsignedLongLong(const std::string & str,uint64_t & value)990 bool ConvertToUnsignedLongLong(const std::string &str, uint64_t &value)
991 {
992     char *endPtr = nullptr;
993     errno = 0;
994 
995     value = std::strtoull(str.c_str(), &endPtr, 0);
996 #ifndef UPDATER_UT
997     if (endPtr == str.c_str() || *endPtr != '\0' || errno == ERANGE) {
998         LOG(ERROR) << "Convert string to uint64_t failed, str " << str << " converted to value " << value;
999         return false;
1000     }
1001 #endif
1002     return true;
1003 }
1004 
ConvertToLongLong(const std::string & str,int64_t & value)1005 bool ConvertToLongLong(const std::string &str, int64_t &value)
1006 {
1007     char *endPtr = nullptr;
1008     errno = 0;
1009 
1010     value = std::strtoll(str.c_str(), &endPtr, 10); // 10 : decimal scale
1011 #ifndef UPDATER_UT
1012     if (endPtr == str.c_str() || *endPtr != '\0' || errno == ERANGE) {
1013         LOG(ERROR) << "Convert string to int64_t failed, str " << str << " converted to value " << value;
1014         return false;
1015     }
1016 #endif
1017     return true;
1018 }
1019 
ConvertToLong(const std::string & str,int32_t & value)1020 bool ConvertToLong(const std::string &str, int32_t &value)
1021 {
1022     char *endPtr = nullptr;
1023     errno = 0;
1024 
1025     value = std::strtol(str.c_str(), &endPtr, 10); // 10 : decimal scale
1026 #ifndef UPDATER_UT
1027     if (endPtr == str.c_str() || *endPtr != '\0' || errno == ERANGE) {
1028         LOG(ERROR) << "Convert string to int32_t failed, str " << str << " converted to value " << value;
1029         return false;
1030     }
1031 #endif
1032     return true;
1033 }
1034 
ConvertToUnsignedLong(const std::string & str,uint32_t & value,int base)1035 bool ConvertToUnsignedLong(const std::string &str, uint32_t &value, int base)
1036 {
1037     char *endPtr = nullptr;
1038     errno = 0;
1039 
1040     value = std::strtoul(str.c_str(), &endPtr, base);
1041 #ifndef UPDATER_UT
1042     if (endPtr == str.c_str() || *endPtr != '\0' || errno == ERANGE) {
1043         LOG(ERROR) << "Convert string to uint32_t failed, str " << str << " converted to value " << value;
1044         return false;
1045     }
1046 #endif
1047     return true;
1048 }
1049 
ConvertToDouble(const std::string & str,double & value)1050 bool ConvertToDouble(const std::string &str, double &value)
1051 {
1052     char *endPtr = nullptr;
1053     errno = 0;
1054 
1055     value = std::strtod(str.c_str(), &endPtr);
1056 #ifndef UPDATER_UT
1057     if (endPtr == str.c_str() || *endPtr != '\0' || errno == ERANGE) {
1058         LOG(ERROR) << "Convert string to double failed, str " << str << " converted to value " << value;
1059         return false;
1060     }
1061 #endif
1062     return true;
1063 }
1064 
ConvertToFloat(const std::string & str,float & value)1065 bool ConvertToFloat(const std::string &str, float &value)
1066 {
1067     char *endPtr = nullptr;
1068     errno = 0;
1069 
1070     value = std::strtof(str.c_str(), &endPtr);
1071 #ifndef UPDATER_UT
1072     if (endPtr == str.c_str() || *endPtr != '\0' || errno == ERANGE) {
1073         LOG(ERROR) << "Convert string to float failed, str " << str << " converted to value " << value;
1074         return false;
1075     }
1076 #endif
1077     return true;
1078 }
1079 
IsVabDevice()1080 bool IsVabDevice()
1081 {
1082     char partType[PARAM_SIZE + 1] = {0};
1083     if (GetParameter("ohos.boot.update.partition_type", "", partType, sizeof(partType) - 1) <= 0) {
1084         LOG(ERROR) << "get part partition failed";
1085         return false;
1086     }
1087     LOG(INFO) << "device type is " << partType;
1088     return std::string(partType) == "vab";
1089 }
1090 
SetUpdateSlot(int setSlot)1091 bool SetUpdateSlot(int setSlot)
1092 {
1093     if (setSlot == -1) {
1094         LOG(ERROR) << "setSlot is invalid value";
1095         return false;
1096     }
1097     int tryNum = 3;
1098     std::string setSlotStr = std::to_string(setSlot);
1099     while (tryNum-- > 0) {
1100         if (SetParameter("update.part.slot", setSlotStr.c_str()) != 0) {
1101             LOG(ERROR) << "set update.part.slot fail";
1102             continue;
1103         }
1104         if (GetUpdateSlot() == setSlot) {
1105             LOG(INFO) << "set update.part.slot is " << setSlot;
1106             return true;
1107         }
1108         if (tryNum != 0) {
1109             sleep(1);
1110         }
1111     }
1112     return false;
1113 }
1114 
SetUpdateSuffix(std::string stringsuffix)1115 bool SetUpdateSuffix(std::string stringsuffix)
1116 {
1117     int tryNum = 3;
1118     while (tryNum-- > 0) {
1119         if (SetParameter("update.part.suffix", stringsuffix.c_str()) != 0) {
1120             LOG(ERROR) << "set update.part.suffix fail";
1121             continue;
1122         }
1123         if (strcmp(GetUpdateSuffix().c_str(), stringsuffix.c_str()) == 0) {
1124             LOG(INFO) << "set update.part.suffix is " << stringsuffix;
1125             return true;
1126         }
1127         if (tryNum != 0) {
1128             sleep(1);
1129         }
1130     }
1131     return false;
1132 }
1133 
GetUpdateSlot()1134 int GetUpdateSlot()
1135 {
1136     if (!IsVabDevice()) {
1137         return NOT_AB;
1138     }
1139     char paramValue[PARAM_SIZE + 1] = {0};
1140     if (GetParameter("update.part.slot", "", paramValue, sizeof(paramValue) - 1) <= 0) {
1141         LOG(ERROR) << "get update.part.slot failed";
1142         return -1;
1143     }
1144     int updateSlot = -1;
1145     if (!Utils::ConvertToLong(paramValue, updateSlot)) {
1146         LOG(ERROR) << "ConvertToLong failed";
1147         return -1;
1148     }
1149     return updateSlot;
1150 }
1151 
GetUpdateSuffix()1152 std::string GetUpdateSuffix()
1153 {
1154     char paramValue[PARAM_SIZE + 1] = {0};
1155     if (GetParameter("update.part.suffix", "", paramValue, sizeof(paramValue) - 1) <= 0) {
1156         LOG(ERROR) << "get update.part.suffix failed";
1157         return std::string(paramValue);
1158     }
1159     LOG(INFO) << "GetUpdateSuffix = " << paramValue;
1160     return std::string(paramValue);
1161 }
1162 
GetUpdateActiveSuffix()1163 std::string GetUpdateActiveSuffix()
1164 {
1165     char paramValue[PARAM_SIZE + 1] = {0};
1166     if (GetParameter("update.part.suffix", "", paramValue, sizeof(paramValue) - 1) <= 0) {
1167         LOG(ERROR) << "get update.part.suffix failed";
1168         return std::string(paramValue);
1169     }
1170     if (strcmp(paramValue, "_a") == 0) {
1171         strncpy_s(paramValue, sizeof(paramValue), "_b", sizeof("_b"));
1172     } else if (strcmp(paramValue, "_b") == 0) {
1173         strncpy_s(paramValue, sizeof(paramValue), "_a", sizeof("_a"));
1174     } else {
1175         LOG(ERROR) << "Unexpected suffix value: " << paramValue;
1176         return std::string(paramValue);
1177     }
1178     LOG(INFO) << "GetUpdateActiveSuffix = " << paramValue;
1179     return std::string(paramValue);
1180 }
1181 
GetAllTids(pid_t pid)1182 std::vector<pid_t> GetAllTids(pid_t pid)
1183 {
1184     std::vector<pid_t> tids;
1185     tids.push_back(pid);
1186     std::string pathName = std::string("/proc/").append(std::to_string(pid)).append("/task");
1187     char tmpPath[PATH_MAX + 1] = {0};
1188     if (realpath(pathName.c_str(), tmpPath) == nullptr || tmpPath[0] == '\0') {
1189         LOG(ERROR) << "realpath fail pathName:" << pathName;
1190         return tids;
1191     }
1192     DIR *dir = opendir(tmpPath);
1193     if (dir == nullptr) {
1194         LOG(ERROR) << "opendir fail pathName:" << pathName;
1195         return tids;
1196     }
1197     struct dirent *de = nullptr;
1198     while ((de = readdir(dir)) != nullptr) {
1199         if (!(de->d_type & DT_DIR) || !isdigit(de->d_name[0])) {
1200             continue;
1201         }
1202         int32_t temp = -1;
1203         if (!Utils::ConvertToLong(de->d_name, temp)) {
1204             LOG(ERROR) << "ConvertToLong failed";
1205             continue;
1206         }
1207         pid_t tid = static_cast<pid_t>(temp);
1208         if (tid > 0) {
1209             tids.push_back(tid);
1210         }
1211     }
1212     closedir(dir);
1213     return tids;
1214 }
1215 
VectorToString(const std::vector<pid_t> & pids)1216 std::string VectorToString(const std::vector<pid_t> &pids)
1217 {
1218     if (pids.empty()) {
1219         return "";
1220     }
1221     std::ostringstream oss;
1222     auto it = pids.begin();
1223     oss << *it++;
1224     while (it != pids.end()) {
1225         oss << "," << *it++;
1226     }
1227     return oss.str();
1228 }
1229 
1230 #ifndef __WIN32
SetFileAttributes(const std::string & file,uid_t owner,gid_t group,mode_t mode)1231 void SetFileAttributes(const std::string& file, uid_t owner, gid_t group, mode_t mode)
1232 {
1233 #ifdef WITH_SELINUX
1234     RestoreconRecurse(file.c_str());
1235 #endif // WITH_SELINUX
1236     if (chown(file.c_str(), USER_ROOT_AUTHORITY, GROUP_ROOT_AUTHORITY) != 0) {
1237         LOG(ERROR) << "Chown failed: " << file << " " << USER_ROOT_AUTHORITY << "," << GROUP_ROOT_AUTHORITY;
1238     }
1239     if (chmod(file.c_str(), mode) != EOK) {
1240         LOG(ERROR) << "chmod failed: " << file << " " << mode;
1241     }
1242     if (chown(file.c_str(), owner, group) != 0) {
1243         LOG(ERROR) << "Chown failed: " << file << " " << owner << "," << group;
1244     }
1245 }
1246 #endif
1247 } // Utils
InitLogger(const std::string & tag)1248 void __attribute__((weak)) InitLogger(const std::string &tag)
1249 {
1250     if (Utils::IsUpdaterMode()) {
1251         InitUpdaterLogger(tag, TMP_LOG, TMP_STAGE_LOG, TMP_ERROR_CODE_PATH);
1252     } else {
1253         InitUpdaterLogger(tag, SYS_INSTALLER_LOG, UPDATER_STAGE_LOG, ERROR_CODE_PATH);
1254     }
1255 }
1256 } // namespace Updater
1257