blob: 19693bce4ef053c9b6b54f8a693e5642fe14775b [file] [log] [blame]
/*
* Disktest
* Copyright (c) International Business Machines Corp., 2001
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Please send e-mail to yardleyb@us.ibm.com if you have
* questions or comments.
*
* Project Website: TBD
*
* $Id: dump.c,v 1.6 2009/02/26 11:43:51 subrata_modak Exp $
*
*/
#include <stdio.h> /* *printf() */
#include <string.h> /* memset(), strn***() */
#include <ctype.h> /* isprint() */
#include <stdlib.h> /* malloc(), free() */
#include "defs.h"
#include "io.h"
#include "sfunc.h"
#include "dump.h"
int format_str(size_t iBytes, const char *ibuff, size_t ibuff_siz, char *obuff, size_t obuff_siz)
{
unsigned int i;
char buff[10];
static size_t TotalBytes = 0;
if((iBytes == 0) &&
(ibuff == NULL) && (ibuff_siz == 0) &&
(obuff == NULL) && (obuff_siz == 0)) {
TotalBytes = 0;
return 0;
}
if((ibuff == NULL) || (obuff == NULL) || (iBytes < 1)) return -1;
memset(obuff, 0, obuff_siz);
sprintf(buff,"%08lX", (long)TotalBytes);
strncat(obuff, buff, (obuff_siz-1)-strlen(obuff));
for(i=0;i<iBytes;i++) {
if((i%4) == 0) strncat(obuff, " ", (obuff_siz-1)-strlen(obuff));
if((i%8) == 0) strncat(obuff, " ", (obuff_siz-1)-strlen(obuff));
sprintf(buff,"%02X ", *(ibuff+i));
strncat(obuff, buff, (obuff_siz-1)-strlen(obuff));
}
for(;i<ibuff_siz;i++) {
if((i%4) == 0) strncat(obuff, " ", (obuff_siz-1)-strlen(obuff));
if((i%8) == 0) strncat(obuff, " ", (obuff_siz-1)-strlen(obuff));
strncat(obuff, " ", (obuff_siz-1)-strlen(obuff));
}
strncat(obuff, " ", (obuff_siz-1)-strlen(obuff));
for(i=0;i<iBytes;i++) {
sprintf(buff, "%c", (isprint(*(ibuff+i))) ? *(ibuff+i) : '.');
strncat(obuff, buff, (obuff_siz-1)-strlen(obuff));
}
TotalBytes += iBytes;
return 0;
}
int format_raw(size_t iBytes, const char *ibuff, char *obuff, size_t obuff_siz)
{
unsigned int i;
char buff[10];
static size_t TotalBytes = 0;
if((iBytes == 0) && (ibuff == NULL) &&
(obuff == NULL) && (obuff_siz == 0)) {
TotalBytes = 0;
return 0;
}
if((ibuff == NULL) || (obuff == NULL) || (iBytes < 1)) return -1;
memset(obuff, 0, obuff_siz);
sprintf(buff,"%08lX ", (long)TotalBytes);
strncat(obuff, buff, (obuff_siz-1)-strlen(obuff));
for(i=0;i<iBytes;i++) {
sprintf(buff,"%02X", *(ibuff+i));
strncat(obuff, buff, (obuff_siz-1)-strlen(obuff));
}
TotalBytes += iBytes;
return 0;
}
int dump_data(FILE *stream, const char *buff, const size_t buff_siz, const size_t ofd_siz, const size_t offset, const int format)
{
size_t TotalRemainingBytes, NumBytes, ibuff_siz, obuff_siz;
char *ibuff, *obuff, *buff_curr;
buff_curr = (char *) buff;
buff_curr += offset;
TotalRemainingBytes = buff_siz;
NumBytes = 0;
ibuff_siz = ofd_siz;
obuff_siz = 12+(3*ibuff_siz)+(ibuff_siz/4)+(ibuff_siz/8)+ibuff_siz;
switch(format) {
case FMT_STR:
format_str(0, NULL, 0, NULL, 0);
break;
case FMT_RAW:
format_raw(0, NULL, NULL, 0);
break;
default:
return(-1);
}
if((ibuff = (char *) ALLOC(ibuff_siz)) == NULL) {
fprintf(stderr, "Can't allocate ibuff\n");
return(-1);
}
if((obuff = (char *) ALLOC(obuff_siz)) == NULL) {
FREE(ibuff);
fprintf(stderr, "Can't allocate obuff\n");
return(-1);
}
while(TotalRemainingBytes > 0) {
if(TotalRemainingBytes >= ibuff_siz) {
memcpy(ibuff, buff_curr, ibuff_siz);
TotalRemainingBytes -= ibuff_siz;
NumBytes = ibuff_siz;
buff_curr += NumBytes;
} else {
memcpy(ibuff, buff_curr, TotalRemainingBytes);
NumBytes = TotalRemainingBytes;
TotalRemainingBytes = 0;
}
switch(format) {
case FMT_STR:
format_str(NumBytes, ibuff, ibuff_siz, obuff, obuff_siz);
fprintf(stream, "%s\n", obuff);
break;
case FMT_RAW:
format_raw(NumBytes, ibuff, obuff, obuff_siz);
fprintf(stream, "%s\n", obuff);
break;
default:
return(-1);
}
}
FREE(ibuff);
FREE(obuff);
return 0;
}
int do_dump(child_args_t *args)
{
size_t NumBytes = 0;
OFF_T TargetLBA, TotalBytes = 0;
char *buff;
fd_t fd;
if((buff = (char *) ALLOC(args->htrsiz*BLK_SIZE)) == NULL) {
fprintf(stderr, "Can't allocate buffer\n");
return(-1);
}
memset(buff, 0, args->htrsiz*BLK_SIZE);
fd = Open(args->device, args->flags | CLD_FLG_R);
if(INVALID_FD(fd)) {
pMsg(ERR, args, "could not open %s.\n",args->device);
pMsg(ERR, args, "%s: Error = %u\n",args->device, GETLASTERROR());
return(-1);
}
TargetLBA = Seek(fd, args->start_lba*BLK_SIZE);
if(TargetLBA != (args->start_lba * (OFF_T) BLK_SIZE)) {
pMsg(ERR, args, "Could not seek to start position.\n");
CLOSE(fd);
return(-1);
}
do {
NumBytes = Read(fd, buff, args->htrsiz*BLK_SIZE);
if((NumBytes > args->htrsiz*BLK_SIZE) || (NumBytes < 0)) {
pMsg(ERR, args, "Failure reading %s\n", args->device);
pMsg(ERR, args, "Last Error was %lu\n", GETLASTERROR());
break;
}
dump_data(stdout, buff, NumBytes, 16, 0, FMT_STR);
TotalBytes += (OFF_T) NumBytes;
} while((TotalBytes < (args->htrsiz*BLK_SIZE)) && (NumBytes > 0));
FREE(buff);
CLOSE(fd);
return 0;
}