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