OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |
| 6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |
| 7 |
| 8 // This class is used to walk a filesystem. It will iterate over every file |
| 9 // on the same device as the file passed in the ctor. Directories will be |
| 10 // visited before their children. Children will be visited in no particular |
| 11 // order. |
| 12 |
| 13 // The iterator is a forward iterator. It's not random access nor can it be |
| 14 // decremented. |
| 15 |
| 16 // Note: If the iterator comes across a mount point where another filesystem |
| 17 // is mounted, that mount point will be present, but none of its children |
| 18 // will be. Technically the mount point is on the other filesystem (and |
| 19 // the Stat() call will verify that), but we return it anyway since: |
| 20 // 1. Such a folder must exist in the first filesystem if it got used |
| 21 // as a mount point. |
| 22 // 2. You probably want to copy if it you're using the iterator to do a |
| 23 // filesystem copy |
| 24 // 3. If you don't want that, you can just check Stat().st_dev and skip |
| 25 // foreign filesystems manually. |
| 26 |
| 27 #include <sys/stat.h> |
| 28 #include <sys/types.h> |
| 29 #include <dirent.h> |
| 30 #include <unistd.h> |
| 31 #include <string> |
| 32 #include <set> |
| 33 #include <vector> |
| 34 |
| 35 namespace chromeos_update_engine { |
| 36 |
| 37 class FilesystemIterator { |
| 38 public: |
| 39 FilesystemIterator(const std::string& path, |
| 40 const std::set<std::string>& excl_prefixes); |
| 41 |
| 42 ~FilesystemIterator(); |
| 43 |
| 44 // Returns stat struct for the current file. |
| 45 struct stat GetStat() const { |
| 46 return stbuf_; |
| 47 } |
| 48 |
| 49 // Returns full path for current file. |
| 50 std::string GetFullPath() const; |
| 51 |
| 52 // Returns the path that's part of the iterator. For example, if |
| 53 // the object were constructed by passing in "/foo/bar" and Path() |
| 54 // returns "/foo/bar/baz/bat.txt", IterPath would return |
| 55 // "/baz/bat.txt". When this object is on root (ie, the very first |
| 56 // path), IterPath will return "", otherwise the first character of |
| 57 // IterPath will be "/". |
| 58 std::string GetPartialPath() const; |
| 59 |
| 60 // Returns name for current file. |
| 61 std::string GetBasename() const { |
| 62 return names_.back(); |
| 63 } |
| 64 |
| 65 // Increments to the next file. |
| 66 void Increment(); |
| 67 |
| 68 // If we're at the end. If at the end, do not call Stat(), Path(), etc., |
| 69 // since this iterator currently isn't pointing to any file at all. |
| 70 bool IsEnd() const { |
| 71 return is_end_; |
| 72 } |
| 73 |
| 74 // Returns true if the iterator is in an error state. |
| 75 bool IsErr() const { |
| 76 return is_err_; |
| 77 } |
| 78 private: |
| 79 // Helper for Increment. |
| 80 void IncrementInternal(); |
| 81 |
| 82 // Returns true if path exists and it's a directory. |
| 83 bool DirectoryExists(const std::string& path); |
| 84 |
| 85 // In general (i.e., not midway through a call to Increment()), there is a |
| 86 // relationship between dirs_ and names_: dirs[i] == names_[i - 1]. |
| 87 // For example, say we are asked to iterate "/usr/local" and we're currently |
| 88 // at /usr/local/share/dict/words. dirs_ contains DIR* variables for the |
| 89 // dirs at: {"/usr/local", ".../share", ".../dict"} and names_ contains: |
| 90 // {"share", "dict", "words"}. root_path_ contains "/usr/local". |
| 91 // root_dev_ would be the dev for root_path_ |
| 92 // (and /usr/local/share/dict/words). stbuf_ would be the stbuf for |
| 93 // /usr/local/share/dict/words. |
| 94 |
| 95 // All opened directories. If this is empty, we're currently on the root, |
| 96 // but not descended into the root. |
| 97 // This will always contain the current directory and all it's ancestors |
| 98 // in root-to-leaf order. For more details, see comment above. |
| 99 std::vector<DIR*> dirs_; |
| 100 |
| 101 // The list of all filenames for the current path that we've descended into. |
| 102 std::vector<std::string> names_; |
| 103 |
| 104 // The device of the root path we've been asked to iterate. |
| 105 dev_t root_dev_; |
| 106 |
| 107 // The root path we've been asked to iteratate. |
| 108 std::string root_path_; |
| 109 |
| 110 // Exclude items w/ this prefix. |
| 111 std::set<std::string> excl_prefixes_; |
| 112 |
| 113 // The struct stat of the current file we're at. |
| 114 struct stat stbuf_; |
| 115 |
| 116 // Generally false; set to true when we reach the end of files to iterate |
| 117 // or error occurs. |
| 118 bool is_end_; |
| 119 |
| 120 // Generally false; set to true if an error occurrs. |
| 121 bool is_err_; |
| 122 }; |
| 123 |
| 124 } // namespace chromeos_update_engine |
| 125 |
| 126 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |
OLD | NEW |