1 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
2 /* Copyright (C) 2002,2005 by Duane H. Hesser. All rights reserved. */
3 /* */
4 /* See the file LICENSE.EXIFPROBE for terms of use. */
5 /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- */
6
7 /* This program reads an arbitrary section of a file from */
8 /* 'start_offset' to 'end_offset', printing the data as numerical */
9 /* values in one or more of the requested formats. */
10
11
12 /* First argument is filename; section to be dumped may be specified */
13 /* by a second argument "@start:length" or by second and third */
14 /* arguments "start end". */
15
16 #ifndef lint
17 static char *ModuleId = "@(#) $Id: dump_section.c,v 1.3 2005/07/24 22:57:36 alex Exp $";
18 #endif
19
20 #include <stdio.h>
21 /* #include <stdlib.h> */
22 #include <limits.h>
23 #include <string.h>
24 #include <values.h> /* Needed for MAXINT, no matter what compiler */
25 /* may say */
26
27 #define END_OF_FILE MAXINT
28 #define NAMELENGTH 1024
29 #define TIFF_INTEL 0x4949
30 #define TIFF_MOTOROLA 0x4d4d
31 #define HERE (unsigned long)0xffffffff
32
33 extern char *optarg;
34 char *Progname;
35 extern int errno;
36
37 extern unsigned short read_ushort(FILE *,unsigned short,unsigned long);
38 extern unsigned short to_ushort(unsigned char *,unsigned short);
39 extern unsigned long read_ulong(FILE *,unsigned short,unsigned long);
40 extern unsigned long to_ulong(unsigned char *,unsigned short);
41
42
43
main(int argc,char ** argv)44 main(int argc,char **argv)
45 {
46 char *arg,*infilename,*colon;
47 unsigned long offset = 0UL;
48 unsigned long start_offset = 0UL;
49 unsigned long end_offset = END_OF_FILE;
50 int opt,i;
51 FILE *ifp;
52 unsigned long section_size = 0;
53 unsigned long lvalue;
54 unsigned short svalue;
55 unsigned short byteorder = TIFF_INTEL;
56 unsigned short snumerator,sdenominator;
57 unsigned long lnumerator,ldenominator;
58 double rvalue;
59 int show_bytes = 0;
60 int show_bytes_decimal = 0;
61 int show_bytes_hex = 0;
62 int show_short = 0;
63 int show_short_decimal = 0;
64 int show_short_hex = 0;
65 int show_long = 0;
66 int show_long_decimal = 0;
67 int show_long_hex = 0;
68 int show_rational = 0;
69 int show_long_rational = 0;
70 int show_short_rational = 0;
71
72 Progname = *argv++;
73 --argc;
74 while(argc > 2 && *argv)
75 {
76 arg = *argv;
77 if(arg && (*arg == '-'))
78 {
79 switch(*++arg)
80 {
81 case 'b': /* bytes */
82 show_bytes = 1;
83 if(*++arg == '\0')
84 {
85 show_bytes_decimal = 1;
86 show_bytes_hex = 1;
87 }
88 if(strchr(arg,'d'))
89 show_bytes_decimal = 1;
90 if(strchr(arg,'h'))
91 show_bytes_hex = 1;
92 break;
93 case 's': /* shorts */
94 show_short = 1;
95 if(*++arg == '\0')
96 {
97 show_short_decimal = 1;
98 show_short_hex = 1;
99 }
100 if(strchr(arg,'d'))
101 show_short_decimal = 1;
102 if(strchr(arg,'h'))
103 show_short_hex = 1;
104 break;
105 case 'l': /* longs */
106 show_long = 1;
107 if(*++arg == '\0')
108 {
109 show_long_decimal = 1;
110 show_long_hex = 1;
111 }
112 if(strchr(arg,'d'))
113 show_long_decimal = 1;
114 if(strchr(arg,'h'))
115 show_long_hex = 1;
116 break;
117 case 'r':
118 show_rational = 1;
119 if(*++arg == '\0')
120 {
121 show_long_rational = 1;
122 show_short_rational = 1;
123 }
124 if(strchr(arg,'l'))
125 show_long_rational = 1;
126 if(strchr(arg,'s'))
127 show_short_rational = 1;
128 break;
129 case 'i': /* Intel byteorder */
130 byteorder = TIFF_INTEL;
131 break;
132 case 'm': /* Motorola byteorder */
133 byteorder = TIFF_MOTOROLA;
134 break;
135
136 }
137 --argc;
138 ++argv;
139 }
140 else
141 break;
142 }
143
144 if(argc >= 1)
145 {
146 infilename = *argv;
147 arg = *++argv;
148 if(arg && (*arg == '@'))
149 {
150 start_offset = strtoul(++arg,(char **)0,0);
151 colon = strchr(arg,':');
152 if(colon)
153 end_offset = start_offset + strtoul(++colon,(char **)0,0) - 1;
154 }
155 else if(arg)
156 {
157 start_offset = strtoul(arg,(char **)0,0);
158 if(*++argv)
159 {
160 arg = *argv;
161 end_offset = strtoul(arg,(char **)0,0);
162 }
163 }
164 }
165
166 printf("input file %s\n",infilename);
167 printf("start_offset = %lu, ",start_offset);
168 section_size = end_offset - start_offset + 1;
169 if(end_offset == END_OF_FILE)
170 printf("end_offset = end of file\n");
171 else
172 printf("end_offset = %ld, section length = %ld\n",end_offset,section_size);
173 printf("byteorder = %2.2s\n",(char *)&byteorder);
174
175 if((ifp = fopen(infilename,"r")) != (FILE *)0)
176 {
177 if(show_bytes)
178 {
179 if(show_bytes_decimal)
180 {
181 fseek(ifp,start_offset,0);
182 offset = start_offset;
183 i = 0;
184 printf("\n=============================================\nUnsigned byte - decimal:\n");
185 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
186 {
187 svalue = fgetc(ifp);
188 printf("%#06lx/%-04lu: %-12u",offset,offset,svalue);
189 ++offset;
190 if(++i == 4)
191 {
192 putchar('\n');
193 i = 0;
194 }
195 }
196 }
197 if(show_bytes_hex)
198 {
199 printf("\n=============================================\nUnsigned byte - hex:\n");
200 fseek(ifp,start_offset,0);
201 offset = start_offset;
202 i = 0;
203 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
204 {
205 svalue = fgetc(ifp);
206 printf("%#06lx/%-04lu: %-12#x",offset,offset,svalue);
207 ++offset;
208 if(++i == 4)
209 {
210 putchar('\n');
211 i = 0;
212 }
213 }
214 }
215 }
216 if(show_short)
217 {
218 if(show_short_decimal)
219 {
220 offset = start_offset;
221 i = 0;
222 printf("\n=============================================\nUnsigned short - decimal:\n");
223 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
224 {
225 svalue = read_ushort(ifp,byteorder,offset);
226 printf("%#06lx/%-04lu: %-12u",offset,offset,svalue);
227 offset += 2;
228 if(++i == 4)
229 {
230 putchar('\n');
231 i = 0;
232 }
233 }
234 }
235 if(show_short_hex)
236 {
237 offset = start_offset;
238 i = 0;
239 printf("\n=============================================\nUnsigned short - hex:\n");
240 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
241 {
242 svalue = read_ushort(ifp,byteorder,offset);
243 printf("%#06lx/%-04lu: %-12#x",offset,offset,svalue);
244 offset += 2;
245 if(++i == 4)
246 {
247 putchar('\n');
248 i = 0;
249 }
250 }
251 }
252 }
253 if(show_long)
254 {
255 if(show_long_decimal)
256 {
257 fseek(ifp,start_offset,0);
258 offset = start_offset;
259 i = 0;
260 printf("\n=============================================\nUnsigned long - decimal:\n");
261 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
262 {
263 lvalue = read_ulong(ifp,byteorder,offset);
264 printf("%#06x/%-04lu: %-12lu",offset,offset,lvalue);
265 offset += 4;
266 if(++i == 4)
267 {
268 putchar('\n');
269 i = 0;
270 }
271 }
272 putchar('\n');
273 }
274 if(show_long_hex)
275 {
276 fseek(ifp,start_offset,0);
277 offset = start_offset;
278 i = 0;
279 printf("\n=============================================\nUnsigned long - hex:\n");
280 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
281 {
282 lvalue = read_ulong(ifp,byteorder,offset);
283 printf("%#06x/%-04lu: %-12#lx",offset,offset,lvalue);
284 offset += 4;
285 if(++i == 4)
286 {
287 putchar('\n');
288 i = 0;
289 }
290 }
291 putchar('\n');
292 }
293 }
294
295 if(show_rational)
296 {
297 if(show_long_rational)
298 {
299 fseek(ifp,start_offset,0);
300 offset = start_offset;
301 i = 0;
302 printf("\n=============================================\nUnsigned long - rational:\n");
303 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
304 {
305 rvalue = 0.0;
306 lnumerator = read_ulong(ifp,byteorder,offset);
307 ldenominator = read_ulong(ifp,byteorder,HERE);
308 if(sdenominator)
309 rvalue = (double)lnumerator / (double)ldenominator;
310 printf("%#06x/%-04lu: %-12.8f",offset,offset,rvalue);
311 offset += 8;
312 if(++i == 4)
313 {
314 putchar('\n');
315 i = 0;
316 }
317 }
318 putchar('\n');
319 }
320 if(show_short_rational)
321 {
322 fseek(ifp,start_offset,0);
323 offset = start_offset;
324 i = 0;
325 printf("\n=============================================\nUnsigned short rational:\n");
326 while((offset <= end_offset) && !feof(ifp) && !ferror(ifp))
327 {
328 rvalue = 0.0;
329 snumerator = read_ushort(ifp,byteorder,offset);
330 sdenominator = read_ushort(ifp,byteorder,HERE);
331 if(sdenominator)
332 rvalue = (double)snumerator / (double)sdenominator;
333 printf("%#06x/%-04lu: %-12.8f",offset,offset,rvalue);
334 offset += 4;
335 if(++i == 4)
336 {
337 putchar('\n');
338 i = 0;
339 }
340 }
341 putchar('\n');
342 }
343 }
344 }
345 else
346 {
347 fprintf(stderr,"%s: could not open input file \"%s\"\n",Progname,infilename);
348 perror("\tbecause");
349 exit(3);
350 }
351 exit(0);
352 }
353
354 unsigned short
read_ushort(FILE * inptr,unsigned short byteorder,unsigned long offset)355 read_ushort(FILE *inptr,unsigned short byteorder,unsigned long offset)
356 {
357 unsigned char rbuf[2];
358 unsigned long curoffset;
359 unsigned short value = 0;
360 int chpr = 0;
361
362 if(inptr /*&& !feof(inptr) && !ferror(inptr)*/)
363 {
364 clearerr(inptr);
365 curoffset = ftell(inptr);
366 if((offset != HERE) && (fseek(inptr,offset,0) == -1))
367 {
368 printf(" SEEK FAILED to read unsigned short at offset ");
369 printf("%lu",offset);
370 }
371 else if(fread(rbuf,1,sizeof(unsigned short),inptr) == sizeof(unsigned short))
372 value = to_ushort(rbuf,byteorder);
373 else
374 {
375 printf(" FAILED to read unsigned short value at offset ");
376 if(offset == HERE)
377 offset = curoffset;
378 chpr += printf("%lu",offset);
379 }
380 if(ferror(inptr))
381 {
382 chpr += printf(" (");
383 printf(strerror(errno));
384 chpr += printf(")");
385 chpr = putchar('\n');
386 }
387 else if(feof(inptr))
388 {
389 printf(" (EOF)");
390 chpr = putchar('\n');
391 }
392 }
393 return(value);
394 }
395
396 unsigned long
read_ulong(FILE * inptr,unsigned short byteorder,unsigned long offset)397 read_ulong(FILE *inptr,unsigned short byteorder,unsigned long offset)
398 {
399 unsigned char rbuf[4];
400 unsigned long curoffset;
401 unsigned long value = 0;
402 int chpr = 0;
403
404 if(inptr /* && !feof(inptr) && !ferror(inptr)*/)
405 {
406 clearerr(inptr);
407 curoffset = ftell(inptr);
408 if((offset != HERE) && (fseek(inptr,offset,0) == -1))
409 {
410 printf(" SEEK FAILED to read unsigned 32bit integer at offset ");
411 printf("%lu",offset);
412 }
413 else if(fread(rbuf,1,4,inptr) == 4)
414 value = to_ulong(rbuf,byteorder);
415 else
416 {
417 printf(" FAILED to read unsigned 32bit integer at offset ");
418 if(offset == HERE)
419 offset = curoffset;
420 chpr += printf("%lu",offset);
421 }
422 if(ferror(inptr))
423 {
424 chpr += printf(" (");
425 printf(strerror(errno));
426 chpr += printf(")");
427 putchar('\n');
428 }
429 else if(feof(inptr))
430 {
431 printf(" (EOF)");
432 chpr = putchar('\n');
433 }
434 }
435 return(value);
436 }
437
438 unsigned short
to_ushort(unsigned char * buf,unsigned short byteorder)439 to_ushort(unsigned char *buf,unsigned short byteorder)
440 {
441 unsigned short value = 0;
442
443 if(buf)
444 {
445 value = *(unsigned short *)buf;
446 #ifdef NATIVE_BYTEORDER_BIGENDIAN
447 if(byteorder == TIFF_INTEL)
448 value = (buf[1] << 8) | buf[0];
449 #else
450 if(byteorder == TIFF_MOTOROLA)
451 value = (buf[0] << 8) | buf[1];
452 #endif
453 }
454 return(value);
455 }
456
457 unsigned long
to_ulong(unsigned char * buf,unsigned short byteorder)458 to_ulong(unsigned char *buf,unsigned short byteorder)
459 {
460 unsigned long value = 0;
461
462 if(buf)
463 {
464 value = *(unsigned long *)buf;
465 #ifdef NATIVE_BYTEORDER_BIGENDIAN
466 if(byteorder == TIFF_INTEL)
467 #else
468 if(byteorder == TIFF_MOTOROLA)
469 #endif
470 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
471 }
472 return((unsigned long)value);
473 }
474
475