1/*
2* Disktest
3* Copyright (c) International Business Machines Corp., 2001
4*
5*
6* This program is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License as published by
8* the Free Software Foundation; either version 2 of the License, or
9* (at your option) any later version.
10*
11* This program is distributed in the hope that it will be useful,
12* but WITHOUT ANY WARRANTY; without even the implied warranty of
13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14* GNU General Public License for more details.
15*
16* You should have received a copy of the GNU General Public License
17* along with this program; if not, write to the Free Software
18* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19*
20*  Please send e-mail to yardleyb@us.ibm.com if you have
21*  questions or comments.
22*
23*  Project Website:  TBD
24*
25* $Id: dump.c,v 1.7 2009/02/26 12:02:22 subrata_modak Exp $
26*
27*/
28#include <stdio.h>		/* *printf() */
29#include <string.h>		/* memset(), strn***() */
30#include <ctype.h>		/* isprint() */
31#include <stdlib.h>		/* malloc(), free() */
32
33#include "defs.h"
34#include "io.h"
35#include "sfunc.h"
36#include "dump.h"
37
38int format_str(size_t iBytes, const char *ibuff, size_t ibuff_siz, char *obuff,
39	       size_t obuff_siz)
40{
41	unsigned int i;
42	char buff[10];
43	static size_t TotalBytes = 0;
44
45	if ((iBytes == 0) &&
46	    (ibuff == NULL) && (ibuff_siz == 0) &&
47	    (obuff == NULL) && (obuff_siz == 0)) {
48		TotalBytes = 0;
49		return 0;
50	}
51
52	if ((ibuff == NULL) || (obuff == NULL) || (iBytes < 1))
53		return -1;
54
55	memset(obuff, 0, obuff_siz);
56	sprintf(buff, "%08lX", (long)TotalBytes);
57	strncat(obuff, buff, (obuff_siz - 1) - strlen(obuff));
58	for (i = 0; i < iBytes; i++) {
59		if ((i % 4) == 0)
60			strncat(obuff, " ", (obuff_siz - 1) - strlen(obuff));
61		if ((i % 8) == 0)
62			strncat(obuff, " ", (obuff_siz - 1) - strlen(obuff));
63		sprintf(buff, "%02X ", *(ibuff + i));
64		strncat(obuff, buff, (obuff_siz - 1) - strlen(obuff));
65	}
66	for (; i < ibuff_siz; i++) {
67		if ((i % 4) == 0)
68			strncat(obuff, " ", (obuff_siz - 1) - strlen(obuff));
69		if ((i % 8) == 0)
70			strncat(obuff, " ", (obuff_siz - 1) - strlen(obuff));
71		strncat(obuff, "   ", (obuff_siz - 1) - strlen(obuff));
72	}
73	strncat(obuff, " ", (obuff_siz - 1) - strlen(obuff));
74	for (i = 0; i < iBytes; i++) {
75		sprintf(buff, "%c",
76			(isprint(*(ibuff + i))) ? *(ibuff + i) : '.');
77		strncat(obuff, buff, (obuff_siz - 1) - strlen(obuff));
78	}
79	TotalBytes += iBytes;
80	return 0;
81}
82
83int format_raw(size_t iBytes, const char *ibuff, char *obuff, size_t obuff_siz)
84{
85	unsigned int i;
86	char buff[10];
87	static size_t TotalBytes = 0;
88
89	if ((iBytes == 0) && (ibuff == NULL) &&
90	    (obuff == NULL) && (obuff_siz == 0)) {
91		TotalBytes = 0;
92		return 0;
93	}
94
95	if ((ibuff == NULL) || (obuff == NULL) || (iBytes < 1))
96		return -1;
97
98	memset(obuff, 0, obuff_siz);
99	sprintf(buff, "%08lX ", (long)TotalBytes);
100	strncat(obuff, buff, (obuff_siz - 1) - strlen(obuff));
101	for (i = 0; i < iBytes; i++) {
102		sprintf(buff, "%02X", *(ibuff + i));
103		strncat(obuff, buff, (obuff_siz - 1) - strlen(obuff));
104	}
105	TotalBytes += iBytes;
106	return 0;
107}
108
109int dump_data(FILE * stream, const char *buff, const size_t buff_siz,
110	      const size_t ofd_siz, const size_t offset, const int format)
111{
112	size_t TotalRemainingBytes, NumBytes, ibuff_siz, obuff_siz;
113	char *ibuff, *obuff, *buff_curr;
114
115	buff_curr = (char *)buff;
116	buff_curr += offset;
117	TotalRemainingBytes = buff_siz;
118	NumBytes = 0;
119	ibuff_siz = ofd_siz;
120	obuff_siz =
121	    12 + (3 * ibuff_siz) + (ibuff_siz / 4) + (ibuff_siz / 8) +
122	    ibuff_siz;
123	switch (format) {
124	case FMT_STR:
125		format_str(0, NULL, 0, NULL, 0);
126		break;
127	case FMT_RAW:
128		format_raw(0, NULL, NULL, 0);
129		break;
130	default:
131		return (-1);
132	}
133
134	if ((ibuff = (char *)ALLOC(ibuff_siz)) == NULL) {
135		fprintf(stderr, "Can't allocate ibuff\n");
136		return (-1);
137	}
138	if ((obuff = (char *)ALLOC(obuff_siz)) == NULL) {
139		FREE(ibuff);
140		fprintf(stderr, "Can't allocate obuff\n");
141		return (-1);
142	}
143
144	while (TotalRemainingBytes > 0) {
145		if (TotalRemainingBytes >= ibuff_siz) {
146			memcpy(ibuff, buff_curr, ibuff_siz);
147			TotalRemainingBytes -= ibuff_siz;
148			NumBytes = ibuff_siz;
149			buff_curr += NumBytes;
150		} else {
151			memcpy(ibuff, buff_curr, TotalRemainingBytes);
152			NumBytes = TotalRemainingBytes;
153			TotalRemainingBytes = 0;
154		}
155		switch (format) {
156		case FMT_STR:
157			format_str(NumBytes, ibuff, ibuff_siz, obuff,
158				   obuff_siz);
159			fprintf(stream, "%s\n", obuff);
160			break;
161		case FMT_RAW:
162			format_raw(NumBytes, ibuff, obuff, obuff_siz);
163			fprintf(stream, "%s\n", obuff);
164			break;
165		default:
166			FREE(ibuff);
167			FREE(obuff);
168			return (-1);
169		}
170	}
171	FREE(ibuff);
172	FREE(obuff);
173	return 0;
174}
175
176int do_dump(child_args_t * args)
177{
178	ssize_t NumBytes = 0;
179	OFF_T TargetLBA, TotalBytes = 0;
180	char *buff;
181	fd_t fd;
182
183	if ((buff = (char *)ALLOC(args->htrsiz * BLK_SIZE)) == NULL) {
184		fprintf(stderr, "Can't allocate buffer\n");
185		return (-1);
186	}
187
188	memset(buff, 0, args->htrsiz * BLK_SIZE);
189
190	fd = Open(args->device, args->flags | CLD_FLG_R);
191	if (INVALID_FD(fd)) {
192		pMsg(ERR, args, "could not open %s.\n", args->device);
193		pMsg(ERR, args, "%s: Error = %u\n", args->device,
194		     GETLASTERROR());
195		FREE(buff);
196		return (-1);
197	}
198
199	TargetLBA = Seek(fd, args->start_lba * BLK_SIZE);
200	if (TargetLBA != (args->start_lba * (OFF_T) BLK_SIZE)) {
201		pMsg(ERR, args, "Could not seek to start position.\n");
202		FREE(buff);
203		CLOSE(fd);
204		return (-1);
205	}
206
207	do {
208		NumBytes = Read(fd, buff, args->htrsiz * BLK_SIZE);
209		if ((NumBytes > args->htrsiz * BLK_SIZE) || (NumBytes < 0)) {
210			pMsg(ERR, args, "Failure reading %s\n", args->device);
211			pMsg(ERR, args, "Last Error was %lu\n", GETLASTERROR());
212			break;
213		}
214		dump_data(stdout, buff, NumBytes, 16, 0, FMT_STR);
215		TotalBytes += (OFF_T) NumBytes;
216	} while ((TotalBytes < (args->htrsiz * BLK_SIZE)) && (NumBytes > 0));
217
218	FREE(buff);
219	CLOSE(fd);
220
221	return 0;
222}
223