1//
2// Automated Testing Framework (atf)
3//
4// Copyright (c) 2007 The NetBSD Foundation, Inc.
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions
9// are met:
10// 1. Redistributions of source code must retain the above copyright
11//    notice, this list of conditions and the following disclaimer.
12// 2. Redistributions in binary form must reproduce the above copyright
13//    notice, this list of conditions and the following disclaimer in the
14//    documentation and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
30#if !defined(_ATF_CXX_FS_HPP_)
31#define _ATF_CXX_FS_HPP_
32
33extern "C" {
34#include <sys/types.h>
35}
36
37#include <map>
38#include <memory>
39#include <ostream>
40#include <set>
41#include <stdexcept>
42#include <string>
43
44extern "C" {
45#include "../../atf-c/detail/fs.h"
46}
47
48namespace atf {
49
50namespace io {
51class systembuf;
52} // namespace io
53
54namespace fs {
55
56// ------------------------------------------------------------------------
57// The "path" class.
58// ------------------------------------------------------------------------
59
60//!
61//! \brief A class to represent a path to a file.
62//!
63//! The path class represents the route to a file or directory in the
64//! file system.  All file manipulation operations use this class to
65//! represent their arguments as it takes care of normalizing user-provided
66//! strings and ensures they are valid.
67//!
68//! It is important to note that the file pointed to by a path need not
69//! exist.
70//!
71class path {
72    //!
73    //! \brief Internal representation of a path.
74    //!
75    atf_fs_path_t m_path;
76
77public:
78    //! \brief Constructs a new path from a user-provided string.
79    //!
80    //! This constructor takes a string, either provided by the program's
81    //! code or by the user and constructs a new path object.  The string
82    //! is normalized to not contain multiple delimiters together and to
83    //! remove any trailing one.
84    //!
85    //! The input string cannot be empty.
86    //!
87    explicit path(const std::string&);
88
89    //!
90    //! \brief Copy constructor.
91    //!
92    path(const path&);
93
94    //!
95    //! \brief Copy constructor.
96    //!
97    path(const atf_fs_path_t *);
98
99    //!
100    //! \brief Destructor for the path class.
101    //!
102    ~path(void);
103
104    //!
105    //! \brief Returns a pointer to a C-style string representing this path.
106    //!
107    const char* c_str(void) const;
108
109    //!
110    //! \brief Returns a pointer to the implementation data.
111    //!
112    const atf_fs_path_t* c_path(void) const;
113
114    //!
115    //! \brief Returns a string representing this path.
116    //! XXX Really needed?
117    //!
118    std::string str(void) const;
119
120    //!
121    //! \brief Returns the branch path of this path.
122    //!
123    //! Calculates and returns the branch path of this path.  In other
124    //! words, it returns what the standard ::dirname function would return.
125    //!
126    path branch_path(void) const;
127
128    //!
129    //! \brief Returns the leaf name of this path.
130    //!
131    //! Calculates and returns the leaf name of this path.  In other words,
132    //! it returns what the standard ::basename function would return.
133    //!
134    std::string leaf_name(void) const;
135
136    //!
137    //! \brief Checks whether this path is absolute or not.
138    //!
139    //! Returns a boolean indicating if this is an absolute path or not;
140    //! i.e. if it starts with a slash.
141    //!
142    bool is_absolute(void) const;
143
144    //!
145    //! \brief Checks whether this path points to the root directory or not.
146    //!
147    //! Returns a boolean indicating if this is path points to the root
148    //! directory or not.  The checks made by this are extremely simple (so
149    //! the results cannot always be trusted) but they are enough for our
150    //! modest sanity-checking needs.  I.e. "/../" could return false.
151    //!
152    bool is_root(void) const;
153
154    //!
155    //! \brief Converts the path to be absolute.
156    //!
157    //! \pre The path was not absolute.
158    //!
159    path to_absolute(void) const;
160
161    //!
162    //! \brief Assignment operator.
163    //!
164    path& operator=(const path&);
165
166    //!
167    //! \brief Checks if two paths are equal.
168    //!
169    bool operator==(const path&) const;
170
171    //!
172    //! \brief Checks if two paths are different.
173    //!
174    bool operator!=(const path&) const;
175
176    //!
177    //! \brief Concatenates a path with a string.
178    //!
179    //! Constructs a new path object that is the concatenation of the
180    //! left-hand path with the right-hand string.  The string is normalized
181    //! before the concatenation, and a path delimiter is introduced between
182    //! the two components if needed.
183    //!
184    path operator/(const std::string&) const;
185
186    //!
187    //! \brief Concatenates a path with another path.
188    //!
189    //! Constructs a new path object that is the concatenation of the
190    //! left-hand path with the right-hand one. A path delimiter is
191    //! introduced between the two components if needed.
192    //!
193    path operator/(const path&) const;
194
195    //!
196    //! \brief Checks if a path has to be sorted before another one
197    //!        lexicographically.
198    //!
199    bool operator<(const path&) const;
200};
201
202// ------------------------------------------------------------------------
203// The "file_info" class.
204// ------------------------------------------------------------------------
205
206class directory;
207
208//!
209//! \brief A class that contains information about a file.
210//!
211//! The file_info class holds information about an specific file that
212//! exists in the file system.
213//!
214class file_info {
215    atf_fs_stat_t m_stat;
216
217public:
218    //!
219    //! \brief The file's type.
220    //!
221    static const int blk_type;
222    static const int chr_type;
223    static const int dir_type;
224    static const int fifo_type;
225    static const int lnk_type;
226    static const int reg_type;
227    static const int sock_type;
228    static const int wht_type;
229
230    //!
231    //! \brief Constructs a new file_info based on a given file.
232    //!
233    //! This constructor creates a new file_info object and fills it with
234    //! the data returned by ::stat when run on the given file, which must
235    //! exist.
236    //!
237    explicit file_info(const path&);
238
239    //!
240    //! \brief The copy constructor.
241    //!
242    file_info(const file_info&);
243
244    //!
245    //! \brief The destructor.
246    //!
247    ~file_info(void);
248
249    //!
250    //! \brief Returns the device containing the file.
251    //!
252    dev_t get_device(void) const;
253
254    //!
255    //! \brief Returns the file's inode.
256    //!
257    ino_t get_inode(void) const;
258
259    //!
260    //! \brief Returns the file's permissions.
261    //!
262    mode_t get_mode(void) const;
263
264    //!
265    //! \brief Returns the file's size.
266    //!
267    off_t get_size(void) const;
268
269    //!
270    //! \brief Returns the file's type.
271    //!
272    int get_type(void) const;
273
274    //!
275    //! \brief Returns whether the file is readable by its owner or not.
276    //!
277    bool is_owner_readable(void) const;
278
279    //!
280    //! \brief Returns whether the file is writable by its owner or not.
281    //!
282    bool is_owner_writable(void) const;
283
284    //!
285    //! \brief Returns whether the file is executable by its owner or not.
286    //!
287    bool is_owner_executable(void) const;
288
289    //!
290    //! \brief Returns whether the file is readable by the users belonging
291    //! to its group or not.
292    //!
293    bool is_group_readable(void) const;
294
295    //!
296    //! \brief Returns whether the file is writable the users belonging to
297    //! its group or not.
298    //!
299    bool is_group_writable(void) const;
300
301    //!
302    //! \brief Returns whether the file is executable by the users
303    //! belonging to its group or not.
304    //!
305    bool is_group_executable(void) const;
306
307    //!
308    //! \brief Returns whether the file is readable by people different
309    //! than the owner and those belonging to the group or not.
310    //!
311    bool is_other_readable(void) const;
312
313    //!
314    //! \brief Returns whether the file is write by people different
315    //! than the owner and those belonging to the group or not.
316    //!
317    bool is_other_writable(void) const;
318
319    //!
320    //! \brief Returns whether the file is executable by people different
321    //! than the owner and those belonging to the group or not.
322    //!
323    bool is_other_executable(void) const;
324};
325
326// ------------------------------------------------------------------------
327// The "directory" class.
328// ------------------------------------------------------------------------
329
330//!
331//! \brief A class representing a file system directory.
332//!
333//! The directory class represents a group of files in the file system and
334//! corresponds to exactly one directory.
335//!
336class directory : public std::map< std::string, file_info > {
337public:
338    //!
339    //! \brief Constructs a new directory.
340    //!
341    //! Constructs a new directory object representing the given path.
342    //! The directory must exist at creation time as the contents of the
343    //! class are gathered from it.
344    //!
345    directory(const path&);
346
347    //!
348    //! \brief Returns the file names of the files in the directory.
349    //!
350    //! Returns the leaf names of all files contained in the directory.
351    //! I.e. the keys of the directory map.
352    //!
353    std::set< std::string > names(void) const;
354};
355
356// ------------------------------------------------------------------------
357// Free functions.
358// ------------------------------------------------------------------------
359
360//!
361//! \brief Checks if the given path exists.
362//!
363bool exists(const path&);
364
365//!
366//! \brief Looks for the given program in the PATH.
367//!
368//! Given a program name (without slashes) looks for it in the path and
369//! returns its full path name if found, otherwise an empty path.
370//!
371bool have_prog_in_path(const std::string&);
372
373//!
374//! \brief Checks if the given path exists, is accessible and is executable.
375//!
376bool is_executable(const path&);
377
378//!
379//! \brief Removes a given file.
380//!
381void remove(const path&);
382
383//!
384//! \brief Removes an empty directory.
385//!
386void rmdir(const path&);
387
388} // namespace fs
389} // namespace atf
390
391#endif // !defined(_ATF_CXX_FS_HPP_)
392