1 // Copyright (c) 2012 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 // Md5sum implementation for Android. This version handles files as well as
6 // directories. Its output is sorted by file path.
13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_path.h"
15 #include "base/files/file_util.h"
16 #include "base/logging.h"
21 // Returns whether |path|'s MD5 was successfully written to |digest_string|.
22 bool MD5Sum(const char* path
, std::string
* digest_string
) {
23 base::ScopedFILE
file(fopen(path
, "rb"));
25 LOG(ERROR
) << "Could not open file " << path
;
30 const size_t kBufferSize
= 1 << 16;
31 scoped_ptr
<char[]> buf(new char[kBufferSize
]);
33 while ((len
= fread(buf
.get(), 1, kBufferSize
, file
.get())) > 0)
34 base::MD5Update(&ctx
, base::StringPiece(buf
.get(), len
));
35 if (ferror(file
.get())) {
36 LOG(ERROR
) << "Error reading file " << path
;
39 base::MD5Digest digest
;
40 base::MD5Final(&digest
, &ctx
);
41 *digest_string
= base::MD5DigestToBase16(digest
);
45 // Returns the set of all files contained in |files|. This handles directories
46 // by walking them recursively. Excludes, .svn directories and file under them.
47 std::set
<std::string
> MakeFileSet(const char** files
) {
48 const std::string svn_dir_component
= FILE_PATH_LITERAL("/.svn/");
49 std::set
<std::string
> file_set
;
50 for (const char** file
= files
; *file
; ++file
) {
51 base::FilePath
file_path(*file
);
52 if (base::DirectoryExists(file_path
)) {
53 base::FileEnumerator
file_enumerator(
54 file_path
, true /* recurse */, base::FileEnumerator::FILES
);
55 for (base::FilePath child
, empty
;
56 (child
= file_enumerator
.Next()) != empty
; ) {
57 // If the path contains /.svn/, ignore it.
58 if (child
.value().find(svn_dir_component
) == std::string::npos
) {
59 file_set
.insert(child
.value());
63 file_set
.insert(*file
);
71 int main(int argc
, const char* argv
[]) {
73 LOG(ERROR
) << "Usage: md5sum <path/to/file_or_dir>...";
76 const std::set
<std::string
> files
= MakeFileSet(argv
+ 1);
79 for (std::set
<std::string
>::const_iterator it
= files
.begin();
80 it
!= files
.end(); ++it
) {
81 if (!MD5Sum(it
->c_str(), &digest
)) {
84 std::cout
<< digest
<< " " << *it
<< std::endl
;