• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "account_file_operator.h"
16 #include <cerrno>
17 #include <cstdio>
18 #include <fstream>
19 #include <nlohmann/json.hpp>
20 #include <sstream>
21 #include <string>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #ifdef WITH_SELINUX
26 #include <policycoreutils.h>
27 #endif // WITH_SELINUX
28 #include "account_log_wrapper.h"
29 #include "directory_ex.h"
30 #include "hisysevent_adapter.h"
31 namespace OHOS {
32 namespace AccountSA {
AccountFileOperator()33 AccountFileOperator::AccountFileOperator()
34 {}
35 
~AccountFileOperator()36 AccountFileOperator::~AccountFileOperator()
37 {}
38 
CreateDir(const std::string & path)39 ErrCode AccountFileOperator::CreateDir(const std::string &path)
40 {
41     ACCOUNT_LOGD("enter");
42 
43     if (!OHOS::ForceCreateDirectory(path)) {
44         ACCOUNT_LOGE("failed to create %{public}s, errno %{public}d.", path.c_str(), errno);
45         return ERR_OSACCOUNT_SERVICE_FILE_CREATE_DIR_ERROR;
46     }
47     mode_t mode = S_IRWXU;
48     bool createFlag = OHOS::ChangeModeDirectory(path, mode);
49     if (!createFlag) {
50         ACCOUNT_LOGE("failed to change mode for %{public}s, errno %{public}d.", path.c_str(), errno);
51         return ERR_OSACCOUNT_SERVICE_FILE_CHANGE_DIR_MODE_ERROR;
52     }
53 
54     return ERR_OK;
55 }
56 
DeleteDirOrFile(const std::string & path)57 ErrCode AccountFileOperator::DeleteDirOrFile(const std::string &path)
58 {
59     bool delFlag = false;
60     if (IsExistFile(path)) {
61         delFlag = OHOS::RemoveFile(path);
62     }
63     if (IsExistDir(path)) {
64         delFlag = OHOS::ForceRemoveDirectory(path);
65     }
66     if (!delFlag) {
67         ACCOUNT_LOGE("DeleteDirOrFile failed, path %{public}s errno %{public}d.", path.c_str(), errno);
68         return ERR_OSACCOUNT_SERVICE_FILE_DELE_ERROR;
69     }
70 
71     return ERR_OK;
72 }
73 
InputFileByPathAndContent(const std::string & path,const std::string & content)74 ErrCode AccountFileOperator::InputFileByPathAndContent(const std::string &path, const std::string &content)
75 {
76     std::string str = path;
77     str.erase(str.rfind('/'));
78     if (!IsExistDir(str)) {
79         ErrCode errCode = CreateDir(str);
80         if (errCode != ERR_OK) {
81             ACCOUNT_LOGE("failed to create dir, str = %{public}s errCode %{public}d.", str.c_str(), errCode);
82             return errCode;
83         }
84     }
85     FILE *fp = fopen(path.c_str(), "wb");
86     if (fp == nullptr) {
87         ACCOUNT_LOGE("failed to open %{public}s, errno %{public}d.", path.c_str(), errno);
88         return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
89     }
90     size_t num = fwrite(content.c_str(), sizeof(char), content.length(), fp);
91     if (num != content.length()) {
92         ACCOUNT_LOGE("failed to fwrite %{public}s, errno %{public}d.", path.c_str(), errno);
93         fclose(fp);
94         return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
95     }
96     if (fflush(fp) != 0) {
97         ACCOUNT_LOGE("failed to fflush %{public}s, errno %{public}d.", path.c_str(), errno);
98         fclose(fp);
99         return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
100     }
101     if (fsync(fileno(fp)) != 0) {
102         ACCOUNT_LOGE("failed to fsync %{public}s, errno %{public}d.", path.c_str(), errno);
103         fclose(fp);
104         return ERR_ACCOUNT_COMMON_FILE_WRITE_FAILED;
105     }
106     fclose(fp);
107 #ifdef WITH_SELINUX
108     Restorecon(path.c_str());
109 #endif // WITH_SELINUX
110     // change mode
111     if (!ChangeModeFile(path, S_IRUSR | S_IWUSR)) {
112         ACCOUNT_LOGW("failed to change mode for file %{public}s, errno %{public}d.", path.c_str(), errno);
113     }
114 
115     return ERR_OK;
116 }
117 
GetFileContentByPath(const std::string & path,std::string & content)118 ErrCode AccountFileOperator::GetFileContentByPath(const std::string &path, std::string &content)
119 {
120     if (!IsExistFile(path)) {
121         ACCOUNT_LOGE("cannot find file, path = %{public}s", path.c_str());
122         return ERR_OSACCOUNT_SERVICE_FILE_FIND_FILE_ERROR;
123     }
124     std::stringstream buffer;
125     std::ifstream i(path);
126     if (!i.is_open()) {
127         ACCOUNT_LOGE("cannot open file %{public}s, errno %{public}d.", path.c_str(), errno);
128         return ERR_ACCOUNT_COMMON_FILE_OPEN_FAILED;
129     }
130     buffer << i.rdbuf();
131     content = buffer.str();
132     i.close();
133     return ERR_OK;
134 }
135 
IsExistFile(const std::string & path)136 bool AccountFileOperator::IsExistFile(const std::string &path)
137 {
138     if (path.empty()) {
139         return false;
140     }
141 
142     struct stat buf = {};
143     if (stat(path.c_str(), &buf) != 0) {
144         return false;
145     }
146 
147     return S_ISREG(buf.st_mode);
148 }
149 
IsJsonFormat(const std::string & path)150 bool AccountFileOperator::IsJsonFormat(const std::string &path)
151 {
152     std::ifstream fin(path);
153     if (!fin) {
154         return false;
155     }
156 
157     nlohmann::json jsonData = nlohmann::json::parse(fin, nullptr, false);
158     fin.close();
159     if (!jsonData.is_structured()) {
160         return false;
161     }
162     return true;
163 }
164 
IsJsonFileReady(const std::string & path)165 bool AccountFileOperator::IsJsonFileReady(const std::string &path)
166 {
167     return IsExistFile(path) && IsJsonFormat(path);
168 }
169 
IsExistDir(const std::string & path)170 bool AccountFileOperator::IsExistDir(const std::string &path)
171 {
172     if (path.empty()) {
173         return false;
174     }
175 
176     struct stat buf = {};
177     if (stat(path.c_str(), &buf) != 0) {
178         return false;
179     }
180 
181     return S_ISDIR(buf.st_mode);
182 }
183 }  // namespace AccountSA
184 }  // namespace OHOS
185