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 <ftw.h>
17 #include <sys/stat.h>
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <limits.h>
21 #include <pthread.h>
22 #include <unistd.h>
23 #include "functionalext.h"
24
25 #define TEST_PATH_DEPTH 5
26 #define TEST_FTW_PATH "/data/local/tmp/ftwPath"
27
28 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30 const int FAIL = -1;
fn(const char * file,const struct stat * sb,int flag)31 int fn(const char *file, const struct stat *sb, int flag)
32 {
33 return 0;
34 }
35
36 /**
37 * @tc.name : ftw_0100
38 * @tc.desc : Each parameter is valid and can traverse the directory tree.
39 * @tc.level : Level 0
40 */
ftw_0100()41 void ftw_0100()
42 {
43 int ret = -1;
44 ret = ftw(TEST_FTW_PATH, fn, 500);
45 EXPECT_NE("ftw_0100", ret, FAIL);
46 }
47
remove_directory(const char * path)48 void remove_directory(const char *path)
49 {
50 DIR *dir;
51 struct dirent *entry;
52 char filepath[PATH_MAX];
53
54 if (!(dir = opendir(path))) {
55 return;
56 }
57
58 while ((entry = readdir(dir)) != NULL) {
59 if (entry->d_type == DT_DIR) {
60 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
61 continue;
62 }
63
64 int result = snprintf(filepath, sizeof(filepath), "%s/%s", path, entry->d_name);
65 if (result >= sizeof(filepath)) {
66 t_error("%s error in snprintf! \n", __func__);
67 }
68 remove_directory(filepath);
69 } else {
70 int result = snprintf(filepath, sizeof(filepath), "%s/%s", path, entry->d_name);
71 if (result >= sizeof(filepath)) {
72 t_error("%s error in snprintf! \n", __func__);
73 }
74 if (remove(filepath) == -1) {
75 t_error("%s error in remove test nftw filepath! \n", __func__);
76 }
77 }
78 }
79
80 closedir(dir);
81
82 // Now we can remove the empty directory
83 if (rmdir(path) == -1) {
84 t_error("%s error in rmdir test nftw path! \n", __func__);
85 }
86 }
87
nftw_build_testfile(const char * path)88 void nftw_build_testfile(const char *path)
89 {
90 // Create directory
91 if (mkdir(path, 0755) == -1) {
92 t_error("%s error in mkdir test nftw path! %s \n", __func__, path);
93 return;
94 }
95
96 char file[PATH_MAX];
97 int result = snprintf(file, sizeof(file), "%s/normal_file.txt", path);
98 if (result >= sizeof(file)) {
99 t_error("%s error in snprintf! \n", __func__);
100 }
101 // Create plain file
102 int fd = open(file, O_WRONLY | O_CREAT, 0644);
103 if (fd == -1) {
104 t_error("%s error in open normal_file.txt! \n", __func__);
105 return;
106 }
107 close(fd);
108
109 result = snprintf(file, sizeof(file), "%s/non-executable_file.txt", path);
110 if (result >= sizeof(file)) {
111 t_error("%s error in snprintf! \n", __func__);
112 }
113 // Create non-executable file
114 fd = open(file, O_WRONLY | O_CREAT, 0666);
115 if (fd == -1) {
116 t_error("%s error in open normal_file.txt! \n", __func__);
117 return;
118 }
119 close(fd);
120
121 result = snprintf(file, sizeof(file), "%s/unauthorized_file.txt", path);
122 if (result >= sizeof(file)) {
123 t_error("%s error in snprintf! \n", __func__);
124 }
125 // Create unauthorized file
126 fd = open(file, O_WRONLY | O_CREAT, 0000);
127 if (fd == -1) {
128 t_error("%s error in open normal_file.txt! \n", __func__);
129 return;
130 }
131 close(fd);
132
133 result = snprintf(file, sizeof(file), "%s/.hidden_file.txt", path);
134 if (result >= sizeof(file)) {
135 t_error("%s error in snprintf! \n", __func__);
136 }
137 // Create Hidden Files
138 fd = open(file, O_WRONLY | O_CREAT, 0644);
139 if (fd == -1) {
140 t_error("%s error in open hidden_file.txt! \n", __func__);
141 return;
142 }
143 close(fd);
144
145 result = snprintf(file, sizeof(file), "%s/read_only_file.txt", path);
146 if (result >= sizeof(file)) {
147 t_error("%s error in snprintf! \n", __func__);
148 }
149 //Create Read-only files
150 fd = open(file, O_WRONLY | O_CREAT, 0444);
151 if (fd == -1) {
152 t_error("%s error in open read_only_file.txt! \n", __func__);
153 return;
154 }
155 close(fd);
156
157 result = snprintf(file, sizeof(file), "%s/symlink_to_normal_file", path);
158 if (result >= sizeof(file)) {
159 t_error("%s error in snprintf! \n", __func__);
160 }
161 // Create Symbolic links
162 if (symlink("normal_file.txt", file) == -1) {
163 t_error("%s error in open symlink_to_normal_file.txt! \n", __func__);
164 return;
165 }
166 }
167
nftw_build_testDir()168 void nftw_build_testDir()
169 {
170 nftw_build_testfile(TEST_FTW_PATH);
171 char path[PATH_MAX];
172 int result = snprintf(path, sizeof(path), "%s", TEST_FTW_PATH);
173 if (result >= sizeof(path)) {
174 t_error("%s error in snprintf! \n", __func__);
175 }
176 for (int i = 0 ; i < TEST_PATH_DEPTH ; i++) {
177 result = snprintf(path, sizeof(path), "%s/data", path);
178 if (result >= sizeof(path)) {
179 t_error("%s error in snprintf! \n", __func__);
180 }
181 nftw_build_testfile(path);
182 }
183 }
184
main(int argc,char * argv[])185 int main(int argc, char *argv[])
186 {
187 pthread_mutex_lock(&g_mutex);
188 nftw_build_testDir();
189 ftw_0100();
190 remove_directory(TEST_FTW_PATH);
191 pthread_mutex_unlock(&g_mutex);
192 return t_status;
193 }