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.
5 // A tool to dump HTML5 filesystem from CUI.
9 // ./out/Release/dump_file_system [options] <filesystem dir> [origin]...
11 // If no origin is specified, this dumps all origins in the profile dir.
15 // -t : dumps temporary files instead of persistent.
16 // -s : dumps syncable files instead of persistent.
17 // -l : more information will be displayed.
19 // The format of -l option is:
21 // === ORIGIN origin_name origin_dir ===
22 // file_name file_id file_size file_content_path
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.
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"
51 fileapi::FileSystemType g_opt_fs_type
= fileapi::kFileSystemTypePersistent
;
53 void ShowMessageAndExit(const std::string
& msg
) {
54 fprintf(stderr
, "%s\n", msg
.c_str());
58 void ShowUsageAndExit(const std::string
& arg0
) {
61 " [-l] [-t] [-s] <filesystem dir> [origin]...");
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
));
73 printf("=== ORIGIN %s %s ===\n",
74 origin_name
.c_str(), FilePathToString(origin_dir
).c_str());
76 if (!file_util::DirectoryExists(origin_dir
))
79 SandboxDirectoryDatabase
directory_db(origin_dir
);
80 SandboxDirectoryDatabase::FileId root_id
;
81 if (!directory_db
.GetFileWithPath(StringToFilePath("/"), &root_id
))
84 std::stack
<std::pair
<SandboxDirectoryDatabase::FileId
,
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
;
92 SandboxDirectoryDatabase::FileInfo info
;
93 if (!directory_db
.GetFileInfo(id
, &info
)) {
94 ShowMessageAndExit(base::StringPrintf("GetFileInfo failed for %"PRId64
,
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
));
108 for (size_t j
= children
.size(); j
; j
--)
109 paths
.push(make_pair(children
[j
-1], name
));
112 // +1 for the leading extra slash.
113 const char* display_name
= name
.c_str() + 1;
114 const char* directory_suffix
= info
.is_directory() ? "/" : "";
117 if (info
.is_directory()) {
118 size
= static_cast<int64
>(children
.size());
120 file_util::GetFileSize(origin_dir
.Append(info
.data_path
), &size
);
122 // TODO(hamaji): Modification time?
123 printf("%s%s %"PRId64
" %"PRId64
" %s\n",
128 FilePathToString(info
.data_path
).c_str());
130 printf("%s%s\n", display_name
, directory_suffix
);
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
));
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
));
148 DumpDirectoryTree(origin_name
, file_system_dir
.Append(origin_dir
));
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
));
162 } // namespace fileapi
164 int main(int argc
, char* argv
[]) {
165 const char* arg0
= argv
[0];
166 std::string username
= "Default";
169 ShowUsageAndExit(arg0
);
171 if (std::string(argv
[1]) == "-l") {
175 } else if (std::string(argv
[1]) == "-t") {
176 g_opt_fs_type
= fileapi::kFileSystemTypeTemporary
;
179 } else if (std::string(argv
[1]) == "-s") {
180 g_opt_fs_type
= fileapi::kFileSystemTypeSyncable
;
189 ShowUsageAndExit(arg0
);
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");
198 fileapi::DumpFileSystem(file_system_dir
);
200 for (int i
= 2; i
< argc
; i
++) {
201 fileapi::DumpOrigin(file_system_dir
, argv
[i
]);