• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 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 "bundle_file_utils.h"
17 
18 #include <climits>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 
24 #include "bundle_daemon_log.h"
25 #include "securec.h"
26 
27 namespace OHOS {
IsExistDir(const char * path)28 bool BundleFileUtils::IsExistDir(const char *path)
29 {
30     if (path == nullptr) {
31         return false;
32     }
33 
34     struct stat buf = {};
35     if (stat(path, &buf) != 0) {
36         return false;
37     }
38     return S_ISDIR(buf.st_mode);
39 }
40 
IsExistFile(const char * file)41 bool BundleFileUtils::IsExistFile(const char *file)
42 {
43     if (file == nullptr) {
44         return false;
45     }
46 
47     struct stat buf = {};
48     if (stat(file, &buf) != 0) {
49         return false;
50     }
51     return S_ISREG(buf.st_mode);
52 }
53 
MkRecursiveDir(const char * dir,bool isReadOthers)54 bool BundleFileUtils::MkRecursiveDir(const char *dir, bool isReadOthers)
55 {
56     if (dir == nullptr) {
57         return false;
58     }
59     if (IsExistDir(dir)) {
60         return true;
61     }
62     size_t len = strlen(dir);
63     if (len == 0 || len > PATH_MAX) {
64         return false;
65     }
66     // Create directories level by level
67     char rootDir[PATH_MAX] = { '\0' };
68     for (size_t i = 0; i < len; ++i) {
69         rootDir[i] = dir[i];
70         if ((rootDir[i] == PATH_SEPARATOR || i == (len - 1)) && !IsExistDir(rootDir)) {
71             mode_t mode = S_IRWXU | S_IRWXG | S_IXOTH;
72             mode |= (isReadOthers ? S_IROTH : 0);
73             if (mkdir(rootDir, mode) < 0) {
74                 return false;
75             }
76         }
77     }
78     return true;
79 }
80 
RemoveFile(const char * path)81 bool BundleFileUtils::RemoveFile(const char *path)
82 {
83     if (IsExistFile(path)) {
84         return remove(path) == 0;
85     } else if (IsExistDir(path)) {
86         DIR *dir = opendir(path);
87         if (dir == nullptr) {
88             return false;
89         }
90         struct dirent *dp = nullptr;
91         // Remove file before delete the directory
92         while ((dp = readdir(dir)) != nullptr) {
93             if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
94                 continue;
95             }
96             std::string dirName = std::string(path) + "/" + dp->d_name;
97             if (dirName.length() >= PATH_MAX || !RemoveFile(dirName.c_str())) {
98                 closedir(dir);
99                 return false;
100             }
101         }
102         closedir(dir);
103         return remove(path) == 0;
104     } else {
105         return true;
106     }
107 }
108 
RenameFile(const char * oldFile,const char * newFile)109 bool BundleFileUtils::RenameFile(const char *oldFile, const char *newFile)
110 {
111     if (oldFile == nullptr || newFile == nullptr) {
112         return false;
113     }
114     if (!RemoveFile(newFile)) {
115         return false;
116     }
117 
118     return rename(oldFile, newFile) == 0;
119 }
120 
ChownFile(const char * file,int32_t uid,int32_t gid)121 bool BundleFileUtils::ChownFile(const char *file, int32_t uid, int32_t gid)
122 {
123     if (file == nullptr) {
124         return false;
125     }
126     return chown(file, uid, gid) == 0;
127 }
128 
WriteFile(const char * file,const void * buffer,uint32_t size)129 bool BundleFileUtils::WriteFile(const char *file, const void *buffer, uint32_t size)
130 {
131     if (file == nullptr || buffer == nullptr || size == 0) {
132         return false;
133     }
134 
135     int32_t fp = open(file, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWUSR | S_IRGRP | S_IROTH);
136     if (fp < 0) {
137         return false;
138     }
139 
140     if (write(fp, buffer, size) != static_cast<int32_t>(size)) {
141         close(fp);
142         return false;
143     }
144 
145     fsync(fp);
146     close(fp);
147     return true;
148 }
149 
IsValidPath(const std::string & rootDir,const std::string & path)150 bool BundleFileUtils::IsValidPath(const std::string &rootDir, const std::string &path)
151 {
152     if (rootDir.find(PATH_SEPARATOR) != 0 || rootDir.rfind(PATH_SEPARATOR) != (rootDir.size() - 1) ||
153         rootDir.find("..") != std::string::npos) {
154         return false;
155     }
156     if (path.find("..") != std::string::npos) {
157         return false;
158     }
159     return path.compare(0, rootDir.size(), rootDir) == 0;
160 }
161 
GetPathDir(const std::string & path)162 std::string BundleFileUtils::GetPathDir(const std::string &path)
163 {
164     std::size_t pos = path.rfind(PATH_SEPARATOR);
165     if (pos == std::string::npos) {
166         return std::string();
167     }
168     return path.substr(0, pos + 1);
169 }
170 } // OHOS
171