1/*
2 * File dump.c - dump a file/device both in hex and in ASCII.
3
4   Written by Eric Youngdale (1993).
5
6   Copyright 1993 Yggdrasil Computing, Incorporated
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
21
22static char rcsid[] ="$Id: dump.c,v 1.1 2000/10/10 20:40:27 beck Exp $";
23
24#include "../config.h"
25
26#include <stdio.h>
27#ifdef HAVE_TERMIOS_H
28#include <termios.h>
29#include <sys/ioctl.h>
30#else
31#include <termio.h>
32#endif
33#include <signal.h>
34
35FILE * infile;
36int file_addr;
37unsigned char buffer[256];
38unsigned char search[64];
39
40#define PAGE 256
41
42#ifdef HAVE_TERMIOS_H
43struct termios savetty;
44struct termios newtty;
45#else
46struct termio savetty;
47struct termio newtty;
48#endif
49
50reset_tty(){
51#ifdef HAVE_TERMIOS_H
52  if(tcsetattr(0, TCSANOW, &savetty) == -1)
53#else
54  if(ioctl(0, TCSETAF, &savetty)==-1)
55#endif
56    {
57      printf("cannot put tty into normal mode\n");
58      exit(1);
59    }
60}
61
62set_tty(){
63#ifdef HAVE_TERMIOS_H
64  if(tcsetattr(0, TCSANOW, &newtty) == -1)
65#else
66  if(ioctl(0, TCSETAF, &newtty)==-1)
67#endif
68    {
69      printf("cannot put tty into raw mode\n");
70      exit(1);
71    }
72}
73
74
75/* Come here when we get a suspend signal from the terminal */
76
77void
78onsusp (int sig)
79{
80    /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */
81    signal(SIGTTOU, SIG_IGN);
82    reset_tty ();
83    fflush (stdout);
84    signal(SIGTTOU, SIG_DFL);
85    /* Send the TSTP signal to suspend our process group */
86    signal(SIGTSTP, SIG_DFL);
87/*    sigsetmask(0);*/
88    kill (0, SIGTSTP);
89    /* Pause for station break */
90
91    /* We're back */
92    signal (SIGTSTP, onsusp);
93    set_tty ();
94}
95
96
97
98crsr2(int row, int col){
99  printf("\033[%d;%dH",row,col);
100}
101
102showblock(int flag){
103  unsigned int k;
104  int i, j;
105  lseek(fileno(infile), file_addr, 0);
106  read(fileno(infile), buffer, sizeof(buffer));
107  if(flag) {
108    for(i=0;i<16;i++){
109      crsr2(i+3,1);
110      printf("%8.8x ",file_addr+(i<<4));
111      for(j=15;j>=0;j--){
112	printf("%2.2x",buffer[(i<<4)+j]);
113	if(!(j & 0x3)) printf(" ");
114      };
115      for(j=0;j< 16;j++){
116	k = buffer[(i << 4) + j];
117	if(k >= ' ' && k < 0x80) printf("%c",k);
118	else printf(".");
119      };
120    }
121  };
122  crsr2(20,1);
123  printf(" Zone, zone offset: %6x %4.4x  ",file_addr>>11, file_addr & 0x7ff);
124  fflush(stdout);
125}
126
127getbyte()
128{
129  char c1;
130  c1 = buffer[file_addr & (PAGE-1)];
131  file_addr++;
132  if ((file_addr & (PAGE-1)) == 0) showblock(0);
133  return c1;
134}
135
136main(int argc, char * argv[]){
137  char c;
138  int nbyte;
139  int i,j;
140  if(argc < 2) return 0;
141  infile = fopen(argv[1],"rb");
142  for(i=0;i<30;i++) printf("\n");
143  file_addr = 0;
144/* Now setup the keyboard for single character input. */
145#ifdef HAVE_TERMIOS_H
146  if(tcgetattr(0, &savetty) == -1)
147#else
148	if(ioctl(0, TCGETA, &savetty) == -1)
149#endif
150	  {
151	    printf("stdin must be a tty\n");
152	    exit(1);
153	  }
154	newtty=savetty;
155	newtty.c_lflag&=~ICANON;
156	newtty.c_lflag&=~ECHO;
157	newtty.c_cc[VMIN]=1;
158  	set_tty();
159	signal(SIGTSTP, onsusp);
160
161  do{
162    if(file_addr < 0) file_addr = 0;
163    showblock(1);
164    read (0, &c, 1);
165    if (c == 'a') file_addr -= PAGE;
166    if (c == 'b') file_addr += PAGE;
167    if (c == 'g') {
168      crsr2(20,1);
169      printf("Enter new starting block (in hex):");
170      scanf("%x",&file_addr);
171      file_addr = file_addr << 11;
172      crsr2(20,1);
173      printf("                                     ");
174    };
175    if (c == 'f') {
176      crsr2(20,1);
177      printf("Enter new search string:");
178      fgets((char *)search,sizeof(search),stdin);
179      while(search[strlen(search)-1] == '\n') search[strlen(search)-1] = 0;
180      crsr2(20,1);
181      printf("                                     ");
182    };
183    if (c == '+') {
184      while(1==1){
185	while(1==1){
186	  c = getbyte(&file_addr);
187	  if (c == search[0]) break;
188	};
189	for (j=1;j<strlen(search);j++)
190	  if(search[j] != getbyte()) break;
191	if(j==strlen(search)) break;
192      };
193      file_addr &= ~(PAGE-1);
194      showblock(1);
195    };
196    if (c == 'q') break;
197  } while(1==1);
198  reset_tty();
199  fclose(infile);
200}
201
202
203
204
205