OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013 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 // A tool to dump HTML5 filesystem from CUI. |
| 6 // |
| 7 // Usage: |
| 8 // |
| 9 // ./out/Release/dump_file_system [options] <profile dir> [origin]... |
| 10 // |
| 11 // If no origin is specified, this dumps all origins in the profile dir. |
| 12 // |
| 13 // Available options: |
| 14 // |
| 15 // -t : dumps temporary files instead of persistent. |
| 16 // -s : dumps syncable files instead of persistent. |
| 17 // -u user : uses the specified user name instead of "Default". |
| 18 // -l : more information will be displayed. |
| 19 // |
| 20 // The format of -l option is: |
| 21 // |
| 22 // === ORIGIN origin_name origin_dir === |
| 23 // file_name file_id file_size file_content_path |
| 24 // ... |
| 25 // |
| 26 // where file_name has a trailing slash, file_size is the number of |
| 27 // children, and file_content_path is empty if the file is a directory. |
| 28 // |
| 29 |
| 30 #include <stdio.h> |
| 31 #include <stdlib.h> |
| 32 |
| 33 #include <stack> |
| 34 #include <string> |
| 35 #include <utility> |
| 36 #include <vector> |
| 37 |
| 38 #include "base/file_util.h" |
| 39 #include "base/files/file_path.h" |
| 40 #include "base/format_macros.h" |
| 41 #include "base/stringprintf.h" |
| 42 #include "webkit/fileapi/file_system_directory_database.h" |
| 43 #include "webkit/fileapi/file_system_origin_database.h" |
| 44 #include "webkit/fileapi/file_system_types.h" |
| 45 #include "webkit/fileapi/file_system_util.h" |
| 46 #include "webkit/fileapi/obfuscated_file_util.h" |
| 47 #include "webkit/fileapi/sandbox_mount_point_provider.h" |
| 48 |
| 49 namespace { |
| 50 |
| 51 bool g_opt_long; |
| 52 fileapi::FileSystemType g_opt_fs_type = fileapi::kFileSystemTypePersistent; |
| 53 |
| 54 void ShowMessageAndExit(const std::string& msg) { |
| 55 fprintf(stderr, "%s\n", msg.c_str()); |
| 56 exit(EXIT_FAILURE); |
| 57 } |
| 58 |
| 59 void ShowUsageAndExit(const std::string& arg0) { |
| 60 ShowMessageAndExit("Usage: " + arg0 + |
| 61 " [-l] [-t] [-s] [-u user] <profile dir> [origin]..."); |
| 62 } |
| 63 |
| 64 } // namespace |
| 65 |
| 66 namespace fileapi { |
| 67 |
| 68 static void DumpDirectoryTree(const std::string& origin_name, |
| 69 base::FilePath origin_dir) { |
| 70 origin_dir = origin_dir.Append( |
| 71 ObfuscatedFileUtil::GetDirectoryNameForType(g_opt_fs_type)); |
| 72 |
| 73 printf("=== ORIGIN %s %s ===\n", |
| 74 origin_name.c_str(), FilePathToString(origin_dir).c_str()); |
| 75 |
| 76 if (!file_util::DirectoryExists(origin_dir)) { |
| 77 ShowMessageAndExit(FilePathToString(origin_dir) + |
| 78 " is not a filesystem origin directory"); |
| 79 } |
| 80 |
| 81 FileSystemDirectoryDatabase directory_db(origin_dir); |
| 82 FileSystemDirectoryDatabase::FileId root_id; |
| 83 if (!directory_db.GetFileWithPath(StringToFilePath("/"), &root_id)) { |
| 84 ShowMessageAndExit(FilePathToString(origin_dir) + |
| 85 " does not have the root directory"); |
| 86 } |
| 87 |
| 88 std::stack<std::pair<FileSystemDirectoryDatabase::FileId, |
| 89 std::string> > paths; |
| 90 paths.push(std::make_pair(root_id, "")); |
| 91 while (!paths.empty()) { |
| 92 FileSystemDirectoryDatabase::FileId id = paths.top().first; |
| 93 const std::string dirname = paths.top().second; |
| 94 paths.pop(); |
| 95 |
| 96 FileSystemDirectoryDatabase::FileInfo info; |
| 97 if (!directory_db.GetFileInfo(id, &info)) { |
| 98 ShowMessageAndExit(base::StringPrintf("GetFileInfo failed for %"PRId64, |
| 99 id)); |
| 100 } |
| 101 |
| 102 const std::string name = |
| 103 dirname + "/" + FilePathToString(base::FilePath(info.name)); |
| 104 std::vector<FileSystemDirectoryDatabase::FileId> children; |
| 105 if (info.is_directory()) { |
| 106 if (!directory_db.ListChildren(id, &children)) { |
| 107 ShowMessageAndExit(base::StringPrintf( |
| 108 "ListChildren failed for %s (%"PRId64")", |
| 109 info.name.c_str(), id)); |
| 110 } |
| 111 |
| 112 for (size_t j = children.size(); j; j--) |
| 113 paths.push(make_pair(children[j-1], name)); |
| 114 } |
| 115 |
| 116 // +1 for the leading extra slash. |
| 117 const char* display_name = name.c_str() + 1; |
| 118 const char* directory_suffix = info.is_directory() ? "/" : ""; |
| 119 if (g_opt_long) { |
| 120 int64 size; |
| 121 if (info.is_directory()) { |
| 122 size = static_cast<int64>(children.size()); |
| 123 } else { |
| 124 file_util::GetFileSize(origin_dir.Append(info.data_path), &size); |
| 125 } |
| 126 // TODO(hamaji): Modification time? |
| 127 printf("%s%s %"PRId64" %"PRId64" %s\n", |
| 128 display_name, |
| 129 directory_suffix, |
| 130 id, |
| 131 size, |
| 132 FilePathToString(info.data_path).c_str()); |
| 133 } else { |
| 134 printf("%s%s\n", display_name, directory_suffix); |
| 135 } |
| 136 } |
| 137 } |
| 138 |
| 139 static void DumpOrigin(const base::FilePath& file_system_dir, |
| 140 const std::string& origin_name) { |
| 141 FileSystemOriginDatabase origin_db(file_system_dir); |
| 142 base::FilePath origin_dir; |
| 143 if (!origin_db.HasOriginPath(origin_name)) { |
| 144 ShowMessageAndExit("Origin " + origin_name + " is not in " + |
| 145 FilePathToString(file_system_dir)); |
| 146 } |
| 147 |
| 148 if (!origin_db.GetPathForOrigin(origin_name, &origin_dir)) { |
| 149 ShowMessageAndExit("Failed to get path of origin " + origin_name + |
| 150 " in " + FilePathToString(file_system_dir)); |
| 151 } |
| 152 DumpDirectoryTree(origin_name, file_system_dir.Append(origin_dir)); |
| 153 } |
| 154 |
| 155 static void DumpFileSystem(const base::FilePath& file_system_dir) { |
| 156 FileSystemOriginDatabase origin_db(file_system_dir); |
| 157 std::vector<FileSystemOriginDatabase::OriginRecord> origins; |
| 158 origin_db.ListAllOrigins(&origins); |
| 159 for (size_t i = 0; i < origins.size(); i++) { |
| 160 const FileSystemOriginDatabase::OriginRecord& origin = origins[i]; |
| 161 DumpDirectoryTree(origin.origin, file_system_dir.Append(origin.path)); |
| 162 puts(""); |
| 163 } |
| 164 } |
| 165 |
| 166 } // namespace fileapi |
| 167 |
| 168 int main(int argc, char* argv[]) { |
| 169 const char* arg0 = argv[0]; |
| 170 std::string username = "Default"; |
| 171 while (true) { |
| 172 if (argc < 2) |
| 173 ShowUsageAndExit(arg0); |
| 174 |
| 175 if (std::string(argv[1]) == "-l") { |
| 176 g_opt_long = true; |
| 177 argc--; |
| 178 argv++; |
| 179 } else if (std::string(argv[1]) == "-t") { |
| 180 g_opt_fs_type = fileapi::kFileSystemTypeTemporary; |
| 181 argc--; |
| 182 argv++; |
| 183 } else if (std::string(argv[1]) == "-s") { |
| 184 g_opt_fs_type = fileapi::kFileSystemTypeSyncable; |
| 185 argc--; |
| 186 argv++; |
| 187 } else if (std::string(argv[1]) == "-u") { |
| 188 if (argc < 3) |
| 189 ShowUsageAndExit(arg0); |
| 190 username = argv[2]; |
| 191 argc -= 2; |
| 192 argv += 2; |
| 193 } else { |
| 194 break; |
| 195 } |
| 196 } |
| 197 |
| 198 if (argc < 2) |
| 199 ShowUsageAndExit(arg0); |
| 200 |
| 201 const base::FilePath profile_dir(fileapi::StringToFilePath(argv[1])); |
| 202 if (!file_util::DirectoryExists(profile_dir)) { |
| 203 ShowMessageAndExit(fileapi::FilePathToString(profile_dir) + |
| 204 " is not a directory"); |
| 205 } |
| 206 |
| 207 const base::FilePath file_system_dir( |
| 208 profile_dir.Append(fileapi::StringToFilePath(username)).Append( |
| 209 base::FilePath( |
| 210 fileapi::SandboxMountPointProvider::kFileSystemDirectory))); |
| 211 if (!file_util::DirectoryExists(file_system_dir)) { |
| 212 ShowMessageAndExit(fileapi::FilePathToString(file_system_dir) + |
| 213 " is not a filesystem directory"); |
| 214 } |
| 215 |
| 216 if (argc == 2) { |
| 217 fileapi::DumpFileSystem(file_system_dir); |
| 218 } else { |
| 219 for (int i = 2; i < argc; i++) { |
| 220 fileapi::DumpOrigin(file_system_dir, argv[i]); |
| 221 } |
| 222 } |
| 223 return 0; |
| 224 } |
OLD | NEW |