• 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 
16 #define LOG_TAG "DirectoryUtils"
17 
18 #include "directory_utils.h"
19 #include <dirent.h>
20 #include <cstring>
21 #include "log_print.h"
22 #include "unistd.h"
23 
24 namespace OHOS {
25 namespace DistributedKv {
26 // change the mode of all files in the specified directory recursively.
ChangeModeFileOnly(const std::string & path,const mode_t & mode)27 bool DirectoryUtils::ChangeModeFileOnly(const std::string &path, const mode_t &mode)
28 {
29     ZLOGI("begin.");
30     std::string subPath;
31     bool ret = true;
32     DIR *dir = opendir(path.c_str());
33     if (dir == nullptr) {
34         return false;
35     }
36 
37     while (true) {
38         struct dirent *ptr = readdir(dir);
39         if (ptr == nullptr) {
40             break;
41         }
42 
43         // skip current directory and parent directory.
44         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
45             continue;
46         }
47 
48         subPath = IncludeDelimiterAtPathTail(path) + std::string(ptr->d_name);
49         if (ptr->d_type == DT_DIR) {
50             ret = ChangeModeFileOnly(subPath, mode);
51             continue;
52         }
53 
54         // change the mode of file only.
55         if ((access(subPath.c_str(), F_OK) == 0) && (ptr->d_type == DT_REG)) {
56             ZLOGD("[Von-Debug]change the file[%s] to mode[%d].", subPath.c_str(), mode);
57             if (!ChangeMode(subPath, mode)) {
58                 closedir(dir);
59                 ZLOGD("[Von-Debug]change the file[%s] to mode[%d] failed.", subPath.c_str(), mode);
60                 return false;
61             }
62         }
63     }
64     closedir(dir);
65     return ret;
66 }
67 
68 // change the mode of all subdirectories in the specified directory recursively.
ChangeModeDirOnly(const std::string & path,const mode_t & mode)69 bool DirectoryUtils::ChangeModeDirOnly(const std::string &path, const mode_t &mode)
70 {
71     ZLOGI("begin.");
72     std::string subPath;
73     bool ret = true;
74     DIR *dir = opendir(path.c_str());
75     if (dir == nullptr) {
76         return false;
77     }
78 
79     while (true) {
80         struct dirent *ptr = readdir(dir);
81         if (ptr == nullptr) {
82             break;
83         }
84 
85         // skip current directory and parent directory.
86         if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) {
87             continue;
88         }
89 
90         subPath = IncludeDelimiterAtPathTail(path) + std::string(ptr->d_name);
91         if (ptr->d_type == DT_DIR) {
92             ret = ChangeModeDirOnly(subPath, mode);
93             continue;
94         }
95 
96         // change the mode of directory only.
97         if ((access(subPath.c_str(), F_OK) == 0) && (ptr->d_type == DT_DIR)) {
98             ZLOGD("[Von-Debug]change the dir[%s] to mode[%d].", subPath.c_str(), mode);
99             if (!ChangeMode(subPath, mode)) {
100                 closedir(dir);
101                 ZLOGD("[Von-Debug]change the dir[%s] to mode[%d] failed.", subPath.c_str(), mode);
102                 return false;
103             }
104         }
105     }
106     closedir(dir);
107 
108     std::string currentPath = ExcludeDelimiterAtPathTail(path);
109     if (access(currentPath.c_str(), F_OK) == 0) {
110         if (!ChangeMode(currentPath, mode)) {
111             return false;
112         }
113     }
114     return ret;
115 }
116 
117 // create all subdirectories in the specified directory recursively.
CreateDirectory(const std::string & path)118 bool DirectoryUtils::CreateDirectory(const std::string &path)
119 {
120     std::string::size_type index = 0;
121     do {
122         std::string subPath;
123         index = path.find('/', index + 1);
124         if (index == std::string::npos) {
125             subPath = path;
126         } else {
127             subPath = path.substr(0, index);
128         }
129 
130         if (access(subPath.c_str(), F_OK) != 0) {
131             if (mkdir(subPath.c_str(), (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
132                 return false;
133             }
134         }
135     } while (index != std::string::npos);
136 
137     return access(path.c_str(), F_OK) == 0;
138 }
139 
140 // exclude separators '/' at the end of the path.
ExcludeDelimiterAtPathTail(const std::string & path)141 std::string DirectoryUtils::ExcludeDelimiterAtPathTail(const std::string &path)
142 {
143     if (path.rfind('/') != path.size() - 1) {
144         return path;
145     }
146 
147     if (!path.empty()) {
148         return path.substr(0, static_cast<int>(path.size()) - 1);
149     }
150 
151     return path;
152 }
153 
154 // include separators '/' at the end of the path.
IncludeDelimiterAtPathTail(const std::string & path)155 std::string DirectoryUtils::IncludeDelimiterAtPathTail(const std::string &path)
156 {
157     if (path.rfind('/') != path.size() - 1) {
158         return path + "/";
159     }
160 
161     return path;
162 }
163 } // namespace DistributedKv
164 } // namespace OHOS
165