1 /******************************************************************************\
2 * Copyright (C) 2001 writen by Jewfish and Armoth *
3 * *
4 * Description: this codes allows a user to view and edit the hexadecimal and*
5 * and ascii values of a file. The curses library is used to *
6 * display and manipulate the output. See the README file *
7 * included for more information. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
22 * *
23 \******************************************************************************/
24
25 #include "hex.h" /* custom header */
26
27 /*#define DEBUG_LLIST*/
28 /*#define DEBUG_GOTO*/
29
30 int BASE, MAXY, resize = 0;
31 int MIN_ADDR_LENGTH;
32 hexList *head; /* linked list struct */
33 WINS *windows; /* window structure */
34 char EBCDIC[256],
35 *fpINfilename = NULL,
36 *fpOUTfilename = NULL;
37 bool printHex; /* address format */
38 bool USE_EBCDIC;
39 bool IN_HELP; /* if help displayed */
40 int hex_win_width,
41 ascii_win_width,
42 hex_outline_width,
43 ascii_outline_width;
44
45
46 /* partial EBCDIC table contributed by Ted (ted@php.net) */
47 char EBCDIC[] = {
48 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
49 '.','.','.','.','.','.','.','.','.','.','.','.','.','.' ,'.','.', /* 0 */
50 '.','.','.','.','.','.','.','.','.','.','.','.','.','.' ,'.','.', /* 1 */
51 '.','.','.','.','.','.','.','.','.','.','.','.','.','.' ,'.','.', /* 2 */
52 '.','.','.','.','.','.','.','.','.','.','.','.','.','.' ,'.','.', /* 3 */
53 ' ','.','.','.','.','.','.','.','.','.','.','.','<','(' ,'+','|', /* 4 */
54 '&','.','.','.','.','.','.','.','.','.','!','$','*',')' ,';','.', /* 5 */
55 '-','/','.','.','.','.','.','.','.','.','.',',','%','_' ,'>','?', /* 6 */
56 '.','.','.','.','.','.','.','.','.','.',':','#','@','\'','=','"', /* 7 */
57 '.','a','b','c','d','e','f','g','h','i','.','.','.','.' ,'.','.', /* 8 */
58 '.','.','j','k','l','m','n','o','p','q','.','.','.','.' ,'.','.', /* 9 */
59 '.','r','s','t','u','v','w','x','y','z','.','.','.','.' ,'.','.', /* A */
60 '.','.','.','.','.','.','.','.','.','`','.','.','.','.' ,'.','.', /* B */
61 '.','A','B','C','D','E','F','G','H','I','.','.','.','.' ,'.','.', /* C */
62 '.','.','J','K','L','M','N','O','P','Q','.','.','.','.' ,'.','.', /* D */
63 '.','R','S','T','U','V','W','X','Y','Z','.','.','.','.' ,'.','.', /* E */
64 '0','1','2','3','4','5','6','7','8','9','.','.','.','.' ,'.','.'};/* F */
65
main(int argc,char * argv[])66 int main(int argc, char *argv[]) /* main program */
67 {
68
69 int x, retval = 1; /* counters, etc. */
70 off_t val, len; /* len need to be off_t*/
71
72 windows = (WINS *) calloc(1, sizeof(WINS)); /* malloc windows */
73 head = llalloc(); /* malloc list space */
74 fpINfilename = NULL; /* allocate in and */
75 fpOUTfilename = NULL; /* out file name ptrs */
76 printHex = TRUE; /* address format */
77 USE_EBCDIC = FALSE; /*use ascii by default*/
78
79 /* get cmd line args */
80 len = parseArgs(argc, argv);
81 MIN_ADDR_LENGTH = getMinimumAddressLength(len);
82
83 use_env(TRUE); /* use env values */
84 slk_init(0); /* init menu bar */
85 init_screen(); /* init visuals */
86 init_colors();
87
88 if ((COLS < MIN_COLS) || (LINES < MIN_LINES)) /* screen's too small */
89 {
90 endwin();
91 fprintf(stderr,"\n\nThe screen size too small.\nThe minimum allowable");
92 fprintf(stderr," screen size is %dx%d\n\n", MIN_COLS, MIN_LINES + 1);
93 exit(-1);
94 }
95
96 slk_set(6, (printHex) ? "Hex Addr":"Dec Addr", 1);
97 init_fkeys(); /* define menu bar */
98
99
100 while (retval)
101 {
102 free_windows(windows);
103
104 /* calculate screen */
105 BASE = (resize > 0 && resize < COLS) ? resize:((COLS-6-MIN_ADDR_LENGTH)/4);
106 MAXY = (LINES) - 3;
107 hex_win_width = BASE * 3;
108 ascii_win_width = BASE;
109 hex_outline_width = (BASE * 3) + 3 + MIN_ADDR_LENGTH;
110 ascii_outline_width = BASE + 2;
111
112 init_menu(windows); /* init windows */
113 head = freeList(head); /* free & init head */
114 /* print origin loc */
115 mvwprintw(windows->hex_outline, 0, 1, "%0*d", MIN_ADDR_LENGTH, 0);
116
117 if (fpIN != NULL) /* if no infile... */
118 {
119 len = maxLoc(fpIN); /* get last file loc */
120 val = maxLines(len); /* max file lines */
121 for (x = 0; x <= MAXY && x<=val; x++) /* output lines */
122 outline(fpIN, x);
123 }
124
125 wmove(windows->hex, 0, 0); /* cursor to origin */
126
127 refreshall(windows); /* refresh all wins */
128 doupdate(); /* update screen */
129
130 mvwaddch(windows->scrollbar, 1, 0, ACS_CKBOARD);/* clear scroller */
131 /* get user input */
132 retval = wacceptch(windows, len);
133 }
134
135 free(fpINfilename);
136 free(fpOUTfilename);
137 freeList(head);
138
139 screen_exit(0); /* end visualizations */
140 return retval; /* return */
141 }
142
143 /********************************************************\
144 * Description: prints out debug info to a file *
145 * Returns: nothing *
146 \********************************************************/
147 /*
148 void printDebug(hexList *head, long int loc)
149 {
150 FILE *tmpofp;
151 hexList *tmpHead = head;
152
153 tmpofp = fopen("debug_llist", "a+");
154 tmpHead = head;
155
156 fprintf(tmpofp, "location undone: %08X\n", loc);
157 while (tmpHead != NULL)
158 {
159 fprintf(tmpofp, "head->loc: %08X head->val: %02X (%c)\n", tmpHead->loc, tmpHead->val, tmpHead->val);
160
161 tmpHead = tmpHead->next;
162 }
163 fprintf(tmpofp, "\n");
164
165 fclose(tmpofp);
166 }
167 */
168
169 /********************************************************\
170 * Description: parses command line arguments and *
171 * processes them. *
172 * Returns: length of file *
173 \********************************************************/
parseArgs(int argc,char * argv[])174 off_t parseArgs(int argc, char *argv[])
175 {
176 extern char *optarg; /* extern vars for */
177 extern int optind, /*opterr,*/ optopt; /* getopt() */
178
179 int val; /* counters, etc. */
180
181 /* get args */
182 while ((val = hgetopt(argc, argv, "a:i:o:r:e")) != -1)
183 {
184 switch (val) /* test args */
185 {
186 case 'a': printHex = FALSE; /* decimal addresses */
187 break;
188 /* infile */
189 case 'i': free(fpINfilename);
190 fpINfilename = strdup(optarg);
191 break;
192 /* outfile */
193 case 'o': free(fpOUTfilename);
194 fpOUTfilename = strdup(optarg);
195 break;
196
197 case 'r': resize = atoi(optarg); /* don't resize screen*/
198 break;
199
200 case 'e': USE_EBCDIC=TRUE; /*use instead of ascii*/
201 break;
202 /* help/invalid args */
203 /* help/invalid args */
204 case '?': print_usage(); /* output help */
205 if ((optopt == 'h') || (optopt == '?'))
206 exit(0); /* exit */
207 else /* illegal option */
208 exit(-1);
209 }
210 }
211 argc -= optind;
212 argv += optind;
213
214 if (argv[0])
215 {
216 free(fpINfilename);
217 fpINfilename = strdup(argv[0]);
218 }
219
220 if (fpINfilename && strcmp(fpINfilename, ""))
221 if ((fpIN = fopen(fpINfilename, "r")) == NULL)
222 exit_err("Could not open file");
223
224 return ((fpIN != NULL) ? maxLoc(fpIN):0); /* return file length */
225 }
226
227 /********************************************************\
228 * Description: Get the minimum address length for the *
229 * address column *
230 * Returns: minimum length for addresses *
231 \********************************************************/
getMinimumAddressLength(off_t len)232 int getMinimumAddressLength(off_t len)
233 {
234 char buffer[1];
235 int min_address_length;
236
237 min_address_length = snprintf(buffer, 1, "%jd", (intmax_t)len);
238
239 /* At least 8 characters wide */
240 return min_address_length > 8 ? min_address_length : 8;
241 }
242
243 /********************************************************\
244 * Description: in the event of a segmentation fault *
245 * this catches the signal and prints out *
246 * instructions on where to send a bug *
247 * report. *
248 * Returns: length of file *
249 \********************************************************/
catchSegfault(int sig)250 RETSIGTYPE catchSegfault(int sig)
251 {
252 /* Avoid unused variable warning */
253 UNUSED(sig);
254
255 endwin();
256 printf("\n\nHexcurse has encountered a segmentation fault!\n");
257 printf("\tPlease submit a full bug report to devel@jewfish.net.\n");
258 printf("\tInclude what you did to cause the segfault, and if possible\n");
259 printf("\tinclude the core dump. And for your troubles, we'll add you \n");
260 printf("\tto the Changelog. Then you can brag to your friends about it!\n");
261
262 exit(-1);
263 }
264