2
* Copyright (c) 2011 Martin Sucha
3
* Copyright (c) 2010 Jiri Svoboda
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
10
* - Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* - Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* - The name of the author may not be used to endorse or promote products
16
* derived from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
* @brief Tool for dumping content of block devices
45
#include <byteorder.h>
46
#include <sys/types.h>
47
#include <sys/typefmt.h>
51
#define NAME "blkdump"
53
static void syntax_print(void);
54
static void print_hex_row(uint8_t *data, size_t length, size_t bytes_per_row);
56
int main(int argc, char **argv)
61
service_id_t service_id;
64
aoff64_t block_offset = 0;
65
aoff64_t block_count = 1;
71
bool relative = false;
74
printf(NAME ": Error, argument missing.\n");
81
if (str_cmp(*argv, "--relative") == 0) {
86
if (str_cmp(*argv, "--offset") == 0) {
89
printf(NAME ": Error, argument missing (offset).\n");
94
block_offset = strtol(*argv, &endptr, 10);
95
if (*endptr != '\0') {
96
printf(NAME ": Error, invalid argument (offset).\n");
104
if (str_cmp(*argv, "--count") == 0) {
107
printf(NAME ": Error, argument missing (count).\n");
112
block_count = strtol(*argv, &endptr, 10);
113
if (*endptr != '\0') {
114
printf(NAME ": Error, invalid argument (count).\n");
123
printf(NAME ": Error, unexpected argument.\n");
130
rc = loc_service_get_id(dev_path, &service_id, 0);
132
printf(NAME ": Error resolving device `%s'.\n", dev_path);
136
rc = block_init(EXCHANGE_SERIALIZE, service_id, 2048);
138
printf(NAME ": Error initializing libblock.\n");
142
rc = block_get_bsize(service_id, &block_size);
144
printf(NAME ": Error determining device block size.\n");
148
rc = block_get_nblocks(service_id, &dev_nblocks);
150
printf(NAME ": Warning, failed to obtain block device size.\n");
153
printf("Device %s has %" PRIuOFF64 " blocks, %" PRIuOFF64 " bytes each\n", dev_path, dev_nblocks, (aoff64_t) block_size);
155
data = malloc(block_size);
157
printf(NAME ": Error allocating data buffer of %" PRIuOFF64 " bytes", (aoff64_t) block_size);
158
block_fini(service_id);
162
limit = block_offset + block_count;
163
for (current = block_offset; current < limit; current++) {
164
rc = block_read_direct(service_id, current, 1, data);
166
printf(NAME ": Error reading block at %" PRIuOFF64 " \n", current);
171
printf("---- Block %" PRIuOFF64 " (at %" PRIuOFF64 ") ----\n", current, current*block_size);
173
for (data_offset = 0; data_offset < block_size; data_offset += 16) {
175
printf("%8" PRIxOFF64 ": ", (aoff64_t) data_offset);
178
printf("%8" PRIxOFF64 ": ", current*block_size + data_offset);
180
print_hex_row(data+data_offset, block_size-data_offset, 16);
188
block_fini(service_id);
194
* Print a row of 16 bytes as commonly seen in hexadecimal dumps
196
static void print_hex_row(uint8_t *data, size_t length, size_t bytes_per_row) {
200
if (length > bytes_per_row) {
201
length = bytes_per_row;
204
/* Print hexadecimal values */
205
for (pos = 0; pos < length; pos++) {
206
if (pos == length/2) {
209
printf("%02hhX ", data[pos]);
212
/* Pad with spaces if we have less than 16 bytes */
213
for (pos = length; pos < bytes_per_row; pos++) {
214
if (pos == length/2) {
220
/* Print printable characters */
221
for (pos = 0; pos < length; pos++) {
222
if (pos == length/2) {
226
if (b >= 32 && b < 128) {
235
static void syntax_print(void)
237
printf("syntax: blkdump [--relative] [--offset <num_blocks>] [--count <num_blocks>] <device_name>\n");