bdd.c

00001 /*
00002  * Copyright (c) 2009 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <str.h>
00032 #include <sys/typefmt.h>
00033 #include "config.h"
00034 #include "util.h"
00035 #include "errors.h"
00036 #include "entry.h"
00037 #include "bdd.h"
00038 #include "cmds.h"
00039 
00040 #include <libblock.h>
00041 #include <devmap.h>
00042 #include <errno.h>
00043 #include <assert.h>
00044 
00045 enum {
00046         /* Number of bytes per row */
00047         BPR = 16
00048 };
00049 
00050 static const char *cmdname = "bdd";
00051 
00052 /* Dispays help for bdd in various levels */
00053 void help_cmd_bdd(unsigned int level)
00054 {
00055         static char helpfmt[] =
00056             "Usage:  %s <device> [<block_number> [<bytes>]]\n";
00057         if (level == HELP_SHORT) {
00058                 printf("'%s' dump block device contents.\n", cmdname);
00059         } else {
00060                 help_cmd_bdd(HELP_SHORT);
00061                 printf(helpfmt, cmdname);
00062         }
00063         return;
00064 }
00065 
00066 /* Main entry point for bdd, accepts an array of arguments */
00067 int cmd_bdd(char **argv)
00068 {
00069         unsigned int argc;
00070         unsigned int i, j;
00071         devmap_handle_t handle;
00072         aoff64_t offset;
00073         uint8_t *blk;
00074         size_t size, bytes, rows;
00075         size_t block_size;
00076         int rc;
00077         aoff64_t ba;
00078         uint8_t b;
00079 
00080         /* Count the arguments */
00081         for (argc = 0; argv[argc] != NULL; argc ++);
00082 
00083         if (argc < 2 || argc > 4) {
00084                 printf("%s - incorrect number of arguments.\n", cmdname);
00085                 return CMD_FAILURE;
00086         }
00087 
00088         if (argc >= 3)
00089                 ba = strtol(argv[2], NULL, 0);
00090         else
00091                 ba = 0;
00092 
00093         if (argc >= 4)
00094                 size = strtol(argv[3], NULL, 0);
00095         else
00096                 size = 256;
00097 
00098         rc = devmap_device_get_handle(argv[1], &handle, 0);
00099         if (rc != EOK) {
00100                 printf("%s: Error resolving device `%s'.\n", cmdname, argv[1]);
00101                 return CMD_FAILURE;
00102         }
00103 
00104         rc = block_init(handle, 2048);
00105         if (rc != EOK)  {
00106                 printf("%s: Error initializing libblock.\n", cmdname);
00107                 return CMD_FAILURE;
00108         }
00109 
00110         rc = block_get_bsize(handle, &block_size);
00111         if (rc != EOK) {
00112                 printf("%s: Error determining device block size.\n", cmdname);
00113                 return CMD_FAILURE;
00114         }
00115 
00116         blk = malloc(block_size);
00117         if (blk == NULL) {
00118                 printf("%s: Error allocating memory.\n", cmdname);
00119                 block_fini(handle);
00120                 return CMD_FAILURE;
00121         }
00122 
00123         offset = ba * block_size;
00124 
00125         while (size > 0) {
00126                 rc = block_read_direct(handle, ba, 1, blk);
00127                 if (rc != EOK) {
00128                         printf("%s: Error reading block %" PRIuOFF64 "\n", cmdname, ba);
00129                         free(blk);
00130                         block_fini(handle);
00131                         return CMD_FAILURE;
00132                 }
00133 
00134                 bytes = (size < block_size) ? size : block_size;
00135                 rows = (bytes + BPR - 1) / BPR;
00136 
00137                 for (j = 0; j < rows; j++) {
00138                         printf("[%06" PRIxOFF64 "] ", offset);
00139                         for (i = 0; i < BPR; i++) {
00140                                 if (j * BPR + i < bytes)
00141                                         printf("%02x ", blk[j * BPR + i]);
00142                                 else
00143                                         printf("   ");
00144                         }
00145                         putchar('\t');
00146 
00147                         for (i = 0; i < BPR; i++) {
00148                                 if (j * BPR + i < bytes) {
00149                                         b = blk[j * BPR + i];
00150                                         if (b >= 32 && b < 127)
00151                                                 putchar(b);
00152                                         else
00153                                                 putchar(' ');
00154                                 } else {
00155                                         putchar(' ');
00156                                 }
00157                         }
00158                         offset += BPR;
00159                         putchar('\n');
00160                 }
00161 
00162                 if (size > rows * BPR)
00163                         size -= rows * BPR;
00164                 else
00165                         size = 0;
00166 
00167                 /* Next block */
00168                 ba += 1;
00169         }
00170 
00171         free(blk);
00172         block_fini(handle);
00173 
00174         return CMD_SUCCESS;
00175 }

Generated on Thu Jun 2 07:45:40 2011 for HelenOS/USB by  doxygen 1.4.7