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/files/file_path.h"
38 #include "base/files/file_util.h"
39 #include "base/format_macros.h"
40 #include "base/strings/stringprintf.h"
41 #include "storage/browser/fileapi/obfuscated_file_util.h"
42 #include "storage/browser/fileapi/sandbox_directory_database.h"
43 #include "storage/browser/fileapi/sandbox_file_system_backend.h"
44 #include "storage/browser/fileapi/sandbox_origin_database.h"
45 #include "storage/common/fileapi/file_system_types.h"
46 #include "storage/common/fileapi/file_system_util.h"
51 const char* g_opt_fs_type
= "p";
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(g_opt_fs_type
);
72 printf("=== ORIGIN %s %s ===\n",
73 origin_name
.c_str(), FilePathToString(origin_dir
).c_str());
75 if (!base::DirectoryExists(origin_dir
))
78 SandboxDirectoryDatabase
directory_db(origin_dir
, NULL
);
79 SandboxDirectoryDatabase::FileId root_id
;
80 if (!directory_db
.GetFileWithPath(StringToFilePath("/"), &root_id
))
83 std::stack
<std::pair
<SandboxDirectoryDatabase::FileId
,
85 paths
.push(std::make_pair(root_id
, ""));
86 while (!paths
.empty()) {
87 SandboxDirectoryDatabase::FileId id
= paths
.top().first
;
88 const std::string dirname
= paths
.top().second
;
91 SandboxDirectoryDatabase::FileInfo info
;
92 if (!directory_db
.GetFileInfo(id
, &info
)) {
93 ShowMessageAndExit(base::StringPrintf("GetFileInfo failed for %"PRId64
,
97 const std::string name
=
98 dirname
+ "/" + FilePathToString(base::FilePath(info
.name
));
99 std::vector
<SandboxDirectoryDatabase::FileId
> children
;
100 if (info
.is_directory()) {
101 if (!directory_db
.ListChildren(id
, &children
)) {
102 ShowMessageAndExit(base::StringPrintf(
103 "ListChildren failed for %s (%"PRId64
")",
104 info
.name
.c_str(), id
));
107 for (size_t j
= children
.size(); j
; j
--)
108 paths
.push(make_pair(children
[j
-1], name
));
111 // +1 for the leading extra slash.
112 const char* display_name
= name
.c_str() + 1;
113 const char* directory_suffix
= info
.is_directory() ? "/" : "";
116 if (info
.is_directory()) {
117 size
= static_cast<int64
>(children
.size());
119 base::GetFileSize(origin_dir
.Append(info
.data_path
), &size
);
121 // TODO(hamaji): Modification time?
122 printf("%s%s %"PRId64
" %"PRId64
" %s\n",
127 FilePathToString(info
.data_path
).c_str());
129 printf("%s%s\n", display_name
, directory_suffix
);
134 static void DumpOrigin(const base::FilePath
& file_system_dir
,
135 const std::string
& origin_name
) {
136 SandboxOriginDatabase
origin_db(file_system_dir
, NULL
);
137 base::FilePath origin_dir
;
138 if (!origin_db
.HasOriginPath(origin_name
)) {
139 ShowMessageAndExit("Origin " + origin_name
+ " is not in " +
140 FilePathToString(file_system_dir
));
143 if (!origin_db
.GetPathForOrigin(origin_name
, &origin_dir
)) {
144 ShowMessageAndExit("Failed to get path of origin " + origin_name
+
145 " in " + FilePathToString(file_system_dir
));
147 DumpDirectoryTree(origin_name
, file_system_dir
.Append(origin_dir
));
150 static void DumpFileSystem(const base::FilePath
& file_system_dir
) {
151 SandboxOriginDatabase
origin_db(file_system_dir
, NULL
);
152 std::vector
<SandboxOriginDatabase::OriginRecord
> origins
;
153 origin_db
.ListAllOrigins(&origins
);
154 for (size_t i
= 0; i
< origins
.size(); i
++) {
155 const SandboxOriginDatabase::OriginRecord
& origin
= origins
[i
];
156 DumpDirectoryTree(origin
.origin
, file_system_dir
.Append(origin
.path
));
161 } // namespace storage
163 int main(int argc
, char* argv
[]) {
164 const char* arg0
= argv
[0];
165 std::string username
= "Default";
168 ShowUsageAndExit(arg0
);
170 if (std::string(argv
[1]) == "-l") {
174 } else if (std::string(argv
[1]) == "-t") {
178 } else if (std::string(argv
[1]) == "-s") {
188 ShowUsageAndExit(arg0
);
190 const base::FilePath file_system_dir
= storage::StringToFilePath(argv
[1]);
191 if (!base::DirectoryExists(file_system_dir
)) {
192 ShowMessageAndExit(storage::FilePathToString(file_system_dir
) +
193 " is not a filesystem directory");
197 storage::DumpFileSystem(file_system_dir
);
199 for (int i
= 2; i
< argc
; i
++) {
200 storage::DumpOrigin(file_system_dir
, argv
[i
]);