• 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 "updaterkits/updaterkits.h"
16 
17 #include <string>
18 #include <unistd.h>
19 #include "init_reboot.h"
20 #include "log.h"
21 #include "misc_info/misc_info.h"
22 #include "securec.h"
23 #include "utils.h"
24 
25 using namespace Updater;
26 using Updater::Utils::SplitString;
27 
WriteToMiscAndRebootToUpdater(const struct UpdateMessage & updateMsg)28 static bool WriteToMiscAndRebootToUpdater(const struct UpdateMessage &updateMsg)
29 {
30     // Write package name to misc, then trigger reboot.
31     const char *bootCmd = "boot_updater";
32     int ret = strncpy_s(const_cast<char*>(updateMsg.command), sizeof(updateMsg.command), bootCmd,
33         sizeof(updateMsg.command) - 1);
34     if (ret != 0) {
35         return false;
36     }
37 #ifndef UPDATER_UT
38     WriteUpdaterMiscMsg(updateMsg);
39     DoReboot("updater");
40     while (true) {
41         pause();
42     }
43 #else
44     return true;
45 #endif
46 }
47 
AddPkgPath(struct UpdateMessage & msg,size_t updateOffset,const std::vector<std::string> & packageName)48 static bool AddPkgPath(struct UpdateMessage &msg, size_t updateOffset, const std::vector<std::string> &packageName)
49 {
50     for (auto path : packageName) {
51         if (updateOffset > sizeof(msg.update)) {
52             LOG(ERROR) << "updaterkits: updateOffset > msg.update, return false";
53             return false;
54         }
55         int ret;
56         if (path.find("--force_update_action=") != std::string::npos) {
57             ret = snprintf_s(msg.update + updateOffset, sizeof(msg.update) - updateOffset,
58                 sizeof(msg.update) - 1 - updateOffset, "%s\n", path.c_str());
59         } else {
60             ret = snprintf_s(msg.update + updateOffset, sizeof(msg.update) - updateOffset,
61                 sizeof(msg.update) - 1 - updateOffset, "--update_package=%s\n", path.c_str());
62         }
63         if (ret < 0) {
64             LOG(ERROR) << "updaterkits: copy updater message failed";
65             return false;
66         }
67         updateOffset += static_cast<size_t>(ret);
68     }
69     return true;
70 }
71 
RebootAndInstallSdcardPackage(const std::string & miscFile,const std::vector<std::string> & packageName)72 bool RebootAndInstallSdcardPackage(const std::string &miscFile, const std::vector<std::string> &packageName)
73 {
74     struct UpdateMessage msg {};
75     int ret = snprintf_s(msg.update, sizeof(msg.update), sizeof(msg.update) - 1, "--sdcard_update\n");
76     if (ret < 0) {
77         LOG(ERROR) << "updaterkits: copy updater message failed";
78         return false;
79     }
80 
81     if (packageName.size() != 0 && !AddPkgPath(msg, static_cast<size_t>(ret), packageName)) {
82         LOG(ERROR) << "get sdcard pkg path fail";
83         return false;
84     }
85     WriteToMiscAndRebootToUpdater(msg);
86 
87     // Never get here.
88     return true;
89 }
90 
RebootAndInstallUpgradePackage(const std::string & miscFile,const std::vector<std::string> & packageName)91 bool RebootAndInstallUpgradePackage(const std::string &miscFile, const std::vector<std::string> &packageName)
92 {
93     if (packageName.size() == 0) {
94         LOG(ERROR) << "updaterkits: invalid argument. one of arugments is empty";
95         return false;
96     }
97 
98     for (auto path : packageName) {
99         if (path.find("--force_update_action=") != std::string::npos) {
100             continue;
101         }
102         if (access(path.c_str(), R_OK) < 0) {
103             LOG(ERROR) << "updaterkits: " << path << " is not readable";
104             return false;
105         }
106     }
107     struct UpdateMessage updateMsg {};
108     if (!AddPkgPath(updateMsg, 0, packageName)) {
109         return false;
110     }
111 
112     WriteToMiscAndRebootToUpdater(updateMsg);
113 
114     // Never get here.
115     return true;
116 }
117 
RebootAndCleanUserData(const std::string & miscFile,const std::string & cmd)118 bool RebootAndCleanUserData(const std::string &miscFile, const std::string &cmd)
119 {
120     if (miscFile.empty() || cmd.empty()) {
121         LOG(ERROR) << "updaterkits: invalid argument. one of arugments is empty";
122         return false;
123     }
124 
125     // Write package name to misc, then trigger reboot.
126     struct UpdateMessage updateMsg {};
127     if (strncpy_s(updateMsg.update, sizeof(updateMsg.update), cmd.c_str(), cmd.size()) != EOK) {
128         LOG(ERROR) << "updaterkits: copy updater message failed";
129         return false;
130     }
131 
132     WriteToMiscAndRebootToUpdater(updateMsg);
133 
134     // Never get here.
135     return true;
136 }
137