1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A tool to dump HTML5 filesystem from CUI.
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Usage:
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ./out/Release/dump_file_system [options] <filesystem dir> [origin]...
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// If no origin is specified, this dumps all origins in the profile dir.
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Available options:
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// -t : dumps temporary files instead of persistent.
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// -s : dumps syncable files instead of persistent.
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// -l : more information will be displayed.
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The format of -l option is:
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// === ORIGIN origin_name origin_dir ===
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// file_name file_id file_size file_content_path
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ...
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// where file_name has a trailing slash, file_size is the number of
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// children, and file_content_path is empty if the file is a directory.
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stdio.h>
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stdlib.h>
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stack>
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <utility>
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h"
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/format_macros.h"
405e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/obfuscated_file_util.h"
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_directory_database.h"
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_file_system_backend.h"
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_origin_database.h"
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_types.h"
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool g_opt_long;
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char* g_opt_fs_type = "p";
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShowMessageAndExit(const std::string& msg) {
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  fprintf(stderr, "%s\n", msg.c_str());
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  exit(EXIT_FAILURE);
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ShowUsageAndExit(const std::string& arg0) {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowMessageAndExit(
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "Usage: " + arg0 +
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      " [-l] [-t] [-s] <filesystem dir> [origin]...");
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void DumpDirectoryTree(const std::string& origin_name,
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              base::FilePath origin_dir) {
708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  origin_dir = origin_dir.Append(g_opt_fs_type);
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  printf("=== ORIGIN %s %s ===\n",
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         origin_name.c_str(), FilePathToString(origin_dir).c_str());
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::DirectoryExists(origin_dir))
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SandboxDirectoryDatabase directory_db(origin_dir, NULL);
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SandboxDirectoryDatabase::FileId root_id;
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!directory_db.GetFileWithPath(StringToFilePath("/"), &root_id))
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::stack<std::pair<SandboxDirectoryDatabase::FileId,
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       std::string> > paths;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  paths.push(std::make_pair(root_id, ""));
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!paths.empty()) {
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SandboxDirectoryDatabase::FileId id = paths.top().first;
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string dirname = paths.top().second;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    paths.pop();
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SandboxDirectoryDatabase::FileInfo info;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!directory_db.GetFileInfo(id, &info)) {
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ShowMessageAndExit(base::StringPrintf("GetFileInfo failed for %"PRId64,
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                            id));
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string name =
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        dirname + "/" + FilePathToString(base::FilePath(info.name));
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::vector<SandboxDirectoryDatabase::FileId> children;
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (info.is_directory()) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!directory_db.ListChildren(id, &children)) {
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ShowMessageAndExit(base::StringPrintf(
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            "ListChildren failed for %s (%"PRId64")",
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            info.name.c_str(), id));
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (size_t j = children.size(); j; j--)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        paths.push(make_pair(children[j-1], name));
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // +1 for the leading extra slash.
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* display_name = name.c_str() + 1;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* directory_suffix = info.is_directory() ? "/" : "";
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (g_opt_long) {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int64 size;
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (info.is_directory()) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        size = static_cast<int64>(children.size());
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::GetFileSize(origin_dir.Append(info.data_path), &size);
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // TODO(hamaji): Modification time?
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      printf("%s%s %"PRId64" %"PRId64" %s\n",
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             display_name,
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             directory_suffix,
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             id,
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             size,
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             FilePathToString(info.data_path).c_str());
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      printf("%s%s\n", display_name, directory_suffix);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void DumpOrigin(const base::FilePath& file_system_dir,
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       const std::string& origin_name) {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SandboxOriginDatabase origin_db(file_system_dir, NULL);
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath origin_dir;
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!origin_db.HasOriginPath(origin_name)) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowMessageAndExit("Origin " + origin_name + " is not in " +
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       FilePathToString(file_system_dir));
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!origin_db.GetPathForOrigin(origin_name, &origin_dir)) {
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowMessageAndExit("Failed to get path of origin " + origin_name +
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       " in " + FilePathToString(file_system_dir));
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DumpDirectoryTree(origin_name, file_system_dir.Append(origin_dir));
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void DumpFileSystem(const base::FilePath& file_system_dir) {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SandboxOriginDatabase origin_db(file_system_dir, NULL);
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::vector<SandboxOriginDatabase::OriginRecord> origins;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  origin_db.ListAllOrigins(&origins);
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < origins.size(); i++) {
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const SandboxOriginDatabase::OriginRecord& origin = origins[i];
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DumpDirectoryTree(origin.origin, file_system_dir.Append(origin.path));
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    puts("");
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int main(int argc, char* argv[]) {
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* arg0 = argv[0];
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string username = "Default";
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (true) {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (argc < 2)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ShowUsageAndExit(arg0);
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (std::string(argv[1]) == "-l") {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      g_opt_long = true;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      argc--;
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      argv++;
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else if (std::string(argv[1]) == "-t") {
1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      g_opt_fs_type = "t";
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      argc--;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      argv++;
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else if (std::string(argv[1]) == "-s") {
1798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      g_opt_fs_type = "s";
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      argc--;
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      argv++;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } else {
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (argc < 2)
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowUsageAndExit(arg0);
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const base::FilePath file_system_dir = storage::StringToFilePath(argv[1]);
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::DirectoryExists(file_system_dir)) {
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ShowMessageAndExit(storage::FilePathToString(file_system_dir) +
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       " is not a filesystem directory");
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (argc == 2) {
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::DumpFileSystem(file_system_dir);
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (int i = 2; i < argc; i++) {
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::DumpOrigin(file_system_dir, argv[i]);
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
205