• 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 "pkg_utils.h"
16 #include <cstring>
17 #include <fcntl.h>
18 #include <iostream>
19 #include <sstream>
20 #include <sys/mman.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include "securec.h"
24 #include "utils.h"
25 
26 namespace hpackage {
27 constexpr int32_t MIN_YEAR = 80;
28 constexpr uint32_t TM_YEAR_BITS = 9;
29 constexpr uint32_t TM_MON_BITS = 5;
30 constexpr uint32_t TM_MIN_BITS = 5;
31 constexpr uint32_t TM_HOUR_BITS = 11;
32 constexpr uint32_t BYTE_SIZE = 8;
33 constexpr uint32_t MAX_MEM_SIZE = 1 << 29;
34 constexpr uint32_t SECOND_BUFFER = 2;
35 constexpr uint32_t THIRD_BUFFER = 3;
36 constexpr uint8_t SHIFT_RIGHT_FOUR_BITS = 4;
37 
38 using namespace updater::utils;
39 
GetFilePath(const std::string & fileName)40 std::string GetFilePath(const std::string &fileName)
41 {
42     int32_t pos = fileName.find_last_of('/');
43     if (pos < 0) {
44         pos = fileName.find_last_of('\\');
45     }
46     return fileName.substr(0, pos + 1);
47 }
48 
GetFileSize(const std::string & fileName)49 size_t GetFileSize(const std::string &fileName)
50 {
51     char *realPath = realpath(fileName.c_str(), NULL);
52     PKG_CHECK(realPath != nullptr, return 0, "realPath is null");
53     FILE *fp = fopen(realPath, "r");
54     free(realPath);
55     PKG_CHECK(fp != nullptr, return 0, "Invalid file %s", fileName.c_str());
56 
57     fseek(fp, 0, SEEK_END);
58     size_t size = ftell(fp);
59     fclose(fp);
60     // return file size in bytes
61     return size;
62 }
63 
GetName(const std::string & filePath)64 std::string GetName(const std::string &filePath)
65 {
66     return filePath.substr(filePath.find_last_of("/") + 1);
67 }
68 
CheckFile(const std::string & fileName)69 int32_t CheckFile(const std::string &fileName)
70 {
71     // Check if the directory of @fileName is exist or has write permission
72     // If not, Create the directory first.
73     std::string path = GetFilePath(fileName);
74     if (path.empty()) {
75         return PKG_SUCCESS;
76     }
77     if (access(path.c_str(), F_OK) == -1) {
78         mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
79     }
80     // If the path writable
81     int ret = access(path.c_str(), R_OK | W_OK);
82     PKG_CHECK(ret != -1, return PKG_NONE_PERMISSION, "file %s no permission ", fileName.c_str());
83     return PKG_SUCCESS;
84 }
85 
MapMemory(const std::string & fileName,size_t size)86 uint8_t *MapMemory(const std::string &fileName, size_t size)
87 {
88     PKG_CHECK(size <= MAX_MEM_SIZE, return nullptr, "Size bigger for alloc memory");
89     void *mappedData = nullptr;
90     // Map the file to memory
91     mappedData = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_POPULATE | MAP_ANON, -1, 0);
92     PKG_CHECK(mappedData != MAP_FAILED, return nullptr, "Failed to mmap file %s ", fileName.c_str());
93     return static_cast<uint8_t *>(mappedData);
94 }
95 
ReleaseMemory(uint8_t * memMap,size_t size)96 void ReleaseMemory(uint8_t *memMap, size_t size)
97 {
98     PKG_CHECK(size > 0 && memMap != nullptr, return, "Size must > 0");
99     // Flush memory and release memory.
100     msync(static_cast<void *>(memMap), size, MS_ASYNC);
101     munmap(memMap, size);
102 }
103 
GetCurrPath()104 std::string GetCurrPath()
105 {
106     std::string path;
107     char *buffer = getcwd(nullptr, 0);
108     PKG_CHECK(buffer != nullptr, return "./", "getcwd error");
109     path.assign(buffer);
110     free(buffer);
111     return path + "/";
112 }
113 
ExtraTimeAndDate(time_t when,uint16_t & date,uint16_t & time)114 void ExtraTimeAndDate(time_t when, uint16_t &date, uint16_t &time)
115 {
116     when = static_cast<time_t>((static_cast<unsigned long>(when) + 1) & (~1));
117     struct tm nowTime {};
118     localtime_r(&when, &nowTime);
119     int year = nowTime.tm_year;
120     if (year < MIN_YEAR) {
121         year = MIN_YEAR;
122     }
123     date = ((year - MIN_YEAR) << TM_YEAR_BITS) | ((nowTime.tm_mon + 1) << TM_MON_BITS) | nowTime.tm_mday;
124     time = (nowTime.tm_hour << TM_HOUR_BITS) | (nowTime.tm_min << TM_MIN_BITS) | (nowTime.tm_sec >> 1);
125 }
126 
ReadLE32(const uint8_t * buff)127 uint32_t ReadLE32(const uint8_t *buff)
128 {
129     PKG_CHECK(buff != nullptr, return 0, "buff is null");
130     size_t offset = 0;
131     uint32_t value32 = buff[0];
132     offset += BYTE_SIZE;
133     value32 += (buff[1] << offset);
134     offset +=  BYTE_SIZE;
135     value32 += (buff[SECOND_BUFFER] << offset);
136     offset += BYTE_SIZE;
137     value32 += (buff[THIRD_BUFFER] << offset);
138     return value32;
139 }
140 
ReadLE64(const uint8_t * buff)141 uint64_t ReadLE64(const uint8_t *buff)
142 {
143     PKG_CHECK(buff != nullptr, return 0, "buff is null");
144     uint32_t low = ReadLE32(buff);
145     uint32_t high = ReadLE32(buff + sizeof(uint32_t));
146     uint64_t value = ((static_cast<uint64_t>(high)) << (BYTE_SIZE * sizeof(uint32_t))) | low;
147     return value;
148 }
149 
WriteLE32(uint8_t * buff,uint32_t value)150 void WriteLE32(uint8_t *buff, uint32_t value)
151 {
152     PKG_CHECK(buff != nullptr, return, "buff is null");
153     size_t offset = 0;
154     buff[0] = static_cast<uint8_t>(value);
155     offset += BYTE_SIZE;
156     buff[1] = static_cast<uint8_t>(value >> offset);
157     offset += BYTE_SIZE;
158     buff[SECOND_BUFFER] = static_cast<uint8_t>(value >> offset);
159     offset += BYTE_SIZE;
160     buff[THIRD_BUFFER] = static_cast<uint8_t>(value >> offset);
161 }
162 
ReadLE16(const uint8_t * buff)163 uint16_t ReadLE16(const uint8_t *buff)
164 {
165     PKG_CHECK(buff != nullptr, return 0, "buff is null");
166     uint16_t value16 = buff[0];
167     value16 += (buff[1] << BYTE_SIZE);
168     return value16;
169 }
170 
WriteLE16(uint8_t * buff,uint16_t value)171 void WriteLE16(uint8_t *buff, uint16_t value)
172 {
173     PKG_CHECK(buff != nullptr, return, "buff is null");
174     buff[0] = static_cast<uint8_t>(value);
175     buff[1] = static_cast<uint8_t>(value >> BYTE_SIZE);
176 }
177 
ConvertShaHex(const std::vector<uint8_t> & shaDigest)178 std::string ConvertShaHex(const std::vector<uint8_t> &shaDigest)
179 {
180     const std::string hexChars = "0123456789abcdef";
181     std::string haxSha256 = "";
182     unsigned int c;
183     for (size_t i = 0; i < shaDigest.size(); ++i) {
184         auto d = shaDigest[i];
185         c = (d >> SHIFT_RIGHT_FOUR_BITS) & 0xf;     // last 4 bits
186         haxSha256.push_back(hexChars[c]);
187         haxSha256.push_back(hexChars[d & 0xf]);
188     }
189     return haxSha256;
190 }
191 } // namespace hpackage
192