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 [-l] [-t] <profile dir> [origin]... | |
10 // | |
11 // If no origin is specified, this dumps all origins in the profile dir. | |
12 // | |
13 // If -t is specified, this dumps temporary files instead of persistent. | |
14 // | |
15 // If -l is specified, more information will be displayed. | |
16 // The format of -l option is: | |
17 // | |
18 // === ORIGIN origin_name origin_dir === | |
19 // file_name file_id file_size file_content_path | |
20 // ... | |
21 // | |
22 // where file_name has a trailing slash, file_size is the number of | |
23 // children, and file_content_path is empty if the file is a directory. | |
24 // | |
25 | |
26 #include <inttypes.h> | |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
29 | |
30 #include <stack> | |
31 #include <string> | |
32 #include <utility> | |
33 #include <vector> | |
34 | |
35 #include "base/file_util.h" | |
36 #include "base/files/file_path.h" | |
37 #include "base/stringprintf.h" | |
38 #include "webkit/fileapi/file_system_directory_database.h" | |
39 #include "webkit/fileapi/file_system_origin_database.h" | |
40 | |
41 namespace { | |
42 | |
43 static void ShowMessageAndExit(const std::string& msg) { | |
kinuko
2013/04/16 10:59:48
nit: no need of static?
hamaji
2013/04/16 12:25:12
Done.
| |
44 fprintf(stderr, "%s\n", msg.c_str()); | |
45 exit(EXIT_FAILURE); | |
46 } | |
47 | |
48 static void ShowUsageAndExit(const std::string& arg0) { | |
kinuko
2013/04/16 10:59:48
ditto
hamaji
2013/04/16 12:25:12
Done.
| |
49 ShowMessageAndExit("Usage: " + arg0 + | |
50 " [-l] [-t] <profile dir> [origin]..."); | |
51 } | |
52 | |
53 } // anonymous namespace | |
kinuko
2013/04/16 10:59:48
nit: '// namespace' is fine in chrome
hamaji
2013/04/16 12:25:12
Done.
| |
54 | |
55 namespace fileapi { | |
56 | |
57 static bool g_opt_long; | |
58 static bool g_opt_temporary; | |
kinuko
2013/04/16 10:59:48
can these be inside the anonymous space?
hamaji
2013/04/16 12:25:12
Done.
| |
59 | |
60 static void DumpDirectoryTree(const std::string& origin_name, | |
61 base::FilePath origin_dir) { | |
62 if (!g_opt_temporary) { | |
63 origin_dir = origin_dir.Append("p"); | |
64 } | |
kinuko
2013/04/16 10:59:48
Append("t") for g_opt_temporary==true?
Can we use
hamaji
2013/04/16 12:25:12
Done.
| |
65 | |
66 printf("=== ORIGIN %s %s ===\n", | |
67 origin_name.c_str(), origin_dir.value().c_str()); | |
68 | |
69 if (!file_util::DirectoryExists(origin_dir)) | |
70 ShowMessageAndExit(origin_dir.value() + | |
71 " is not a filesystem origin directory"); | |
kinuko
2013/04/16 10:59:48
nit: Please put { } for multi-line body (here and
hamaji
2013/04/16 12:25:12
Done.
| |
72 | |
73 FileSystemDirectoryDatabase directory_db(origin_dir); | |
74 if (!directory_db.IsFileSystemConsistent()) | |
75 ShowMessageAndExit(origin_dir.value() + | |
76 " is not a consistent file system"); | |
kinuko
2013/04/16 10:59:48
Probably you don't need these lines, or maybe add
hamaji
2013/04/16 12:25:12
Removed.
| |
77 | |
78 FileSystemDirectoryDatabase::FileId root_id; | |
79 if (!directory_db.GetFileWithPath(base::FilePath("/"), &root_id)) | |
80 ShowMessageAndExit(origin_dir.value() + | |
81 " does not have the root directory"); | |
82 | |
83 std::stack<std::pair<FileSystemDirectoryDatabase::FileId, | |
84 std::string> > paths; | |
85 paths.push(std::make_pair(root_id, "")); | |
86 while (!paths.empty()) { | |
87 FileSystemDirectoryDatabase::FileId id = paths.top().first; | |
88 const std::string dirname = paths.top().second; | |
89 paths.pop(); | |
90 | |
91 FileSystemDirectoryDatabase::FileInfo info; | |
92 if (!directory_db.GetFileInfo(id, &info)) | |
93 ShowMessageAndExit(base::StringPrintf("GetFileInfo failed for %"PRId64, | |
94 id)); | |
95 | |
96 const std::string name = dirname + "/" + info.name; | |
97 std::vector<FileSystemDirectoryDatabase::FileId> children; | |
98 if (info.is_directory()) { | |
99 if (!directory_db.ListChildren(id, &children)) | |
100 ShowMessageAndExit(base::StringPrintf( | |
101 "ListChildren failed for %s (%"PRId64")", | |
102 info.name.c_str(), id)); | |
103 | |
104 for (size_t j = children.size(); j; j--) | |
105 paths.push(make_pair(children[j-1], name)); | |
106 } | |
107 | |
108 // +1 for the leading extra slash. | |
109 const char* display_name = name.c_str() + 1; | |
110 const char* directory_suffix = info.is_directory() ? "/" : ""; | |
111 if (g_opt_long) { | |
112 int64 size; | |
113 if (info.is_directory()) { | |
114 size = static_cast<int64>(children.size()); | |
115 } else { | |
116 file_util::GetFileSize(origin_dir.Append(info.data_path), &size); | |
117 } | |
118 // TODO(hamaji): Modification time? | |
119 printf("%s%s %"PRId64" %"PRId64" %s\n", | |
120 display_name, | |
121 directory_suffix, | |
122 id, | |
123 size, | |
124 info.data_path.value().c_str()); | |
125 } else { | |
126 printf("%s%s\n", display_name, directory_suffix); | |
127 } | |
128 } | |
129 } | |
130 | |
131 static void DumpOrigin(const base::FilePath& file_system_dir, | |
132 const std::string& origin_name) { | |
133 FileSystemOriginDatabase origin_db(file_system_dir); | |
134 base::FilePath origin_dir; | |
135 if (!origin_db.HasOriginPath(origin_name)) | |
136 ShowMessageAndExit("Origin " + origin_name + " is not in " + | |
137 file_system_dir.value()); | |
138 | |
139 if (!origin_db.GetPathForOrigin(origin_name, &origin_dir)) | |
140 ShowMessageAndExit("Failed to get path of origin " + origin_name + | |
141 " in " + file_system_dir.value()); | |
142 DumpDirectoryTree(origin_name, file_system_dir.Append(origin_dir)); | |
143 } | |
144 | |
145 static void DumpFileSystem(const base::FilePath& file_system_dir) { | |
146 FileSystemOriginDatabase origin_db(file_system_dir); | |
147 std::vector<FileSystemOriginDatabase::OriginRecord> origins; | |
148 origin_db.ListAllOrigins(&origins); | |
149 for (size_t i = 0; i < origins.size(); i++) { | |
150 const FileSystemOriginDatabase::OriginRecord& origin = origins[i]; | |
151 DumpDirectoryTree(origin.origin, file_system_dir.Append(origin.path)); | |
152 puts(""); | |
153 } | |
154 } | |
155 | |
156 } // namespace fileapi | |
157 | |
158 int main(int argc, char* argv[]) { | |
159 const char* arg0 = argv[0]; | |
160 while (true) { | |
161 if (argc < 2) | |
162 ShowUsageAndExit(arg0); | |
163 | |
164 if (std::string(argv[1]) == "-l") { | |
165 fileapi::g_opt_long = true; | |
166 argc--; | |
167 argv++; | |
168 } else if (std::string(argv[1]) == "-t") { | |
169 fileapi::g_opt_temporary = true; | |
170 argc--; | |
171 argv++; | |
172 } else { | |
173 break; | |
174 } | |
175 } | |
176 | |
177 if (argc < 2) | |
178 ShowUsageAndExit(arg0); | |
179 | |
180 const base::FilePath profile_dir(argv[1]); | |
181 if (!file_util::DirectoryExists(profile_dir)) | |
182 ShowMessageAndExit(profile_dir.value() + " is not a profile directory"); | |
kinuko
2013/04/16 10:59:48
nit: "is not a directory" ?
hamaji
2013/04/16 12:25:12
Done.
| |
183 | |
184 const base::FilePath file_system_dir( | |
185 profile_dir.Append("Default").Append("File System")); | |
kinuko
2013/04/16 10:59:48
can you use
fileapi::SandboxMountPointProvider::kF
hamaji
2013/04/16 12:25:12
Done.
| |
186 if (!file_util::DirectoryExists(file_system_dir)) | |
187 ShowMessageAndExit(file_system_dir.value() + | |
188 " is not a filesystem directory"); | |
189 | |
190 if (argc == 2) { | |
191 fileapi::DumpFileSystem(file_system_dir); | |
192 } else { | |
193 for (int i = 2; i < argc; i++) { | |
194 fileapi::DumpOrigin(file_system_dir, argv[i]); | |
195 } | |
196 } | |
197 return 0; | |
198 } | |
OLD | NEW |