Index: src/platform/update_engine/filesystem_iterator.h |
diff --git a/src/platform/update_engine/filesystem_iterator.h b/src/platform/update_engine/filesystem_iterator.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a1ba8af7ebc5d82fbd44edee4eb7ed3c9123b108 |
--- /dev/null |
+++ b/src/platform/update_engine/filesystem_iterator.h |
@@ -0,0 +1,126 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |
+ |
+// This class is used to walk a filesystem. It will iterate over every file |
+// on the same device as the file passed in the ctor. Directories will be |
+// visited before their children. Children will be visited in no particular |
+// order. |
+ |
+// The iterator is a forward iterator. It's not random access nor can it be |
+// decremented. |
+ |
+// Note: If the iterator comes across a mount point where another filesystem |
+// is mounted, that mount point will be present, but none of its children |
+// will be. Technically the mount point is on the other filesystem (and |
+// the Stat() call will verify that), but we return it anyway since: |
+// 1. Such a folder must exist in the first filesystem if it got used |
+// as a mount point. |
+// 2. You probably want to copy if it you're using the iterator to do a |
+// filesystem copy |
+// 3. If you don't want that, you can just check Stat().st_dev and skip |
+// foreign filesystems manually. |
+ |
+#include <sys/stat.h> |
+#include <sys/types.h> |
+#include <dirent.h> |
+#include <unistd.h> |
+#include <string> |
+#include <set> |
+#include <vector> |
+ |
+namespace chromeos_update_engine { |
+ |
+class FilesystemIterator { |
+ public: |
+ FilesystemIterator(const std::string& path, |
+ const std::set<std::string>& excl_prefixes); |
+ |
+ ~FilesystemIterator(); |
+ |
+ // Returns stat struct for the current file. |
+ struct stat GetStat() const { |
+ return stbuf_; |
+ } |
+ |
+ // Returns full path for current file. |
+ std::string GetFullPath() const; |
+ |
+ // Returns the path that's part of the iterator. For example, if |
+ // the object were constructed by passing in "/foo/bar" and Path() |
+ // returns "/foo/bar/baz/bat.txt", IterPath would return |
+ // "/baz/bat.txt". When this object is on root (ie, the very first |
+ // path), IterPath will return "", otherwise the first character of |
+ // IterPath will be "/". |
+ std::string GetPartialPath() const; |
+ |
+ // Returns name for current file. |
+ std::string GetBasename() const { |
+ return names_.back(); |
+ } |
+ |
+ // Increments to the next file. |
+ void Increment(); |
+ |
+ // If we're at the end. If at the end, do not call Stat(), Path(), etc., |
+ // since this iterator currently isn't pointing to any file at all. |
+ bool IsEnd() const { |
+ return is_end_; |
+ } |
+ |
+ // Returns true if the iterator is in an error state. |
+ bool IsErr() const { |
+ return is_err_; |
+ } |
+ private: |
+ // Helper for Increment. |
+ void IncrementInternal(); |
+ |
+ // Returns true if path exists and it's a directory. |
+ bool DirectoryExists(const std::string& path); |
+ |
+ // In general (i.e., not midway through a call to Increment()), there is a |
+ // relationship between dirs_ and names_: dirs[i] == names_[i - 1]. |
+ // For example, say we are asked to iterate "/usr/local" and we're currently |
+ // at /usr/local/share/dict/words. dirs_ contains DIR* variables for the |
+ // dirs at: {"/usr/local", ".../share", ".../dict"} and names_ contains: |
+ // {"share", "dict", "words"}. root_path_ contains "/usr/local". |
+ // root_dev_ would be the dev for root_path_ |
+ // (and /usr/local/share/dict/words). stbuf_ would be the stbuf for |
+ // /usr/local/share/dict/words. |
+ |
+ // All opened directories. If this is empty, we're currently on the root, |
+ // but not descended into the root. |
+ // This will always contain the current directory and all it's ancestors |
+ // in root-to-leaf order. For more details, see comment above. |
+ std::vector<DIR*> dirs_; |
+ |
+ // The list of all filenames for the current path that we've descended into. |
+ std::vector<std::string> names_; |
+ |
+ // The device of the root path we've been asked to iterate. |
+ dev_t root_dev_; |
+ |
+ // The root path we've been asked to iteratate. |
+ std::string root_path_; |
+ |
+ // Exclude items w/ this prefix. |
+ std::set<std::string> excl_prefixes_; |
+ |
+ // The struct stat of the current file we're at. |
+ struct stat stbuf_; |
+ |
+ // Generally false; set to true when we reach the end of files to iterate |
+ // or error occurs. |
+ bool is_end_; |
+ |
+ // Generally false; set to true if an error occurrs. |
+ bool is_err_; |
+}; |
+ |
+} // namespace chromeos_update_engine |
+ |
+#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_FILESYSTEM_ITERATOR_H__ |