1/*
2 * Copyright (c) 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
16#include "test_common.h"
17#include <dirent.h>
18#include <unistd.h>
19#include <sys/stat.h>
20
21namespace OHOS {
22namespace Security {
23namespace SelinuxUnitTest {
24bool CreateDirectory(const std::string &path)
25{
26    std::string::size_type index = 0;
27    do {
28        std::string subPath;
29        index = path.find('/', index + 1);
30        if (index == std::string::npos) {
31            subPath = path;
32        } else {
33            subPath = path.substr(0, index);
34        }
35
36        if (access(subPath.c_str(), F_OK) != 0) {
37            if (mkdir(subPath.c_str(), S_IRWXU) != 0) {
38                return false;
39            }
40        }
41    } while (index != std::string::npos);
42
43    return access(path.c_str(), F_OK) == 0;
44}
45
46bool RemoveDirectory(const std::string &path)
47{
48    std::string curDir = ".";
49    std::string upDir = "..";
50    DIR *dirp;
51    struct dirent *dp;
52    struct stat dirStat;
53
54    if (access(path.c_str(), F_OK) != 0) {
55        return true;
56    }
57    int statRet = stat(path.c_str(), &dirStat);
58    if (statRet < 0) {
59        return false;
60    }
61
62    if (S_ISREG(dirStat.st_mode)) {
63        remove(path.c_str());
64    } else if (S_ISDIR(dirStat.st_mode)) {
65        dirp = opendir(path.c_str());
66        while ((dp = readdir(dirp)) != nullptr) {
67            if ((curDir == std::string(dp->d_name)) || (upDir == std::string(dp->d_name))) {
68                continue;
69            }
70            std::string dirName = path + "/" + std::string(dp->d_name);
71            RemoveDirectory(dirName.c_str());
72        }
73        closedir(dirp);
74        rmdir(path.c_str());
75    } else {
76        return false;
77    }
78    return true;
79}
80
81std::string GetDirectory(const std::string &path)
82{
83    std::string dir = "";
84    size_t index = path.rfind('/');
85    if (index != std::string::npos) {
86        dir = path.substr(0, index);
87    }
88    return dir;
89}
90
91bool CreateFile(const std::string &path)
92{
93    std::string dir = GetDirectory(path);
94    if (dir != "") {
95        if (!CreateDirectory(dir)) {
96            return false;
97        }
98    }
99
100    if (access(path.c_str(), F_OK) != 0) {
101        FILE *fp = fopen(path.c_str(), "w");
102        if (fp == nullptr) {
103            return false;
104        }
105        fclose(fp);
106    }
107
108    return access(path.c_str(), F_OK) == 0;
109}
110
111bool CopyFile(const std::string &src, const std::string &des)
112{
113    std::ifstream fin(src, std::ifstream::in || std::ifstream::binary);
114    if (!fin) {
115        return false;
116    }
117    std::ofstream fout(des, std::ofstream::out || std::ofstream::binary);
118    if (!fout) {
119        fin.close();
120        return false;
121    }
122    fout << fin.rdbuf();
123    if (!fout) {
124        fin.close();
125        fout.close();
126        return false;
127    }
128    fin.close();
129    fout.close();
130    return true;
131}
132
133bool WriteFile(const std::string &file, const std::vector<std::string> &info)
134{
135    std::ofstream fout(file, std::ofstream::out || std::ofstream::app);
136    if (!fout) {
137        return false;
138    }
139    for (auto i : info) {
140        fout << i << std::endl;
141    }
142    if (!fout) {
143        fout.close();
144        return false;
145    }
146    fout.close();
147    return true;
148}
149
150int RenameFile(const std::string &src, const std::string &des)
151{
152    return rename(src.c_str(), des.c_str());
153}
154
155std::string RunCommand(const std::string &command)
156{
157    std::string result = "";
158    FILE *file = popen(command.c_str(), "r");
159
160    if (file != nullptr) {
161        char commandResult[1024] = {0};
162        while ((fgets(commandResult, sizeof(commandResult), file)) != nullptr) {
163            result.append(commandResult);
164        }
165        pclose(file);
166        file = nullptr;
167    }
168    return result;
169}
170} // namespace SelinuxUnitTest
171} // namespace Security
172} // namespace OHOS
173