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] <filesystem 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 // -l : more information will be displayed. | |
18 // | |
19 // The format of -l option is: | |
20 // | |
21 // === ORIGIN origin_name origin_dir === | |
22 // file_name file_id file_size file_content_path | |
23 // ... | |
24 // | |
25 // where file_name has a trailing slash, file_size is the number of | |
26 // children, and file_content_path is empty if the file is a directory. | |
27 // | |
28 | |
29 #include <stdio.h> | |
30 #include <stdlib.h> | |
31 | |
32 #include <stack> | |
33 #include <string> | |
34 #include <utility> | |
35 #include <vector> | |
36 | |
37 #include "base/file_util.h" | |
38 #include "base/files/file_path.h" | |
39 #include "base/format_macros.h" | |
40 #include "base/stringprintf.h" | |
41 #include "webkit/browser/fileapi/obfuscated_file_util.h" | |
42 #include "webkit/browser/fileapi/sandbox_directory_database.h" | |
43 #include "webkit/browser/fileapi/sandbox_mount_point_provider.h" | |
44 #include "webkit/browser/fileapi/sandbox_origin_database.h" | |
45 #include "webkit/fileapi/file_system_types.h" | |
46 #include "webkit/fileapi/file_system_util.h" | |
47 | |
48 namespace { | |
49 | |
50 bool g_opt_long; | |
51 fileapi::FileSystemType g_opt_fs_type = fileapi::kFileSystemTypePersistent; | |
52 | |
53 void ShowMessageAndExit(const std::string& msg) { | |
54 fprintf(stderr, "%s\n", msg.c_str()); | |
55 exit(EXIT_FAILURE); | |
56 } | |
57 | |
58 void ShowUsageAndExit(const std::string& arg0) { | |
59 ShowMessageAndExit( | |
60 "Usage: " + arg0 + | |
61 " [-l] [-t] [-s] <filesystem 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 return; | |
78 | |
79 SandboxDirectoryDatabase directory_db(origin_dir); | |
80 SandboxDirectoryDatabase::FileId root_id; | |
81 if (!directory_db.GetFileWithPath(StringToFilePath("/"), &root_id)) | |
82 return; | |
83 | |
84 std::stack<std::pair<SandboxDirectoryDatabase::FileId, | |
85 std::string> > paths; | |
86 paths.push(std::make_pair(root_id, "")); | |
87 while (!paths.empty()) { | |
88 SandboxDirectoryDatabase::FileId id = paths.top().first; | |
89 const std::string dirname = paths.top().second; | |
90 paths.pop(); | |
91 | |
92 SandboxDirectoryDatabase::FileInfo info; | |
93 if (!directory_db.GetFileInfo(id, &info)) { | |
94 ShowMessageAndExit(base::StringPrintf("GetFileInfo failed for %"PRId64, | |
95 id)); | |
96 } | |
97 | |
98 const std::string name = | |
99 dirname + "/" + FilePathToString(base::FilePath(info.name)); | |
100 std::vector<SandboxDirectoryDatabase::FileId> children; | |
101 if (info.is_directory()) { | |
102 if (!directory_db.ListChildren(id, &children)) { | |
103 ShowMessageAndExit(base::StringPrintf( | |
104 "ListChildren failed for %s (%"PRId64")", | |
105 info.name.c_str(), id)); | |
106 } | |
107 | |
108 for (size_t j = children.size(); j; j--) | |
109 paths.push(make_pair(children[j-1], name)); | |
110 } | |
111 | |
112 // +1 for the leading extra slash. | |
113 const char* display_name = name.c_str() + 1; | |
114 const char* directory_suffix = info.is_directory() ? "/" : ""; | |
115 if (g_opt_long) { | |
116 int64 size; | |
117 if (info.is_directory()) { | |
118 size = static_cast<int64>(children.size()); | |
119 } else { | |
120 file_util::GetFileSize(origin_dir.Append(info.data_path), &size); | |
121 } | |
122 // TODO(hamaji): Modification time? | |
123 printf("%s%s %"PRId64" %"PRId64" %s\n", | |
124 display_name, | |
125 directory_suffix, | |
126 id, | |
127 size, | |
128 FilePathToString(info.data_path).c_str()); | |
129 } else { | |
130 printf("%s%s\n", display_name, directory_suffix); | |
131 } | |
132 } | |
133 } | |
134 | |
135 static void DumpOrigin(const base::FilePath& file_system_dir, | |
136 const std::string& origin_name) { | |
137 SandboxOriginDatabase origin_db(file_system_dir); | |
138 base::FilePath origin_dir; | |
139 if (!origin_db.HasOriginPath(origin_name)) { | |
140 ShowMessageAndExit("Origin " + origin_name + " is not in " + | |
141 FilePathToString(file_system_dir)); | |
142 } | |
143 | |
144 if (!origin_db.GetPathForOrigin(origin_name, &origin_dir)) { | |
145 ShowMessageAndExit("Failed to get path of origin " + origin_name + | |
146 " in " + FilePathToString(file_system_dir)); | |
147 } | |
148 DumpDirectoryTree(origin_name, file_system_dir.Append(origin_dir)); | |
149 } | |
150 | |
151 static void DumpFileSystem(const base::FilePath& file_system_dir) { | |
152 SandboxOriginDatabase origin_db(file_system_dir); | |
153 std::vector<SandboxOriginDatabase::OriginRecord> origins; | |
154 origin_db.ListAllOrigins(&origins); | |
155 for (size_t i = 0; i < origins.size(); i++) { | |
156 const SandboxOriginDatabase::OriginRecord& origin = origins[i]; | |
157 DumpDirectoryTree(origin.origin, file_system_dir.Append(origin.path)); | |
158 puts(""); | |
159 } | |
160 } | |
161 | |
162 } // namespace fileapi | |
163 | |
164 int main(int argc, char* argv[]) { | |
165 const char* arg0 = argv[0]; | |
166 std::string username = "Default"; | |
167 while (true) { | |
168 if (argc < 2) | |
169 ShowUsageAndExit(arg0); | |
170 | |
171 if (std::string(argv[1]) == "-l") { | |
172 g_opt_long = true; | |
173 argc--; | |
174 argv++; | |
175 } else if (std::string(argv[1]) == "-t") { | |
176 g_opt_fs_type = fileapi::kFileSystemTypeTemporary; | |
177 argc--; | |
178 argv++; | |
179 } else if (std::string(argv[1]) == "-s") { | |
180 g_opt_fs_type = fileapi::kFileSystemTypeSyncable; | |
181 argc--; | |
182 argv++; | |
183 } else { | |
184 break; | |
185 } | |
186 } | |
187 | |
188 if (argc < 2) | |
189 ShowUsageAndExit(arg0); | |
190 | |
191 const base::FilePath file_system_dir = fileapi::StringToFilePath(argv[1]); | |
192 if (!file_util::DirectoryExists(file_system_dir)) { | |
193 ShowMessageAndExit(fileapi::FilePathToString(file_system_dir) + | |
194 " is not a filesystem directory"); | |
195 } | |
196 | |
197 if (argc == 2) { | |
198 fileapi::DumpFileSystem(file_system_dir); | |
199 } else { | |
200 for (int i = 2; i < argc; i++) { | |
201 fileapi::DumpOrigin(file_system_dir, argv[i]); | |
202 } | |
203 } | |
204 return 0; | |
205 } | |
OLD | NEW |