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 
format_str(size_t iBytes,const char * ibuff,size_t ibuff_siz,char * obuff,size_t obuff_siz)38 int 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 
format_raw(size_t iBytes,const char * ibuff,char * obuff,size_t obuff_siz)83 int 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 
dump_data(FILE * stream,const char * buff,const size_t buff_siz,const size_t ofd_siz,const size_t offset,const int format)109 int 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 
do_dump(child_args_t * args)176 int 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