1 /*
2 ** Copyright 2012-2013 Centreon
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 **
16 ** For more information : contact@centreon.com
17 */
18
19 #include "com/centreon/io/directory_entry.hh"
20 #include <dirent.h>
21 #include <unistd.h>
22 #include <cerrno>
23 #include <cstdlib>
24 #include <cstring>
25 #include "com/centreon/exceptions/basic.hh"
26
27 using namespace com::centreon::io;
28
29 /**
30 * Constructor.
31 *
32 * @param[in] path The directory path.
33 */
directory_entry(char const * path)34 directory_entry::directory_entry(char const* path) : _entry(path) {}
35
36 /**
37 * Constructor.
38 *
39 * @param[in] path The directory path.
40 */
directory_entry(std::string const & path)41 directory_entry::directory_entry(std::string const& path) : _entry(path) {}
42
43 /**
44 * Copy constructor.
45 *
46 * @param[in] right The object to copy.
47 */
directory_entry(directory_entry const & right)48 directory_entry::directory_entry(directory_entry const& right) {
49 _internal_copy(right);
50 }
51
52 /**
53 * Copy operator.
54 *
55 * @param[in] right The object to copy.
56 *
57 * @return This object.
58 */
operator =(directory_entry const & right)59 directory_entry& directory_entry::operator=(directory_entry const& right) {
60 _internal_copy(right);
61 return *this;
62 }
63
64 /**
65 * Equal operator.
66 *
67 * @param[in] right The object to compare.
68 *
69 * @return True if is the same object, owtherwise false.
70 */
operator ==(directory_entry const & right) const71 bool directory_entry::operator==(directory_entry const& right) const noexcept {
72 return _entry == right._entry;
73 }
74
75 /**
76 * Not equal operator.
77 *
78 * @param[in] right The object to compare.
79 *
80 * @return True if is not the same object, owtherwise false.
81 */
operator !=(directory_entry const & right) const82 bool directory_entry::operator!=(directory_entry const& right) const noexcept {
83 return !operator==(right);
84 }
85
86 /**
87 * Destructor.
88 */
~directory_entry()89 directory_entry::~directory_entry() noexcept {}
90
91 /**
92 * Get the current directory path.
93 *
94 * @return The current directory path.
95 */
current_path()96 std::string directory_entry::current_path() {
97 char* buffer(getcwd(NULL, 0));
98 if (!buffer)
99 throw(basic_error() << "current path failed");
100 std::string path(buffer);
101 free(buffer);
102 return path;
103 }
104
105 /**
106 * Get the directory information.
107 *
108 * @return The directory entry.
109 */
entry() const110 file_entry const& directory_entry::entry() const noexcept {
111 return _entry;
112 }
113
114 /**
115 * Get the list of all entry into a directory.
116 *
117 * @param[in] filter An optional filter.
118 *
119 * @return The file entry list.
120 */
entry_list(std::string const & filter)121 std::list<file_entry> const& directory_entry::entry_list(
122 std::string const& filter) {
123 _entry_lst.clear();
124 char const* filter_ptr(filter.empty() ? NULL : filter.c_str());
125
126 DIR* dir(opendir(_entry.path().c_str()));
127 if (!dir) {
128 char const* msg(strerror(errno));
129 throw(basic_error() << "open directory failed: " << msg);
130 }
131
132 dirent entry;
133 dirent* result;
134 while (true) {
135 if (readdir_r(dir, &entry, &result)) {
136 closedir(dir);
137 throw(basic_error() << "parse directory failed");
138 }
139 if (!result)
140 break;
141 if (!filter_ptr || _nmatch(entry.d_name, filter_ptr))
142 _entry_lst.push_back(file_entry(_entry.path() + "/" + entry.d_name));
143 }
144 closedir(dir);
145
146 return _entry_lst;
147 }
148
149 /**
150 * Internal copy.
151 *
152 * @param[in] right The object to copy.
153 */
_internal_copy(directory_entry const & right)154 void directory_entry::_internal_copy(directory_entry const& right) {
155 if (this != &right) {
156 _entry = right._entry;
157 _entry_lst = right._entry_lst;
158 }
159 }
160
161 /**
162 * Check if a string match a pattern.
163 *
164 * @param[in] str The string to check.
165 * @param[in] pattern The partter to match.
166 *
167 * @return 1 on success, otherwiswe 0.
168 */
_nmatch(char const * str,char const * pattern)169 int directory_entry::_nmatch(char const* str, char const* pattern) {
170 if (!*str && !*pattern)
171 return 1;
172 if (*str == *pattern)
173 return _nmatch(str + 1, pattern + 1);
174 return (*pattern == '*' ? (*str ? _nmatch(str + 1, pattern) : 0) +
175 _nmatch(str, pattern + 1)
176 : 0);
177 }
178