Botan 3.0.0
Crypto and TLS for C&
filesystem.cpp
Go to the documentation of this file.
1/*
2* (C) 2015,2017,2019 Jack Lloyd
3* (C) 2015 Simon Warta (Kullo GmbH)
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/exceptn.h>
9#include <botan/internal/filesystem.h>
10#include <algorithm>
11#include <deque>
12#include <memory>
13#include <sstream>
14
15#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <dirent.h>
19 #include <functional>
20#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
21 #define NOMINMAX 1
22 #define _WINSOCKAPI_ // stop windows.h including winsock.h
23 #include <windows.h>
24#endif
25
26namespace Botan {
27
28namespace {
29
30#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
31
32std::vector<std::string> impl_readdir(std::string_view dir_path)
33 {
34 std::vector<std::string> out;
35 std::deque<std::string> dir_list;
36 dir_list.push_back(std::string(dir_path));
37
38 while(!dir_list.empty())
39 {
40 const std::string cur_path = dir_list[0];
41 dir_list.pop_front();
42
43 std::unique_ptr<DIR, std::function<int (DIR*)>> dir(::opendir(cur_path.c_str()), ::closedir);
44
45 if(dir)
46 {
47 while(struct dirent* dirent = ::readdir(dir.get()))
48 {
49 const std::string filename = dirent->d_name;
50 if(filename == "." || filename == "..")
51 continue;
52
53 std::ostringstream full_path_sstr;
54 full_path_sstr << cur_path << "/" << filename;
55 const std::string full_path = full_path_sstr.str();
56
57 struct stat stat_buf;
58
59 if(::stat(full_path.c_str(), &stat_buf) == -1)
60 continue;
61
62 if(S_ISDIR(stat_buf.st_mode))
63 dir_list.push_back(full_path);
64 else if(S_ISREG(stat_buf.st_mode))
65 out.push_back(full_path);
66 }
67 }
68 }
69
70 return out;
71 }
72
73#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
74
75std::vector<std::string> impl_win32(std::string_view dir_path)
76 {
77 std::vector<std::string> out;
78 std::deque<std::string> dir_list;
79 dir_list.push_back(std::string(dir_path));
80
81 while(!dir_list.empty())
82 {
83 const std::string cur_path = dir_list[0];
84 dir_list.pop_front();
85
86 WIN32_FIND_DATAA find_data;
87 HANDLE dir = ::FindFirstFileA((cur_path + "/*").c_str(), &find_data);
88
89 if(dir != INVALID_HANDLE_VALUE)
90 {
91 do
92 {
93 const std::string filename = find_data.cFileName;
94 if(filename == "." || filename == "..")
95 continue;
96 const std::string full_path = cur_path + "/" + filename;
97
98 if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
99 {
100 dir_list.push_back(full_path);
101 }
102 else
103 {
104 out.push_back(full_path);
105 }
106 }
107 while(::FindNextFileA(dir, &find_data));
108 }
109
110 ::FindClose(dir);
111 }
112
113 return out;
114}
115#endif
116
117}
118
120 {
121#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
122 return true;
123#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
124 return true;
125#else
126 return false;
127#endif
128 }
129
130std::vector<std::string> get_files_recursive(std::string_view dir)
131 {
132 std::vector<std::string> files;
133
134#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
135 files = impl_readdir(dir);
136#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
137 files = impl_win32(dir);
138#else
139 BOTAN_UNUSED(dir);
140 throw No_Filesystem_Access();
141#endif
142
143 std::sort(files.begin(), files.end());
144
145 return files;
146 }
147
148}
#define BOTAN_UNUSED(...)
Definition: assert.h:141
Definition: alg_id.cpp:12
bool has_filesystem_impl()
Definition: filesystem.cpp:119
std::vector< std::string > get_files_recursive(std::string_view dir)
Definition: filesystem.cpp:130