1// Copyright 2014 The Android Open Source Project
2//
3// This software is licensed under the terms of the GNU General Public
4// License version 2, as published by the Free Software Foundation, and
5// may be copied, distributed, and modified under those terms.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10// GNU General Public License for more details.
11
12#include "android/filesystems/ext4_utils.h"
13
14#include "android/base/Log.h"
15#include "android/base/files/ScopedStdioFile.h"
16
17#include "make_ext4fs.h"
18
19#include <stdint.h>
20#include <string.h>
21
22#define DEBUG_EXT4  0
23
24#define EXT4_LOG     LOG_IF(INFO, DEBUG_EXT4)
25#define EXT4_PLOG    PLOG_IF(INFO, DEBUG_EXT4)
26#define EXT4_ERROR   LOG_IF(ERROR, DEBUG_EXT4)
27#define EXT4_PERROR  PLOG_IF(ERROR, DEBUG_EXT4)
28
29struct Ext4Magic {
30    static const size_t kOffset = 0x438U;
31    static const size_t kSize = 2U;
32    static const uint8_t kExpected[kSize];
33};
34
35const uint8_t Ext4Magic::kExpected[kSize] = { 0x53, 0xef };
36
37bool android_pathIsExt4PartitionImage(const char* path) {
38    if (!path) {
39        EXT4_ERROR << "NULL path parameter";
40        return false;
41    }
42
43    android::base::ScopedStdioFile file(::fopen(path, "rb"));
44    if (!file.get()) {
45        EXT4_PERROR << "Could not open file: " << path;
46        return false;
47    }
48
49    if (::fseek(file.get(), Ext4Magic::kOffset, SEEK_SET) != 0) {
50        EXT4_LOG << "Can't seek to byte " << Ext4Magic::kOffset
51                 << " of " << path;
52        return false;
53    }
54
55    char magic[Ext4Magic::kSize];
56    if (::fread(magic, sizeof(magic), 1, file.get()) != 1) {
57        EXT4_PLOG << "Could not read " << sizeof(magic)
58                  << " bytes from " << path;
59        return false;
60    }
61
62    if (!::memcmp(magic, Ext4Magic::kExpected, sizeof(magic))) {
63        EXT4_LOG << "File is Ext4 partition image: " << path;
64        return true;
65    }
66
67    EXT4_LOG << "Not an Ext4 partition image: " << path;
68    return false;
69}
70
71int android_createEmptyExt4Image(const char *filePath,
72                                 uint64_t size,
73                                 const char *mountpoint) {
74    int ret = ::make_ext4fs(filePath, size, mountpoint, NULL);
75    if (ret < 0)
76        EXT4_ERROR << "Failed to create ext4 image at: " << filePath;
77    return ret;
78}
79