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 "misc_info/misc_info.h"
17 #include <cstring>
18 #include "fs_manager/mount.h"
19 #include "log/log.h"
20 #include "securec.h"
21 #include "updater/updater_const.h"
22 
23 namespace Updater {
WriteUpdaterMessage(const std::string & path,const UpdateMessage & boot)24 bool WriteUpdaterMessage(const std::string &path, const UpdateMessage &boot)
25 {
26     char *realPath = realpath(path.c_str(), NULL);
27     if (realPath == nullptr) {
28         LOG(ERROR) << "realPath is NULL" << " : " << strerror(errno);
29         return false;
30     }
31     FILE* fp = fopen(realPath, "rb+");
32     free(realPath);
33     if (fp == nullptr) {
34         LOG(ERROR) << "WriteUpdaterMessage fopen failed" << " : " << strerror(errno);
35         return false;
36     }
37 
38     size_t ret = fwrite(&boot, sizeof(UpdateMessage), 1, fp);
39     if (ret != 1) {
40         LOG(ERROR) << "WriteUpdaterMessage fwrite failed" << " : " << strerror(errno);
41         fclose(fp);
42         return false;
43     }
44     if (fsync(fileno(fp)) == -1) {
45         LOG(ERROR) << "WriteUpdaterMessage fsync failed" << " : " << strerror(errno);
46     }
47 
48     int res = fclose(fp);
49     if (res != 0) {
50         LOG(ERROR) << "WriteUpdaterMessage fclose failed" << " : " << strerror(errno);
51         return false;
52     }
53     return true;
54 }
55 
ReadUpdaterMessage(const std::string & path,UpdateMessage & boot)56 bool ReadUpdaterMessage(const std::string &path, UpdateMessage &boot)
57 {
58     char *realPath = realpath(path.c_str(), NULL);
59     if (realPath == nullptr) {
60         LOG(ERROR) << "realPath is NULL" << " : " << strerror(errno);
61         return false;
62     }
63     FILE* fp = fopen(realPath, "rb");
64     free(realPath);
65     if (fp == nullptr) {
66         LOG(ERROR) << "ReadUpdaterMessage fopen failed" << " : " << strerror(errno);
67         return false;
68     }
69 
70     struct UpdateMessage tempBoot {};
71     size_t ret = fread(&tempBoot, sizeof(UpdateMessage), 1, fp);
72     if (ret != 1) {
73         LOG(ERROR) << "ReadUpdaterMessage fwrite failed" << " : " << strerror(errno);
74         fclose(fp);
75         return false;
76     }
77 
78     int res = fclose(fp);
79     if (res != 0) {
80         LOG(ERROR) << "ReadUpdaterMessage fclose failed" << " : " << strerror(errno);
81         return false;
82     }
83     if (memcpy_s(&boot, sizeof(UpdateMessage), &tempBoot, sizeof(UpdateMessage)) != EOK) {
84         LOG(ERROR) << "ReadUpdaterMessage memcpy failed" << " : " << strerror(errno);
85         return false;
86     }
87     return true;
88 }
89 
WriteUpdaterMiscMsg(const UpdateMessage & boot)90 bool WriteUpdaterMiscMsg(const UpdateMessage &boot)
91 {
92     auto path = GetBlockDeviceByMountPoint(MISC_PATH);
93     if (path.empty()) {
94         LOG(INFO) << "cannot get block device of partition";
95         path = MISC_FILE;
96     }
97     LOG(INFO) << "WriteUpdaterMiscMsg::misc path : " << path;
98     return WriteUpdaterMessage(path, boot);
99 }
100 
ReadUpdaterMiscMsg(UpdateMessage & boot)101 bool ReadUpdaterMiscMsg(UpdateMessage &boot)
102 {
103     auto path = GetBlockDeviceByMountPoint(MISC_PATH);
104     if (path.empty()) {
105         LOG(INFO) << "cannot get block device of partition";
106         path = MISC_FILE;
107     }
108     return ReadUpdaterMessage(path, boot);
109 }
110 
WriteUpdaterParaMisc(const UpdaterPara & para)111 bool WriteUpdaterParaMisc(const UpdaterPara &para)
112 {
113     auto path = GetBlockDeviceByMountPoint(MISC_PATH);
114     if (path.empty()) {
115         LOG(INFO) << "WriteUpdaterParaMisc cannot get block device of partition";
116         path = MISC_FILE;
117     }
118 
119     char *realPath = realpath(path.c_str(), NULL);
120     if (realPath == nullptr) {
121         LOG(ERROR) << "WriteUpdaterParaMisc realPath is NULL" << ":" << strerror(errno);
122         return false;
123     }
124     FILE *fp = fopen(realPath, "rb+");
125     free(realPath);
126     if (fp == nullptr) {
127         LOG(ERROR) << "WriteUpdaterParaMisc fopen failed" << ":" << strerror(errno);
128         return false;
129     }
130 
131     if (lseek(fileno(fp), MISC_UPDATER_PARA_OFFSET, SEEK_SET) == -1) {
132         LOG(ERROR) << "lseek fp failed";
133         fclose(fp);
134         return false;
135     }
136     size_t ret = fwrite(&para, sizeof(UpdaterPara), 1, fp);
137     if (ret != 1) {
138         LOG(ERROR) << "WriteUpdaterParaMisc fwrite failed" << " : " << strerror(errno);
139         fclose(fp);
140         return false;
141     }
142 
143     if (fsync(fileno(fp)) == -1) {
144         LOG(ERROR) << "WriteUpdaterParaMisc fsync failed" << " : " << strerror(errno);
145     }
146 
147     if (fclose(fp) != 0) {
148         LOG(ERROR) << "WriteUpdaterParaMisc fclose failed" << " : " << strerror(errno);
149     }
150     return true;
151 }
152 
ReadUpdaterParaMisc(UpdaterPara & para)153 bool ReadUpdaterParaMisc(UpdaterPara &para)
154 {
155     auto path = GetBlockDeviceByMountPoint(MISC_PATH);
156     if (path.empty()) {
157         LOG(INFO) << "ReadUpdaterParaMisc cannot get block device of partition";
158         path = MISC_FILE;
159     }
160 
161     char *realPath = realpath(path.c_str(), NULL);
162     if (realPath == nullptr) {
163         LOG(ERROR) << "ReadUpdaterParaMisc realPath is NULL" << ":" << strerror(errno);
164         return false;
165     }
166     FILE *fp = fopen(realPath, "rb");
167     free(realPath);
168     if (fp == nullptr) {
169         LOG(ERROR) << "ReadUpdaterParaMisc fopen failed" << ":" << strerror(errno);
170         return false;
171     }
172 
173     if (lseek(fileno(fp), MISC_UPDATER_PARA_OFFSET, SEEK_SET) == -1) {
174         LOG(ERROR) << "lseek fp failed";
175         fclose(fp);
176         return false;
177     }
178     size_t ret = fread(&para, sizeof(UpdaterPara), 1, fp);
179     if (ret != 1) {
180         LOG(ERROR) << "ReadUpdaterParaMisc fwrite failed" << " : " << strerror(errno);
181         fclose(fp);
182         return false;
183     }
184 
185     fclose(fp);
186     return true;
187 }
188 
ClearUpdaterParaMisc(void)189 void ClearUpdaterParaMisc(void)
190 {
191     struct UpdaterPara cleanPara {};
192     if (!WriteUpdaterParaMisc(cleanPara)) {
193         LOG(ERROR) << "Clear para including language of misc failed";
194     }
195 }
196 } // Updater
197