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