1 /*
2 * Copyright (c) 2023 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 "file_operator.h"
17 #include <cerrno>
18 #include <climits>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <fstream>
22 #include <sstream>
23 #include <string>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include "directory_ex.h"
28 #include "dlp_permission.h"
29 #include "dlp_permission_log.h"
30
31 namespace OHOS {
32 namespace Security {
33 namespace DlpPermission {
34 namespace {
35 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, SECURITY_DOMAIN_DLP_PERMISSION, "FileOperator" };
36 }
FileOperator()37 FileOperator::FileOperator() {}
38
~FileOperator()39 FileOperator::~FileOperator() {}
40
InputFileByPathAndContent(const std::string & path,const std::string & content)41 int32_t FileOperator::InputFileByPathAndContent(const std::string& path, const std::string& content)
42 {
43 std::string str = path;
44 str.erase(str.rfind('/'));
45 if (!IsExistDir(str)) {
46 DLP_LOG_INFO(LABEL, "dir not exist, str = %{public}s errCode %{public}d.", str.c_str(), errno);
47 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
48 }
49
50 char realPath[PATH_MAX] = {0};
51 (void)realpath(str.c_str(), realPath);
52
53 if (str.compare(realPath) != 0) {
54 DLP_LOG_INFO(LABEL, "path need to be canonical, str %{public}s realPath %{public}s.", str.c_str(), realPath);
55 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
56 }
57
58 FILE* fp = fopen(path.c_str(), "wb");
59 if (fp == nullptr) {
60 DLP_LOG_INFO(LABEL, "failed to open %{public}s, errno %{public}d.", path.c_str(), errno);
61 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
62 }
63 size_t num = fwrite(content.c_str(), sizeof(char), content.length(), fp);
64 if (num != content.length()) {
65 DLP_LOG_INFO(LABEL, "failed to fwrite %{public}s, errno %{public}d.", path.c_str(), errno);
66 fclose(fp);
67 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
68 }
69 if (fflush(fp) != 0) {
70 DLP_LOG_INFO(LABEL, "failed to fflush %{public}s, errno %{public}d.", path.c_str(), errno);
71 fclose(fp);
72 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
73 }
74 if (fsync(fileno(fp)) != 0) {
75 DLP_LOG_INFO(LABEL, "failed to fsync %{public}s, errno %{public}d.", path.c_str(), errno);
76 fclose(fp);
77 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
78 }
79 fclose(fp);
80 fp = nullptr;
81 // change mode
82 if (!ChangeModeFile(path, S_IRUSR | S_IWUSR)) {
83 DLP_LOG_INFO(LABEL, "failed to change mode for file %{public}s, errno %{public}d.", path.c_str(), errno);
84 }
85
86 return DLP_OK;
87 }
88
GetFileContentByPath(const std::string & path,std::string & content)89 int32_t FileOperator::GetFileContentByPath(const std::string& path, std::string& content)
90 {
91 char realPath[PATH_MAX] = {0};
92 if ((realpath(path.c_str(), realPath) == nullptr) && (errno != ENOENT)) {
93 DLP_LOG_ERROR(LABEL, "Realpath %{private}s failed, %{public}s.", path.c_str(), strerror(errno));
94 return DLP_RETENTION_FILE_FIND_FILE_ERROR;
95 }
96 if (!IsExistFile(realPath)) {
97 DLP_LOG_INFO(LABEL, "cannot find file, path = %{public}s", realPath);
98 return DLP_RETENTION_FILE_FIND_FILE_ERROR;
99 }
100 std::stringstream buffer;
101 std::ifstream i(realPath);
102 if (!i.is_open()) {
103 DLP_LOG_INFO(LABEL, "cannot open file %{public}s, errno %{public}d.", realPath, errno);
104 return DLP_RETENTION_COMMON_FILE_OPEN_FAILED;
105 }
106 buffer << i.rdbuf();
107 content = buffer.str();
108 i.close();
109 return DLP_OK;
110 }
111
IsExistFile(const std::string & path)112 bool FileOperator::IsExistFile(const std::string& path)
113 {
114 if (path.empty()) {
115 DLP_LOG_ERROR(LABEL, "path is empty");
116 return false;
117 }
118
119 struct stat buf = {};
120 if (stat(path.c_str(), &buf) != 0) {
121 DLP_LOG_ERROR(LABEL, "stat path: %{public}s, errno %{public}d.", path.c_str(), errno);
122 return false;
123 }
124
125 return S_ISREG(buf.st_mode);
126 }
127
IsExistDir(const std::string & path)128 bool FileOperator::IsExistDir(const std::string& path)
129 {
130 if (path.empty()) {
131 DLP_LOG_ERROR(LABEL, "path is empty");
132 return false;
133 }
134
135 struct stat buf = {};
136 if (stat(path.c_str(), &buf) != 0) {
137 DLP_LOG_ERROR(LABEL, "stat path: %{public}s, errno %{public}d.", path.c_str(), errno);
138 return false;
139 }
140
141 return S_ISDIR(buf.st_mode);
142 }
143 } // namespace DlpPermission
144 } // namespace Security
145 } // namespace OHOS
146