1240116Smarcel// Copyright (c) 2007 The NetBSD Foundation, Inc.
2240116Smarcel// All rights reserved.
3240116Smarcel//
4240116Smarcel// Redistribution and use in source and binary forms, with or without
5240116Smarcel// modification, are permitted provided that the following conditions
6240116Smarcel// are met:
7240116Smarcel// 1. Redistributions of source code must retain the above copyright
8240116Smarcel//    notice, this list of conditions and the following disclaimer.
9240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright
10240116Smarcel//    notice, this list of conditions and the following disclaimer in the
11240116Smarcel//    documentation and/or other materials provided with the distribution.
12240116Smarcel//
13240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25240116Smarcel
26273929Sjmmv#if !defined(ATF_CXX_DETAIL_FS_HPP)
27273929Sjmmv#define ATF_CXX_DETAIL_FS_HPP
28240116Smarcel
29240116Smarcelextern "C" {
30240116Smarcel#include <sys/types.h>
31240116Smarcel}
32240116Smarcel
33240116Smarcel#include <map>
34240116Smarcel#include <memory>
35240116Smarcel#include <ostream>
36240116Smarcel#include <set>
37240116Smarcel#include <stdexcept>
38240116Smarcel#include <string>
39240116Smarcel
40240116Smarcelextern "C" {
41273929Sjmmv#include "atf-c/detail/fs.h"
42240116Smarcel}
43240116Smarcel
44240116Smarcelnamespace atf {
45240116Smarcel
46240116Smarcelnamespace io {
47240116Smarcelclass systembuf;
48240116Smarcel} // namespace io
49240116Smarcel
50240116Smarcelnamespace fs {
51240116Smarcel
52240116Smarcel// ------------------------------------------------------------------------
53240116Smarcel// The "path" class.
54240116Smarcel// ------------------------------------------------------------------------
55240116Smarcel
56240116Smarcel//!
57240116Smarcel//! \brief A class to represent a path to a file.
58240116Smarcel//!
59240116Smarcel//! The path class represents the route to a file or directory in the
60240116Smarcel//! file system.  All file manipulation operations use this class to
61240116Smarcel//! represent their arguments as it takes care of normalizing user-provided
62240116Smarcel//! strings and ensures they are valid.
63240116Smarcel//!
64240116Smarcel//! It is important to note that the file pointed to by a path need not
65240116Smarcel//! exist.
66240116Smarcel//!
67240116Smarcelclass path {
68240116Smarcel    //!
69240116Smarcel    //! \brief Internal representation of a path.
70240116Smarcel    //!
71240116Smarcel    atf_fs_path_t m_path;
72240116Smarcel
73240116Smarcelpublic:
74240116Smarcel    //! \brief Constructs a new path from a user-provided string.
75240116Smarcel    //!
76240116Smarcel    //! This constructor takes a string, either provided by the program's
77240116Smarcel    //! code or by the user and constructs a new path object.  The string
78240116Smarcel    //! is normalized to not contain multiple delimiters together and to
79240116Smarcel    //! remove any trailing one.
80240116Smarcel    //!
81240116Smarcel    //! The input string cannot be empty.
82240116Smarcel    //!
83240116Smarcel    explicit path(const std::string&);
84240116Smarcel
85240116Smarcel    //!
86240116Smarcel    //! \brief Copy constructor.
87240116Smarcel    //!
88240116Smarcel    path(const path&);
89240116Smarcel
90240116Smarcel    //!
91240116Smarcel    //! \brief Copy constructor.
92240116Smarcel    //!
93240116Smarcel    path(const atf_fs_path_t *);
94240116Smarcel
95240116Smarcel    //!
96240116Smarcel    //! \brief Destructor for the path class.
97240116Smarcel    //!
98240116Smarcel    ~path(void);
99240116Smarcel
100240116Smarcel    //!
101240116Smarcel    //! \brief Returns a pointer to a C-style string representing this path.
102240116Smarcel    //!
103240116Smarcel    const char* c_str(void) const;
104240116Smarcel
105240116Smarcel    //!
106240116Smarcel    //! \brief Returns a pointer to the implementation data.
107240116Smarcel    //!
108240116Smarcel    const atf_fs_path_t* c_path(void) const;
109240116Smarcel
110240116Smarcel    //!
111240116Smarcel    //! \brief Returns a string representing this path.
112240116Smarcel    //! XXX Really needed?
113240116Smarcel    //!
114240116Smarcel    std::string str(void) const;
115240116Smarcel
116240116Smarcel    //!
117240116Smarcel    //! \brief Returns the branch path of this path.
118240116Smarcel    //!
119240116Smarcel    //! Calculates and returns the branch path of this path.  In other
120240116Smarcel    //! words, it returns what the standard ::dirname function would return.
121240116Smarcel    //!
122240116Smarcel    path branch_path(void) const;
123240116Smarcel
124240116Smarcel    //!
125240116Smarcel    //! \brief Returns the leaf name of this path.
126240116Smarcel    //!
127240116Smarcel    //! Calculates and returns the leaf name of this path.  In other words,
128240116Smarcel    //! it returns what the standard ::basename function would return.
129240116Smarcel    //!
130240116Smarcel    std::string leaf_name(void) const;
131240116Smarcel
132240116Smarcel    //!
133240116Smarcel    //! \brief Checks whether this path is absolute or not.
134240116Smarcel    //!
135240116Smarcel    //! Returns a boolean indicating if this is an absolute path or not;
136240116Smarcel    //! i.e. if it starts with a slash.
137240116Smarcel    //!
138240116Smarcel    bool is_absolute(void) const;
139240116Smarcel
140240116Smarcel    //!
141240116Smarcel    //! \brief Checks whether this path points to the root directory or not.
142240116Smarcel    //!
143240116Smarcel    //! Returns a boolean indicating if this is path points to the root
144240116Smarcel    //! directory or not.  The checks made by this are extremely simple (so
145240116Smarcel    //! the results cannot always be trusted) but they are enough for our
146240116Smarcel    //! modest sanity-checking needs.  I.e. "/../" could return false.
147240116Smarcel    //!
148240116Smarcel    bool is_root(void) const;
149240116Smarcel
150240116Smarcel    //!
151240116Smarcel    //! \brief Converts the path to be absolute.
152240116Smarcel    //!
153240116Smarcel    //! \pre The path was not absolute.
154240116Smarcel    //!
155240116Smarcel    path to_absolute(void) const;
156240116Smarcel
157240116Smarcel    //!
158240116Smarcel    //! \brief Assignment operator.
159240116Smarcel    //!
160240116Smarcel    path& operator=(const path&);
161240116Smarcel
162240116Smarcel    //!
163240116Smarcel    //! \brief Checks if two paths are equal.
164240116Smarcel    //!
165240116Smarcel    bool operator==(const path&) const;
166240116Smarcel
167240116Smarcel    //!
168240116Smarcel    //! \brief Checks if two paths are different.
169240116Smarcel    //!
170240116Smarcel    bool operator!=(const path&) const;
171240116Smarcel
172240116Smarcel    //!
173240116Smarcel    //! \brief Concatenates a path with a string.
174240116Smarcel    //!
175240116Smarcel    //! Constructs a new path object that is the concatenation of the
176240116Smarcel    //! left-hand path with the right-hand string.  The string is normalized
177240116Smarcel    //! before the concatenation, and a path delimiter is introduced between
178240116Smarcel    //! the two components if needed.
179240116Smarcel    //!
180240116Smarcel    path operator/(const std::string&) const;
181240116Smarcel
182240116Smarcel    //!
183240116Smarcel    //! \brief Concatenates a path with another path.
184240116Smarcel    //!
185240116Smarcel    //! Constructs a new path object that is the concatenation of the
186240116Smarcel    //! left-hand path with the right-hand one. A path delimiter is
187240116Smarcel    //! introduced between the two components if needed.
188240116Smarcel    //!
189240116Smarcel    path operator/(const path&) const;
190240116Smarcel
191240116Smarcel    //!
192240116Smarcel    //! \brief Checks if a path has to be sorted before another one
193240116Smarcel    //!        lexicographically.
194240116Smarcel    //!
195240116Smarcel    bool operator<(const path&) const;
196240116Smarcel};
197240116Smarcel
198240116Smarcel// ------------------------------------------------------------------------
199240116Smarcel// The "file_info" class.
200240116Smarcel// ------------------------------------------------------------------------
201240116Smarcel
202240116Smarcelclass directory;
203240116Smarcel
204240116Smarcel//!
205240116Smarcel//! \brief A class that contains information about a file.
206240116Smarcel//!
207240116Smarcel//! The file_info class holds information about an specific file that
208240116Smarcel//! exists in the file system.
209240116Smarcel//!
210240116Smarcelclass file_info {
211240116Smarcel    atf_fs_stat_t m_stat;
212240116Smarcel
213240116Smarcelpublic:
214240116Smarcel    //!
215240116Smarcel    //! \brief The file's type.
216240116Smarcel    //!
217240116Smarcel    static const int blk_type;
218240116Smarcel    static const int chr_type;
219240116Smarcel    static const int dir_type;
220240116Smarcel    static const int fifo_type;
221240116Smarcel    static const int lnk_type;
222240116Smarcel    static const int reg_type;
223240116Smarcel    static const int sock_type;
224240116Smarcel    static const int wht_type;
225240116Smarcel
226240116Smarcel    //!
227240116Smarcel    //! \brief Constructs a new file_info based on a given file.
228240116Smarcel    //!
229240116Smarcel    //! This constructor creates a new file_info object and fills it with
230240116Smarcel    //! the data returned by ::stat when run on the given file, which must
231240116Smarcel    //! exist.
232240116Smarcel    //!
233240116Smarcel    explicit file_info(const path&);
234240116Smarcel
235240116Smarcel    //!
236240116Smarcel    //! \brief The copy constructor.
237240116Smarcel    //!
238240116Smarcel    file_info(const file_info&);
239240116Smarcel
240240116Smarcel    //!
241240116Smarcel    //! \brief The destructor.
242240116Smarcel    //!
243240116Smarcel    ~file_info(void);
244240116Smarcel
245240116Smarcel    //!
246240116Smarcel    //! \brief Returns the device containing the file.
247240116Smarcel    //!
248240116Smarcel    dev_t get_device(void) const;
249240116Smarcel
250240116Smarcel    //!
251240116Smarcel    //! \brief Returns the file's inode.
252240116Smarcel    //!
253240116Smarcel    ino_t get_inode(void) const;
254240116Smarcel
255240116Smarcel    //!
256240116Smarcel    //! \brief Returns the file's permissions.
257240116Smarcel    //!
258240116Smarcel    mode_t get_mode(void) const;
259240116Smarcel
260240116Smarcel    //!
261240116Smarcel    //! \brief Returns the file's size.
262240116Smarcel    //!
263240116Smarcel    off_t get_size(void) const;
264240116Smarcel
265240116Smarcel    //!
266240116Smarcel    //! \brief Returns the file's type.
267240116Smarcel    //!
268240116Smarcel    int get_type(void) const;
269240116Smarcel
270240116Smarcel    //!
271240116Smarcel    //! \brief Returns whether the file is readable by its owner or not.
272240116Smarcel    //!
273240116Smarcel    bool is_owner_readable(void) const;
274240116Smarcel
275240116Smarcel    //!
276240116Smarcel    //! \brief Returns whether the file is writable by its owner or not.
277240116Smarcel    //!
278240116Smarcel    bool is_owner_writable(void) const;
279240116Smarcel
280240116Smarcel    //!
281240116Smarcel    //! \brief Returns whether the file is executable by its owner or not.
282240116Smarcel    //!
283240116Smarcel    bool is_owner_executable(void) const;
284240116Smarcel
285240116Smarcel    //!
286240116Smarcel    //! \brief Returns whether the file is readable by the users belonging
287240116Smarcel    //! to its group or not.
288240116Smarcel    //!
289240116Smarcel    bool is_group_readable(void) const;
290240116Smarcel
291240116Smarcel    //!
292240116Smarcel    //! \brief Returns whether the file is writable the users belonging to
293240116Smarcel    //! its group or not.
294240116Smarcel    //!
295240116Smarcel    bool is_group_writable(void) const;
296240116Smarcel
297240116Smarcel    //!
298240116Smarcel    //! \brief Returns whether the file is executable by the users
299240116Smarcel    //! belonging to its group or not.
300240116Smarcel    //!
301240116Smarcel    bool is_group_executable(void) const;
302240116Smarcel
303240116Smarcel    //!
304240116Smarcel    //! \brief Returns whether the file is readable by people different
305240116Smarcel    //! than the owner and those belonging to the group or not.
306240116Smarcel    //!
307240116Smarcel    bool is_other_readable(void) const;
308240116Smarcel
309240116Smarcel    //!
310240116Smarcel    //! \brief Returns whether the file is write by people different
311240116Smarcel    //! than the owner and those belonging to the group or not.
312240116Smarcel    //!
313240116Smarcel    bool is_other_writable(void) const;
314240116Smarcel
315240116Smarcel    //!
316240116Smarcel    //! \brief Returns whether the file is executable by people different
317240116Smarcel    //! than the owner and those belonging to the group or not.
318240116Smarcel    //!
319240116Smarcel    bool is_other_executable(void) const;
320240116Smarcel};
321240116Smarcel
322240116Smarcel// ------------------------------------------------------------------------
323240116Smarcel// The "directory" class.
324240116Smarcel// ------------------------------------------------------------------------
325240116Smarcel
326240116Smarcel//!
327240116Smarcel//! \brief A class representing a file system directory.
328240116Smarcel//!
329240116Smarcel//! The directory class represents a group of files in the file system and
330240116Smarcel//! corresponds to exactly one directory.
331240116Smarcel//!
332240116Smarcelclass directory : public std::map< std::string, file_info > {
333240116Smarcelpublic:
334240116Smarcel    //!
335240116Smarcel    //! \brief Constructs a new directory.
336240116Smarcel    //!
337240116Smarcel    //! Constructs a new directory object representing the given path.
338240116Smarcel    //! The directory must exist at creation time as the contents of the
339240116Smarcel    //! class are gathered from it.
340240116Smarcel    //!
341240116Smarcel    directory(const path&);
342240116Smarcel
343240116Smarcel    //!
344240116Smarcel    //! \brief Returns the file names of the files in the directory.
345240116Smarcel    //!
346240116Smarcel    //! Returns the leaf names of all files contained in the directory.
347240116Smarcel    //! I.e. the keys of the directory map.
348240116Smarcel    //!
349240116Smarcel    std::set< std::string > names(void) const;
350240116Smarcel};
351240116Smarcel
352240116Smarcel// ------------------------------------------------------------------------
353240116Smarcel// Free functions.
354240116Smarcel// ------------------------------------------------------------------------
355240116Smarcel
356240116Smarcel//!
357240116Smarcel//! \brief Checks if the given path exists.
358240116Smarcel//!
359240116Smarcelbool exists(const path&);
360240116Smarcel
361240116Smarcel//!
362240116Smarcel//! \brief Looks for the given program in the PATH.
363240116Smarcel//!
364240116Smarcel//! Given a program name (without slashes) looks for it in the path and
365240116Smarcel//! returns its full path name if found, otherwise an empty path.
366240116Smarcel//!
367240116Smarcelbool have_prog_in_path(const std::string&);
368240116Smarcel
369240116Smarcel//!
370240116Smarcel//! \brief Checks if the given path exists, is accessible and is executable.
371240116Smarcel//!
372240116Smarcelbool is_executable(const path&);
373240116Smarcel
374240116Smarcel//!
375240116Smarcel//! \brief Removes a given file.
376240116Smarcel//!
377240116Smarcelvoid remove(const path&);
378240116Smarcel
379240116Smarcel//!
380240116Smarcel//! \brief Removes an empty directory.
381240116Smarcel//!
382240116Smarcelvoid rmdir(const path&);
383240116Smarcel
384240116Smarcel} // namespace fs
385240116Smarcel} // namespace atf
386240116Smarcel
387273929Sjmmv#endif // !defined(ATF_CXX_DETAIL_FS_HPP)
388