2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)dump.c 1.24 05/05/15 joerg */
15 * File dump.c - dump a file/device both in hex and in ASCII.
17 * Written by Eric Youngdale (1993).
19 * Copyright 1993 Yggdrasil Computing, Incorporated
20 * Copyright (c) 1999-2004 J. Schilling
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 2
24 * as published by the Free Software Foundation.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License along with
32 * this program; see the file COPYING. If not, write to the Free Software
33 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
49 #include "../../wodim/defaults.h"
52 * Note: always use these macros to avoid problems.
54 * ISO_ROUND_UP(X) may cause an integer overflow and thus give
55 * incorrect results. So avoid it if possible.
57 * ISO_BLOCKS(X) is overflow safe. Prefer this when ever it is possible.
59 #define SECTOR_SIZE (2048)
60 #define ISO_ROUND_UP(X) (((X) + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1))
61 #define ISO_BLOCKS(X) (((X) / SECTOR_SIZE) + (((X)%SECTOR_SIZE)?1:0))
63 #define infile in_image
65 static off_t file_addr;
66 static off_t sec_addr = (off_t)-1;
67 static Uchar sector[2048];
69 static Uchar buffer[PAGE];
70 static Uchar search[64];
73 static struct sgttyb savetty;
74 static struct sgttyb newtty;
76 static struct termios savetty;
77 static struct termios newtty;
80 static void reset_tty(void);
81 static void set_tty(void);
82 static void onsusp(int sig);
83 static void crsr2(int row, int col);
84 static void readblock(void);
85 static void showblock(int flag);
86 static int getbyte(void);
87 static void usage(int excode);
93 if (ioctl(STDIN_FILENO, TIOCSETN, &savetty) == -1) {
96 if (tcsetattr(STDIN_FILENO, TCSANOW, &savetty) == -1) {
98 if (ioctl(STDIN_FILENO, TCSETAF, &savetty) == -1) {
102 comerr("Cannot put tty into normal mode\n");
104 printf("Cannot put tty into normal mode\n");
114 if (ioctl(STDIN_FILENO, TIOCSETN, &newtty) == -1) {
117 if (tcsetattr(STDIN_FILENO, TCSANOW, &newtty) == -1) {
119 if (ioctl(STDIN_FILENO, TCSETAF, &newtty) == -1) {
123 comerr("Cannot put tty into raw mode\n");
125 printf("Cannot put tty into raw mode\n");
133 * Come here when we get a suspend signal from the terminal
139 /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
140 signal(SIGTTOU, SIG_IGN);
145 signal(SIGTTOU, SIG_DFL);
146 /* Send the TSTP signal to suspend our process group */
147 signal(SIGTSTP, SIG_DFL);
150 /* Pause for station break */
153 signal(SIGTSTP, onsusp);
160 crsr2(int row, int col)
162 printf("\033[%d;%dH", row, col);
168 off_t dpos = file_addr - sec_addr;
171 dpos < 0 || (dpos + sizeof (buffer)) > sizeof (sector)) {
172 sec_addr = file_addr & ~2047;
174 readsecs(sec_addr/2048, sector, ISO_BLOCKS(sizeof (sector)));
176 lseek(fileno(infile), sec_addr, SEEK_SET);
177 read(fileno(infile), sector, sizeof (sector));
179 dpos = file_addr - sec_addr;
181 movebytes(§or[dpos], buffer, sizeof (buffer));
193 for (i = 0; i < 16; i++) {
195 if (sizeof (file_addr) > sizeof (long)) {
196 printf("%16.16llx ", (Llong)file_addr+(i<<4));
198 printf("%8.8lx ", (long)file_addr+(i<<4));
200 for (j = 15; j >= 0; j--) {
201 printf("%2.2x", buffer[(i<<4)+j]);
205 for (j = 0; j < 16; j++) {
206 k = buffer[(i << 4) + j];
207 if (k >= ' ' && k < 0x80)
215 if (sizeof (file_addr) > sizeof (long)) {
216 printf(" Zone, zone offset: %14llx %12.12llx ",
217 (Llong)file_addr>>11, (Llong)file_addr & 0x7ff);
219 printf(" Zone, zone offset: %6lx %4.4lx ",
220 (long)(file_addr>>11), (long)(file_addr & 0x7ff));
230 c1 = buffer[file_addr & (PAGE-1)];
232 if ((file_addr & (PAGE-1)) == 0)
240 errmsgno(EX_BAD, "Usage: %s [options] [image]\n",
243 fprintf(stderr, "Options:\n");
244 fprintf(stderr, "\t-help, -h Print this help\n");
245 fprintf(stderr, "\t-version Print version info and exit\n");
246 fprintf(stderr, "\t-i filename Filename to read ISO-9660 image from\n");
247 fprintf(stderr, "\tdev=target SCSI target to use as CD/DVD-Recorder\n");
248 fprintf(stderr, "\nIf neither -i nor dev= are speficied, <image> is needed.\n");
253 main(int argc, char *argv[])
257 char *opts = "help,h,version,i*,dev*";
260 char *filename = NULL;
261 char *devname = NULL;
266 save_args(argc, argv);
270 if (getallargs(&cac, &cav, opts, &help, &help, &prvers,
271 &filename, &devname) < 0) {
272 errmsgno(EX_BAD, "Bad Option: '%s'\n", cav[0]);
278 printf("devdump %s (%s)\n", CDRKIT_VERSION, HOST_SYSTEM);
283 if (filename == NULL && devname == NULL) {
284 if (getfiles(&cac, &cav, opts) != 0) {
289 if (getfiles(&cac, &cav, opts) != 0) {
290 errmsgno(EX_BAD, "Bad Argument: '%s'\n", cav[0]);
293 if (filename != NULL && devname != NULL) {
294 errmsgno(EX_BAD, "Only one of -i or dev= allowed\n");
298 if (filename == NULL && devname == NULL)
299 cdr_defaults(&devname, NULL, NULL, NULL);
301 if (filename == NULL && devname == NULL) {
303 errmsgno(EX_BAD, "ISO-9660 image not specified\n");
305 fprintf(stderr, "ISO-9660 image not specified\n");
310 if (filename != NULL)
311 infile = fopen(filename, "rb");
315 if (infile != NULL) {
318 } else if (scsidev_open(filename) < 0) {
323 comerr("Cannot open '%s'\n", filename);
325 fprintf(stderr, "Cannot open '%s'\n", filename);
330 for (i = 0; i < 30; i++)
332 file_addr = (off_t)0;
335 * Now setup the keyboard for single character input.
338 if (ioctl(STDIN_FILENO, TIOCGETP, &savetty) == -1) {
341 if (tcgetattr(STDIN_FILENO, &savetty) == -1) {
343 if (ioctl(STDIN_FILENO, TCGETA, &savetty) == -1) {
347 comerr("Stdin must be a tty\n");
349 printf("Stdin must be a tty\n");
355 newtty.sg_flags &= ~(ECHO|CRMOD);
356 newtty.sg_flags |= CBREAK;
358 newtty.c_lflag &= ~ICANON;
359 newtty.c_lflag &= ~ECHO;
360 newtty.c_cc[VMIN] = 1;
364 signal(SIGTSTP, onsusp);
366 on_comerr((void(*)(int, void *))reset_tty, NULL);
369 if (file_addr < (off_t)0) file_addr = (off_t)0;
371 read(STDIN_FILENO, &c, 1); /* FIXME: check return value */
378 printf("Enter new starting block (in hex):");
379 if (sizeof (file_addr) > sizeof (long)) {
381 scanf("%llx", &ll); /* FIXME: check return value */
382 file_addr = (off_t)ll;
385 scanf("%lx", &l); /* FIXME: check return value */
386 file_addr = (off_t)l;
388 file_addr = file_addr << 11;
394 printf("Enter new search string:");
395 fgets((char *)search, sizeof (search), stdin); /* FIXME: check return value */
396 while (search[strlen((char *)search)-1] == '\n')
397 search[strlen((char *)search)-1] = 0;
410 slen = (int)strlen((char *)search);
411 for (j = 1; j < slen; j++) {
412 if (search[j] != getbyte())
418 file_addr &= ~(PAGE-1);