11static BOOL make_file(
const char* base,
const char* name)
13 char path[512] = WINPR_C_ARRAY_INIT;
14 (void)_snprintf(path,
sizeof(path),
"%s/%s", base, name);
15 FILE* file = fopen(path,
"wb");
18 const BOOL ok = fputs(
"data", file) >= 0;
19 return (fclose(file) == 0) && ok;
22static BOOL make_dir(
const char* base,
const char* name)
24 char path[512] = WINPR_C_ARRAY_INIT;
25 (void)_snprintf(path,
sizeof(path),
"%s/%s", base, name);
26 return mkdir(path, 0700) == 0;
29static BOOL make_link(
const char* base,
const char* target,
const char* name)
31 char path[512] = WINPR_C_ARRAY_INIT;
32 (void)_snprintf(path,
sizeof(path),
"%s/%s", base, name);
33 return symlink(target, path) == 0;
36static BOOL exists(
const char* base,
const char* name)
38 struct stat st = WINPR_C_ARRAY_INIT;
39 char path[512] = WINPR_C_ARRAY_INIT;
40 (void)_snprintf(path,
sizeof(path),
"%s/%s", base, name);
41 return lstat(path, &st) == 0;
44static BOOL remove_below(
const char* base,
const char* name)
46 char path[512] = WINPR_C_ARRAY_INIT;
47 (void)_snprintf(path,
sizeof(path),
"%s/%s", base, name);
48 return winpr_RemoveDirectory_RecursiveA(path);
52static BOOL test_tree(
const char* base)
54 if (!make_dir(base,
"tree") || !make_dir(base,
"tree/sub") || !make_dir(base,
"tree/empty") ||
55 !make_file(base,
"tree/a") || !make_file(base,
"tree/sub/b"))
57 return remove_below(base,
"tree") && !exists(base,
"tree");
61static BOOL test_links_stay_out(
const char* base)
63 if (!make_dir(base,
"kept") || !make_file(base,
"kept/keep") || !make_file(base,
"keep2") ||
64 !make_dir(base,
"links") || !make_dir(base,
"links/sub") ||
65 !make_link(base,
"../kept",
"links/to-dir") ||
66 !make_link(base,
"../../kept",
"links/sub/deep") ||
67 !make_link(base,
"../keep2",
"links/to-file"))
70 return remove_below(base,
"links") && !exists(base,
"links") && exists(base,
"kept/keep") &&
71 exists(base,
"keep2");
75static BOOL test_named_link(
const char* base)
77 if (!make_link(base,
"kept",
"link"))
79 return remove_below(base,
"link") && !exists(base,
"link") && exists(base,
"kept/keep");
82int TestPathRemoveDirectoryRecursive(
int argc,
char* argv[])
88 char base[] =
"/tmp/TestPathRemoveDirectoryRecursive.XXXXXX";
93 (void)fprintf(stderr,
"a tree was not removed\n");
94 else if (!test_links_stay_out(base))
95 (
void)fprintf(stderr,
"a link inside was followed\n");
96 else if (!test_named_link(base))
97 (void)fprintf(stderr,
"the named link was followed\n");
101 (void)winpr_RemoveDirectory_RecursiveA(base);