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