source: mainline/uspace/app/blkdump/blkdump.c@ 013e5d32

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 013e5d32 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Sucha
3 * Copyright (c) 2013 Jiri Svoboda
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
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.
17 *
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.
28 */
29
30/** @addtogroup fs
31 * @{
32 */
33
34/**
35 * @file blockdump.c
36 * @brief Tool for dumping content of block devices
37 *
38 */
39
40#include <stdio.h>
41#include <stdlib.h>
42#include <stdint.h>
43#include <block.h>
44#include <mem.h>
45#include <loc.h>
46#include <byteorder.h>
47#include <scsi/mmc.h>
48#include <offset.h>
49#include <inttypes.h>
50#include <errno.h>
51#include <str.h>
52
53#define NAME "blkdump"
54
55static void syntax_print(void);
56static int print_blocks(aoff64_t block_offset, aoff64_t block_count, size_t block_size);
57static int print_toc(void);
58static void print_hex_row(uint8_t *data, size_t length, size_t bytes_per_row);
59
60static bool relative = false;
61static service_id_t service_id;
62
63int main(int argc, char **argv)
64{
65
66 errno_t rc;
67 char *dev_path;
68 size_t block_size;
69 char *endptr;
70 aoff64_t block_offset = 0;
71 aoff64_t block_count = 1;
72 aoff64_t dev_nblocks;
73 bool toc = false;
74
75 if (argc < 2) {
76 printf(NAME ": Error, argument missing.\n");
77 syntax_print();
78 return 1;
79 }
80
81 --argc; ++argv;
82
83 if (str_cmp(*argv, "--toc") == 0) {
84 --argc; ++argv;
85 toc = true;
86 goto devname;
87 }
88
89 if (str_cmp(*argv, "--relative") == 0) {
90 --argc; ++argv;
91 relative = true;
92 }
93
94 if (str_cmp(*argv, "--offset") == 0) {
95 --argc; ++argv;
96 if (*argv == NULL) {
97 printf(NAME ": Error, argument missing (offset).\n");
98 syntax_print();
99 return 1;
100 }
101
102 block_offset = strtol(*argv, &endptr, 10);
103 if (*endptr != '\0') {
104 printf(NAME ": Error, invalid argument (offset).\n");
105 syntax_print();
106 return 1;
107 }
108
109 --argc; ++argv;
110 }
111
112 if (str_cmp(*argv, "--count") == 0) {
113 --argc; ++argv;
114 if (*argv == NULL) {
115 printf(NAME ": Error, argument missing (count).\n");
116 syntax_print();
117 return 1;
118 }
119
120 block_count = strtol(*argv, &endptr, 10);
121 if (*endptr != '\0') {
122 printf(NAME ": Error, invalid argument (count).\n");
123 syntax_print();
124 return 1;
125 }
126
127 --argc; ++argv;
128 }
129
130devname:
131 if (argc != 1) {
132 printf(NAME ": Error, unexpected argument.\n");
133 syntax_print();
134 return 1;
135 }
136
137 dev_path = *argv;
138
139 rc = loc_service_get_id(dev_path, &service_id, 0);
140 if (rc != EOK) {
141 printf(NAME ": Error resolving device `%s'.\n", dev_path);
142 return 2;
143 }
144
145 rc = block_init(service_id, 2048);
146 if (rc != EOK) {
147 printf(NAME ": Error initializing libblock.\n");
148 return 2;
149 }
150
151 rc = block_get_bsize(service_id, &block_size);
152 if (rc != EOK) {
153 printf(NAME ": Error determining device block size.\n");
154 return 2;
155 }
156
157 rc = block_get_nblocks(service_id, &dev_nblocks);
158 if (rc != EOK) {
159 printf(NAME ": Warning, failed to obtain block device size.\n");
160 }
161
162 printf("Device %s has %" PRIuOFF64 " blocks, %" PRIuOFF64 " bytes each\n", dev_path, dev_nblocks, (aoff64_t) block_size);
163
164 int ret;
165 if (toc)
166 ret = print_toc();
167 else
168 ret = print_blocks(block_offset, block_count, block_size);
169
170 block_fini(service_id);
171
172 return ret;
173}
174
175static int print_blocks(aoff64_t block_offset, aoff64_t block_count, size_t block_size)
176{
177 uint8_t *data;
178 aoff64_t current;
179 aoff64_t limit;
180 size_t data_offset;
181 errno_t rc;
182
183 data = malloc(block_size);
184 if (data == NULL) {
185 printf(NAME ": Error allocating data buffer of %" PRIuOFF64 " bytes", (aoff64_t) block_size);
186 return 3;
187 }
188
189 limit = block_offset + block_count;
190 for (current = block_offset; current < limit; current++) {
191 rc = block_read_direct(service_id, current, 1, data);
192 if (rc != EOK) {
193 printf(NAME ": Error reading block at %" PRIuOFF64 " \n", current);
194 free(data);
195 return 3;
196 }
197
198 printf("---- Block %" PRIuOFF64 " (at %" PRIuOFF64 ") ----\n", current, current*block_size);
199
200 for (data_offset = 0; data_offset < block_size; data_offset += 16) {
201 if (relative) {
202 printf("%8" PRIxOFF64 ": ", (aoff64_t) data_offset);
203 }
204 else {
205 printf("%8" PRIxOFF64 ": ", current*block_size + data_offset);
206 }
207 print_hex_row(data+data_offset, block_size-data_offset, 16);
208 printf("\n");
209 }
210 printf("\n");
211 }
212
213 free(data);
214 return 0;
215}
216
217static int print_toc(void)
218{
219 scsi_toc_multisess_data_t toc;
220 errno_t rc;
221
222 rc = block_read_toc(service_id, 0, &toc, sizeof(toc));
223 if (rc != EOK)
224 return 1;
225
226 printf("Multisession Information:\n");
227 printf("\tFirst complete session: %" PRIu8 "\n", toc.first_sess);
228 printf("\tLast complete session: %" PRIu8 "\n", toc.last_sess);
229 printf("\tFirst track of last complete session:\n");
230 printf("\t\tADR / Control: 0x%" PRIx8 "\n", toc.ftrack_lsess.adr_control);
231 printf("\t\tTrack number: %" PRIu8 "\n", toc.ftrack_lsess.track_no);
232 printf("\t\tStart block address: %" PRIu32 "\n", toc.ftrack_lsess.start_addr);
233
234 return 0;
235}
236
237/**
238 * Print a row of 16 bytes as commonly seen in hexadecimal dumps
239 */
240static void print_hex_row(uint8_t *data, size_t length, size_t bytes_per_row) {
241 size_t pos;
242 uint8_t b;
243
244 if (length > bytes_per_row) {
245 length = bytes_per_row;
246 }
247
248 /* Print hexadecimal values */
249 for (pos = 0; pos < length; pos++) {
250 if (pos == length/2) {
251 printf(" ");
252 }
253 printf("%02hhX ", data[pos]);
254 }
255
256 /* Pad with spaces if we have less than 16 bytes */
257 for (pos = length; pos < bytes_per_row; pos++) {
258 if (pos == length/2) {
259 printf(" ");
260 }
261 printf(" ");
262 }
263
264 /* Print printable characters */
265 for (pos = 0; pos < length; pos++) {
266 if (pos == length/2) {
267 printf(" ");
268 }
269 b = data[pos];
270 if (b >= 32 && b < 128) {
271 putchar(b);
272 }
273 else {
274 putchar('.');
275 }
276 }
277}
278
279static void syntax_print(void)
280{
281 printf("syntax: blkdump [--toc] [--relative] [--offset <num_blocks>] "
282 "[--count <num_blocks>] <device_name>\n");
283}
284
285/**
286 * @}
287 */
Note: See TracBrowser for help on using the repository browser.