home *** CD-ROM | disk | FTP | other *** search
- /* fv is a binary file editor written by Chris Hooper (cdh@mtu.edu)
- * on 6-2-91 and has gone through many revisions since then.
- * Much inspiration was given by Bill Moore, the first real user!
- *
- * Author: CHRISTOPHER D HOOPER
- *
- * fv source Copyright (c) 1992 - 1998 Chris Hooper
- *
- * Modification and redistribution is strictly prohibited.
- * Sale of this software above media cost is prohibited.
- *
- * Except for above two restrictions, this software may be used for
- * any purpose, commercial or private.
- *
- * Disclaimer: This product is fit for no use, foreign or domestic.
- * Use implies knowledge you intend to destroy something.
- */
-
- #define VERSION "@(#)fv 2.20 19-Jan-98 cdh"
-
- #ifdef OS9
- _asm("_sysedit: equ 220");
- #endif
-
- #include <stdio.h>
- #include <curses.h>
- #include <string.h>
- #if !defined(_OS9000) && !defined(_OSK)
- # include <sys/types.h>
- #endif
- #include "main.h"
- #if !defined(Amiga) && !defined(OS9) && !defined(FreeBSD)
- # include <malloc.h>
- # include <unistd.h>
- # include <ctype.h>
- #endif
- #ifdef Linux
- # include <sys/ioctl.h>
- #endif
- #include <signal.h>
- #include "edit.h"
- #include "screen.h"
- #include "io.h"
-
- #ifdef Dynix
- # include <sys/types.h>
- #endif
-
- #if defined(NetBSD) || defined(Linux) || defined(__FreeBSD__)
- # define _cury cury
- # define _curx curx
- #endif
-
- #ifdef OS9
- # define _cury w_wrow
- # define _curx w_wcol
- char *strdup(char *str);
- #endif
-
- #ifdef LINT
- # include "lint.h"
- #endif
-
- #define WDISMAX 4
- #define KBUFMAX 1024
- #define HIGH_BUF_SIZE 65536
-
- uchar *buffer; /* character pointer into display buffer */
- ulong *ibuffer; /* integer pointer into display buffer */
- char *filename[256]; /* name of files currently being edited */
- char kbuffer[KBUFMAX]; /* storage area for "automatic" keystrokes */
- char out_string[512]; /* output buffering scratch space */
- char *version = VERSION; /* program version string */
- int SWAPBYTES = 0; /* both display-only displacement */
- int Swapbytes = 0; /* character cursor displacement */
- int Zmode = 1; /* cycle for display character for nil */
- int addis = 0; /* 1=address display mode on */
- int alignment = 1; /* start out with single character {1,2,4,8} */
- int buf_size = 0; /* size of display buffer */
- int chdis = 1; /* 1=character display mode on */
- int cpline = 0; /* number of characters (bytes) per line */
- int divisor = 0; /* address display divisor/modulus for bottom */
- int divisor2 = 0; /* address display divisor/modulus for left */
- int divmod = 0; /* toggle (divide or modulus) for bottom */
- int divmod2 = 0; /* toggle (divide or modulus) for left */
- int filenames = 0; /* number of files in buffer */
- int filenum = 0; /* number of file currently being edited */
- int force_ronly = 0; /* 1=force file read-only */
- int force_write = 0; /* 1=force file write mode */
- int global_direction = 0; /* direction of last search (o=forward) */
- int global_num = 0; /* number of bytes last searched against */
- int global_special[MAXLEN]; /* wildcard positions for search */
- int global_type = 0; /* type of last search (hex or character) */
- int kbuffer_size = 0; /* number of buffered keystrokes */
- int max_buf_size = 0; /* maximum size of display buffer */
- int mode = STRING; /* display/search mode (words or string) */
- int noscreen = 0; /* turn off all screen stuff */
- int ronly = 0; /* 1=file is read-only */
- int prompting = 0; /* flag for interrupt handler of search */
- int swapbytes = 0; /* word cursor displacement */
- int swapmode = 0; /* cycle for which of above three is active */
- int view_address = 0; /* file address at top left corner of screen */
- int wdis = 1; /* 1=word display mode on */
- int wdismode = 0; /* word display mode, 0=hex, 1=dec, etc */
- int wpline = 0; /* number of (4 byte) words per line */
- int wref = 0; /* refresh window because of motion or change */
- int zmode = 1; /* cycle for display chara of non-printable */
- int daddr = -1; /* current buffered address */
- int dirty = 0; /* buffer has dirty data */
- uchar global_search[MAXLEN]; /* last search data */
- ulong cursor_address = 0; /* current cursor position in file */
- ulong last_viewed = 0; /* last address relocated from */
- ulong fend = 0; /* size of file in bytes */
-
- extern ulong inbuf_size;
-
- void sigint();
- #ifndef AMIGA
- void sigquit();
- #ifndef HPUX
- void sigwinch();
- #endif
- #endif
-
- static void print_usage();
- static void kbuffer_append();
- static int parse_string();
-
- extern char *getenv();
-
-
- #ifdef Amiga
- int main(argc, argv)
- #else
- void main(argc, argv)
- #endif
- int argc;
- char *argv[];
- {
- int index = 0;
- char *ptr;
-
- while (*version != ' ')
- version++;
-
- if ((ptr = getenv("FVINIT")) != NULL)
- kbuffer_append(ptr);
-
- for (index = 1; index < argc; index++)
- if (*(ptr = argv[index]) == '-')
- for (ptr++; *ptr != '\0'; ptr++)
- switch (*ptr) {
- #ifdef EDIT_MEMORY
- case 'a': /* access memory */
- index++;
- if ((index < argc) && isdigit(*argv[index])) {
- out_string[0] = '<';
- strcpy(out_string + 1, argv[index]);
- strcat(out_string, ">");
- filename[filenames++] = strdup(out_string);
- } else {
- fprintf(stderr, "No address for -a given\n");
- print_usage(argv[0], 0);
- exit(1);
- }
- break;
- #endif
- case 'A':
- for (index = 0; index < 24; index++)
- #ifdef LITTLE_ENDIAN
- putchar(((char *) file_sz)[index ^ 3] ^ 64);
- #else
- putchar(((char *) file_sz)[index] ^ 64);
- #endif
- break;
- case 'h':
- case '?':
- case '/':
- print_usage(argv[0], 0);
- exit(0);
- case 'k': /* buffer keystrokes */
- index++;
- if (index < argc)
- kbuffer_append(argv[index]);
- else {
- fprintf(stderr, "No command for -k given\n");
- print_usage(argv[0], 0);
- exit(1);
- }
- break;
- case 'r': /* force read-only */
- force_ronly = !force_ronly;
- break;
- case 's': /* turn off screen */
- noscreen = !noscreen;
- break;
- case 'v': /* version */
- print_usage(argv[0], 1);
- printf("%s\n", version);
- exit(0);
- break;
- case 'w': /* force write mode */
- force_write = !force_write;
- break;
- default:
- fprintf(stderr, "Unknown parameter -%s\n", ptr);
- print_usage(argv[0], 0);
- exit(1);
- }
- else
- filename[filenames++] = ptr;
-
-
- if (filenames == 0) {
- fprintf(stderr, "No filename specified! ");
- print_usage(argv[0], 0);
- exit(1);
- }
-
- for (index = 0; index < filenames; index++)
- if (open_file(index))
- break;
-
- if (index < filenames)
- filenum = index;
- else
- exit(1);
-
-
- signal(SIGINT, sigint);
- #if !defined(AMIGA) && !defined(Win32)
- signal(SIGQUIT, sigint);
- #if !defined(OS9) && !defined(HPUX)
- if (!noscreen)
- signal(SIGWINCH, sigwinch);
- #endif /* !OS9 */
- #endif /* !Amiga */
-
- assign_curses();
- init();
-
- if (noscreen)
- assign_dummy();
-
- if (fend < HIGH_BUF_SIZE)
- max_buf_size = fend;
-
- if (max_buf_size < HIGH_BUF_SIZE)
- max_buf_size = HIGH_BUF_SIZE;
-
- ibuffer = (ulong *) malloc(max_buf_size + MAXLEN);
- if (ibuffer == NULL)
- error_exit("main: malloc failed");
-
- buffer = (uchar *) ibuffer;
-
- if (!kbuffer_size)
- status_filename();
- else
- wref = 1;
-
- refresh_buffer(1);
-
- if (!noscreen)
- show_addr(view_address);
-
- edit_file();
- close_file();
-
- de_init();
- exit(0);
- }
-
- void error_exit(str)
- char *str;
- {
- de_init();
- if (str)
- fprintf(stderr, str);
- exit(1);
- }
-
- ulong file_sz[] =
- {0x03081209,0x13140f10,0x08051260,0x046e6008,0x0f0f1005,0x124a4040};
-
- /************************************************************************/
- /* */
- /* Editor state machine */
- /* */
- /************************************************************************/
-
- int edit_file()
- {
- int ch = ' '; /* input character */
- int looptime = 1; /* default number of times to execute operation */
- int rollover = 1; /* if non-zero digit entered previously */
- int cref = 0; /* refresh display because of cursor motion */
- int temp; /* temp calculation */
- int temp2; /* temp calculation */
- int temp3; /* temp calculation */
- int addr;
- int addr2;
- int running = 1; /* 0=terminating */
-
- update_cursor(ON);
- if (!kbuffer_size)
- xrefresh(main_window);
- status_mode();
-
- while (running) {
- ch = get_key();
- if (((ch >= '1') && (ch <= '9')) ||
- ((ch == '0') && (rollover == 0))) {
- if (rollover)
- looptime = ch - '0';
- else
- looptime = looptime * 10 + ch - '0';
- rollover = 0;
- } else {
- if (rollover)
- looptime = 1;
-
- while (looptime-- > 0)
- switch (ch) {
- case 'a': /* toggle address display */
- wref = 1;
- addis = !addis;
-
- wpline = (COLS - addis * 10) /
- (9 * wdis + chdis * 4);
- cpline = wpline << 2;
- buf_size = (LINES - 1) * cpline;
-
- if ((cursor_address - view_address) >= buf_size) {
- cursor_address = view_address + buf_size - 1;
- ALIGN(cursor_address);
- }
-
- xmove(main_window, 0, 0);
- xclrtobot(main_window);
- break;
- case 'A': /* append bis cursor von mark to a file */
- looptime = 0;
- write_mark(cursor_address, 1);
- wref = 1;
- break;
- case 'b':
- #ifndef EMACS_FEEL
- case 2: /* ^B back one page */
- #endif
- #ifdef KEY_SR
- case KEY_SR:
- #endif
- last_viewed = view_address;
- view_address -= buf_size;
- VALIGN(view_address);
- if (view_address < 0)
- view_address = 0;
- if (cursor_address >= view_address + inbuf_size) {
- cursor_address -= buf_size;
- ALIGN(cursor_address);
- }
- wref = 1;
- break;
- case 'c': /* toggle character display */
- wref = 1;
- chdis = !chdis;
- temp = wpline;
- if (chdis == 0)
- wdis = 1;
-
- wpline = (COLS - addis * 10) /
- (9 * wdis + chdis * 4);
- cpline = wpline << 2;
- buf_size = (LINES - 1) * cpline;
-
- if (cursor_address >= view_address + inbuf_size) {
- cursor_address = view_address + buf_size - 1;
- ALIGN(cursor_address);
- }
- xmove(main_window, 0, 0);
- xclrtobot(main_window);
- break;
- /* ^C taken for SIGINT and 'q' below */
- case 'C': /* copy bis cursor von mark to file */
- looptime = 0;
- write_mark(cursor_address, 0);
- wref = 1;
- break;
- case 4: /* ^D down one half page */
- case 'd':
- if (view_address < fend - buf_size / 2) {
- last_viewed = view_address;
- view_address += buf_size / 2;
- VALIGN(view_address);
- wref = 1;
- if (cursor_address < view_address) {
- cursor_address += buf_size / 2;
- ALIGN(cursor_address);
- }
- }
- break;
- case 'D': /* delete physical area */
- break;
- case 'f':
- #ifndef EMACS_FEEL
- case 6: /* ^F forward one page */
- #endif
- #ifdef KEY_SF
- case KEY_SF:
- #endif
- if (view_address < fend - buf_size) {
- last_viewed = view_address;
- view_address += buf_size;
- VALIGN(view_address);
- wref = 1;
- if (cursor_address < view_address) {
- cursor_address += buf_size;
- ALIGN(cursor_address);
- }
- }
- break;
- case 'F': /* select new file to edit */
- #ifdef KEY_OPEN
- case KEY_OPEN:
- #endif
- temp = select_file();
- if (temp != filenum) {
- if (save_changes(1))
- break;
- close_file();
- view_address = 0;
- cursor_address = 0;
- daddr = -1;
- wref = 1;
- xmove(status_window, 0, 0);
- xclrtoeol(status_window);
- if (open_file(temp))
- filenum = temp;
- else if (open_file(filenum) == 0) {
- sprintf(out_string, "cannot reopen %s!\n",
- filename[filenum]);
- error_exit(out_string);
- }
- } else {
- xmove(status_window, 0, 0);
- xclrtoeol(status_window);
- }
- status_range(view_address, view_address + buf_size);
- status_filename();
- status_mode();
- break;
- case 'g': /* go (jump) to address */
- looptime = 0;
- temp = get_jump(view_address);
- if (temp == -1) {
- status_mode();
- break;
- }
- temp <<= divisor;
- ALIGN(temp);
- extend_end(temp);
- if ((temp >= view_address) &&
- (temp <= view_address + inbuf_size)) {
- update_cursor(OFF);
- cref = 1;
- cursor_address = temp;
- } else if ((view_address != temp) &&
- (temp >= 0) && (temp <= fend)) {
- wref = 1;
- last_viewed = view_address;
- view_address = temp;
- cursor_address = temp;
- }
- status_mode();
- break;
- case 'G': /* go to bottom of file */
- /* eventually let user enter address below and this
- would then let them Go to that address? */
- update_cursor(OFF);
-
- if (rollover == 0) { /* jump to addr */
- cursor_address = ALIGNED(looptime + 1);
- if (cursor_address > fend - 1) {
- wref = 1;
- cursor_address = ALIGNED(fend - 1);
- }
- if ((cursor_address < view_address) ||
- (cursor_address > ALIGNED(view_address +
- buf_size - 1))) {
- wref = 1;
- view_address = ALIGNED((cursor_address -
- buf_size / 2) & ~3);
- } else
- cref = 1;
- } else { /* jump to end of file */
- if (cursor_address == ALIGNED(fend - 1))
- fend = file_end();
- cursor_address = ALIGNED(fend - 1);
- temp = fend - buf_size + alignment - 1;
- ALIGN(temp);
- if (view_address < temp) {
- wref = 1;
- last_viewed = view_address;
- view_address = temp;
- } else
- cref = 1;
- }
-
- looptime = 0;
- break;
- case 7: /* ^G display current filename + cursor addr */
- status_filename();
- status_mode();
- break;
- case 'h':
- #ifdef EMACS_FEEL
- case 2: /* ^B back one page */
- #endif
- #ifdef KEY_LEFT
- case KEY_LEFT:
- #endif
- update_cursor(OFF);
- cref = 1;
-
- if (cursor_address >= alignment)
- cursor_address -= alignment;
- else if (cursor_address > 0)
- cursor_address = 0;
-
- if (cursor_address < view_address) {
- wref = 1;
- last_viewed = view_address;
- view_address -= buf_size / 2;
- VALIGN(view_address);
- if (view_address < 0)
- view_address = 0;
- }
- break;
- case 'H': /* move display (not cursor) left */
- last_viewed = view_address;
- view_address += alignment;
- #ifdef ALIGN_VIEW
- if (view_address > fend - alignment) {
- view_address = fend - 1;
- ALIGN(view_address);
- }
- #endif
- wref = 1;
- if (cursor_address < view_address)
- cursor_address = view_address;
- break;
- case 8: /* ^H Give simple help */
- #ifdef KEY_HELP
- case KEY_HELP:
- #endif
- looptime = 0;
- help_me(0);
- xtouchwin(main_window);
- xrefresh(main_window);
- break;
- case 'I': /* insert physical area */
- break;
- case 9: /* ^I toggle hex/string edit mode */
- mode = !mode;
- cref = 1;
- status_mode();
- break;
- case 'j': /* move cursor down one line */
- case 14: /* ^N - for Emacs users */
- #ifdef KEY_DOWN
- case KEY_DOWN:
- #endif
- update_cursor(OFF);
- cref = 1;
- if (cursor_address < (fend - cpline)) {
- cursor_address += cpline;
- if (cursor_address >= view_address + buf_size) {
- last_viewed = view_address;
- view_address += buf_size / 2;
- #ifdef ALIGN_VIEW
- ALIGN(view_address);
- #endif
- wref = 1;
- if (view_address > fend) {
- view_address = fend - 1;
- #ifdef ALIGN_VIEW
- ALIGN(view_address);
- #endif
- }
- }
- }
- break;
- case 'J': /* move display (not cursor) down */
- update_cursor(OFF);
- if (view_address > 0) {
- last_viewed = view_address;
- view_address -= cpline;
- if (view_address < 0)
- view_address = 0;
- if (cursor_address >= view_address + inbuf_size + cpline)
- cursor_address -= cpline;
- }
- wref = 1;
- break;
- case 'k': /* move cursor up one line */
- case 16: /* ^P - for Emacs users */
- #ifdef KEY_UP
- case KEY_UP:
- #endif
- update_cursor(OFF);
- cref = 1;
-
- if (cursor_address >= cpline)
- cursor_address -= cpline;
-
- if (cursor_address < view_address) {
- wref = 1;
- last_viewed = view_address;
- view_address -= buf_size / 2;
- #ifdef ALIGN_VIEW
- ALIGN(view_address);
- #endif
- if (view_address < 0)
- view_address = 0;
- }
- break;
- case 'K': /* move display (not cursor) up */
- update_cursor(OFF);
- if (view_address < fend - cpline) {
- last_viewed = view_address;
- view_address += cpline;
- if (cursor_address < view_address)
- cursor_address += cpline;
- }
- wref = 1;
- break;
- case 'l': /* move cursor right */
- #ifdef EMACS_FEEL
- case 6: /* ^F */
- #endif
- #ifdef KEY_RIGHT
- case KEY_RIGHT:
- #endif
- update_cursor(OFF);
- cref = 1;
- if (cursor_address < (fend - alignment)) {
- cursor_address += alignment;
- if (cursor_address >= (view_address + buf_size)) {
- wref = 1;
- last_viewed = view_address;
- view_address += buf_size / 2;
- #ifdef ALIGN_VIEW
- ALIGN(view_address);
- #endif
- if (view_address > fend)
- view_address = fend - 1;
- }
- }
- break;
- case 'L': /* move display (not cursor) right */
- last_viewed = view_address;
- view_address -= alignment;
- if (view_address < 0)
- view_address = 0;
- wref = 1;
- if (cursor_address >= view_address + inbuf_size + alignment) {
- cursor_address = view_address + inbuf_size - 1;
- ALIGN(cursor_address);
- }
- break;
- case 12: /* ^L redraw screen */
- #ifdef KEY_REFRESH
- case KEY_REFRESH:
- #endif
- #ifdef KEY_CLEAR
- case KEY_CLEAR:
- #endif
- looptime = 0;
- wref = 1;
- daddr = -1;
- if (noscreen)
- break;
-
- xclear(stdscr);
- xmove(stdscr, 0, 0);
- xclrtobot(stdscr);
- xtouchwin(main_window);
- xtouchwin(status_window);
-
- xrefresh(stdscr);
-
- break;
- case 'm': /* set mark */
- #ifdef KEY_MARK
- case KEY_MARK:
- #endif
- set_mark(cursor_address);
- break;
- case 'M': /* move to middle of screen */
- update_cursor(OFF);
- cursor_address = view_address + buf_size / 2;
- ALIGN(cursor_address);
- cref = 1;
- break;
- case '.': /* repeat last edit command - must precede ^M */
- #ifdef KEY_REDO
- case KEY_REDO:
- #endif
- if (load_ksbuf_from_hist())
- case 13: /* ^M start edit mode */
- case 10: /* ^J start edit mode */
- looptime = 0;
- addr = cursor_address - view_address;
- addr2 = addr >> 2;
- temp = ibuffer[addr2];
- temp2 = ibuffer[addr2 + 1];
- temp3 = ibuffer[addr2 + 2];
- update_cursor(OFF);
- #if !defined(Dynix) && !defined(Linux) && !defined(FreeBSD) && !defined(HPUX)
- if (!noscreen)
- raw();
- #endif
- prompting = 1;
- if (mode == STRING)
- edit_mem_string(addr);
- else
- edit_mem_base(addr, wdismode);
- prompting = 0;
- #if !defined(Dynix) && !defined(Linux) && !defined(FreeBSD) && !defined(HPUX)
- if (!noscreen) {
- noraw();
- # ifdef Solaris2
- cbreak();
- # endif
- }
- #endif
- status_mode();
- if ((temp != ibuffer[addr2]) ||
- (temp2 != ibuffer[addr2 + 1]) ||
- (temp3 != ibuffer[addr2 + 2]))
- dirty = 1;
- wref = 1;
- break;
- case 'N': /* switch search direction and re-search */
- #ifdef KEY_PREVIOUS
- case KEY_PREVIOUS:
- #endif
- global_direction = !global_direction;
- case 'n': /* search again for same thing */
- #ifdef KEY_NEXT
- case KEY_NEXT:
- #endif
- if (save_changes(1))
- break;
- wref = 1;
- update_cursor(OFF);
- prompting = 1;
- cursor_address = generic_search(cursor_address);
- ALIGN(cursor_address);
- prompting = 0;
- if ((cursor_address < view_address) ||
- (cursor_address >= view_address + inbuf_size)) {
- last_viewed = view_address;
- view_address = cursor_address;
- status_mode();
- }
- status_mode();
- daddr = -1;
- break;
- case 'o': /* rotate display character for non-printable */
- if (save_changes(1))
- break;
- wref = 1;
- zmode++;
- zmode = zmode % 12;
- init_ascii();
- break;
- case 'O': /* rotate display character for nil */
- if (save_changes(1))
- break;
- wref = 1;
- Zmode++;
- Zmode = Zmode % 12;
- init_ascii();
- break;
- /* q and Q taken for exit below */
- case 'r': /* reread/redisplay file */
- daddr = -1;
- wref = 1;
- break;
- case 'R': /* change Read-only mode */
- ronly = !ronly;
- status_mode();
- break;
- case 's': /* cycle byte swapping off, word, long, quad */
- swapbytes |= Swapbytes | SWAPBYTES;
- swapbytes += swapbytes + 1;
- if (swapbytes == 15)
- swapbytes = 0;
- if (swapmode == 1) {
- Swapbytes = swapbytes;
- swapbytes = 0;
- } else if (swapmode == 2) {
- SWAPBYTES = swapbytes;
- swapbytes = 0;
- }
- wref = 1;
- status_mode();
- break;
- case 'S': /* toggle word or character display swapping */
- swapmode = (swapmode + 1) % 3;
- switch (swapmode) {
- case 0:
- swapbytes = SWAPBYTES;
- Swapbytes = 0;
- SWAPBYTES = 0;
- break;
- case 1:
- Swapbytes = swapbytes;
- swapbytes = 0;
- SWAPBYTES = 0;
- break;
- case 2:
- SWAPBYTES = Swapbytes;
- swapbytes = 0;
- Swapbytes = 0;
- break;
- }
- wref = 1;
- status_mode();
- break;
- case 't': /* toggle hex or decimal word display */
- if (wdismode != 0)
- wdismode = -1;
- case 'T': /* cycle word display hex,dec,float,double */
- wdismode = (wdismode + 1) % WDISMAX;
- switch (wdismode) {
- case 1:
- case 2:
- if (alignment < 4)
- alignment = 4;
- break;
- case 3:
- alignment = 8;
- }
- ALIGN(cursor_address);
- VALIGN(view_address);
- wref = 1;
- status_mode();
- break;
- case 21: /* ^U up one half page */
- case 'u':
- if (view_address > 0) {
- wref = 1;
- last_viewed = view_address;
- view_address -= buf_size / 2;
- VALIGN(view_address);
- if (view_address < 0)
- view_address = 0;
- if (cursor_address >= view_address + inbuf_size) {
- /* cursor_address = view_address + inbuf_size - 1; */
- cursor_address -= buf_size / 2;
- ALIGN(cursor_address);
- }
- }
- break;
- case 'w': /* toggle word display */
- wref = 1;
- wdis = !wdis;
- if (wdis == 0)
- chdis = 1;
-
- wpline = (COLS - addis * 10) / (9 * wdis + chdis * 4);
- cpline = wpline << 2;
- buf_size = (LINES - 1) * cpline;
-
- if (cursor_address >= view_address + buf_size) {
- cursor_address = view_address + buf_size - 1;
- ALIGN(cursor_address);
- }
-
- xmove(main_window, 0, 0);
- xclrtobot(main_window);
- break;
- case 23: /* ^W write changes */
- case 'W':
- #ifdef KEY_SAVE
- case KEY_SAVE:
- #endif
- looptime = 0;
- if (save_changes(1))
- break;
- wref = 1;
- break;
- #ifndef EMACS_FEEL
- case 24: /* ^X exit program */
- #endif
- case 'q':
- case 'x':
- #ifdef KEY_EXIT
- case KEY_EXIT:
- #endif
- looptime = 0;
- if (save_changes(1))
- break;
- running = 0;
- break;
- case 3: /* ^C exit immediately - no save */
- case 'Q':
- #ifdef KEY_SEXIT
- case KEY_SEXIT:
- #endif
- dirty = 0;
- looptime = 0;
- running = 0;
- break;
- case 'z': /* relocate display, keeping cursor on addr */
- ch = get_key();
- switch (ch) {
- case '.': /* center current line */
- temp = (cursor_address - buf_size / 2);
- ALIGN(temp);
- if (temp < 0)
- temp = 0;
- break;
- case '-': /* line to bottom of screen */
- temp = cursor_address + cpline - buf_size;
- ALIGN(temp);
- if (temp < 0)
- temp = 0;
- break;
- case '+': /* bottom line to top of screen */
- temp = view_address + buf_size - cpline;
- if (temp >= fend)
- temp = fend - 1;
- ALIGN(temp);
- if (cursor_address < temp)
- cursor_address = temp;
- break;
- case 10: /* ^J line to top of screen */
- case 13: /* ^M */
- temp = cursor_address;
- break;
- default: /* unknown, stay there */
- temp = view_address;
- break;
- }
- if (view_address != temp) {
- last_viewed = view_address;
- view_address = temp;
- wref = 1;
- }
- break;
- case 'Z': /* save/exit if second Z received */
- ch = get_key();
- if (ch == 'Z') {
- looptime = 0;
- if (save_changes(0))
- break;
- running = 0;
- }
- break;
- #ifdef ZERO_START
- case '0': /* jump to start of file */
- update_cursor(OFF);
- if (view_address > 0) {
- last_viewed = view_address;
- view_address = 0;
- wref = 1;
- if (cursor_address >= view_address + inbuf_size) {
- cursor_address = view_address + inbuf_size - 1;
- ALIGN(cursor_address);
- }
- } else {
- cursor_address = 0;
- cref = 1;
- }
- break;
- #endif
- case '/': /* search forward */
- #ifdef KEY_FIND
- case KEY_FIND:
- #endif
- global_direction = -1;
- case '?': /* search backward */
- #ifdef KEY_SFIND
- case KEY_SFIND:
- #endif
- global_direction++;
-
- if (save_changes(1))
- break;
- wref = 1;
- update_cursor(OFF);
-
- prompting = 1;
-
- /* global_direction = (ch == '?') ? 1 : 0; */
- #if !defined(Dynix) && !defined(Linux) && !defined(FreeBSD) && !defined(HPUX)
- if (!noscreen)
- raw();
- #endif
- if (mode == STRING)
- cursor_address = find_str(cursor_address);
- else
- cursor_address = find_hex(cursor_address);
-
- prompting = 0;
- #if !defined(Dynix) && !defined(Linux) && !defined(FreeBSD) && !defined(HPUX)
- if (!noscreen) {
- noraw();
- # if defined(Solaris2)
- cbreak();
- # endif
- }
- #endif
-
- ALIGN(cursor_address);
-
- if ((cursor_address < view_address) ||
- (cursor_address >= view_address + inbuf_size)) {
- last_viewed = view_address;
- view_address = cursor_address;
- }
- status_mode();
- wref = 1;
- daddr = -1;
- if (looptime)
- ch = 'n';
- break;
- case '^': /* go to beginning of current display row */
- #ifndef ZERO_START
- case '0':
- #endif
- #ifdef KEY_SLEFT
- case KEY_SLEFT:
- #endif
- update_cursor(OFF);
- cursor_address = view_address +
- ((cursor_address - view_address) /
- cpline) * cpline;
- ALIGN(cursor_address);
- cref = 1;
- break;
- case '$': /* go to end of current display row */
- #ifdef KEY_SRIGHT
- case KEY_SRIGHT:
- #endif
- update_cursor(OFF);
- cursor_address = view_address +
- ((cursor_address - view_address) /
- cpline + 1) * cpline - 1;
- ALIGN(cursor_address);
- cref = 1;
- break;
- case '+': /* increase number of columns in display */
- case '=':
- wref = 1;
- wpline++;
- if (wpline > (COLS - addis * 10)/(9 * wdis + chdis * 4))
- wpline--;
- else
- cpline += 4;
- buf_size = (LINES - 1) * cpline;
-
- break;
- case '-': /* decrease number of columns in display */
- case '_':
- wref = 1;
- wpline--;
- if (wpline < 1)
- wpline++;
- else
- cpline -= 4;
- cpline = wpline << 2;
- buf_size = (LINES - 1) * cpline;
-
- if (cursor_address >= view_address + buf_size) {
- cursor_address = view_address + buf_size - 1;
- ALIGN(cursor_address);
- }
-
- xmove(main_window, 0, 0);
- xclrtobot(main_window);
- break;
- case '\'': /* jump to address of mark */
- case '`':
- looptime = 0;
- if ((temp = get_mark(-1)) != -1) {
- ALIGN(temp);
- last_viewed = cursor_address;
- if ((temp > view_address + inbuf_size - 1) ||
- (temp < view_address)) {
- view_address = temp;
- cursor_address = temp;
- wref = 1;
- } else {
- update_cursor(OFF);
- cursor_address = temp;
- cref = 1;
- }
- }
- break;
- case ')': /* cursor to bottom right corner of display */
- #ifdef KEY_END
- case KEY_END:
- #endif
- update_cursor(OFF);
- cursor_address = view_address + inbuf_size - 1;
- ALIGN(cursor_address);
- cref = 1;
- break;
- case '(': /* cursor to top left corner of display */
- #ifdef KEY_HOME
- case KEY_HOME:
- #endif
- update_cursor(OFF);
- cursor_address = view_address;
- cref = 1;
- break;
- case '<': /* increase alignment (cursor size) */
- update_cursor(OFF);
- alignment <<= 1;
- if (alignment > 8)
- alignment = 1;
- status_mode();
- cref = 1;
- ALIGN(cursor_address);
- if (cursor_address < view_address)
- cursor_address += alignment;
- #ifdef ALIGN_VIEW
- if (view_address & (alignment - 1)) {
- ALIGN(view_address);
- wref = 1;
- }
- #endif
- break;
- case '>': /* decrease alignment (cursor size) */
- update_cursor(OFF);
- alignment >>= 1;
- if (alignment == 0)
- alignment = 8;
- status_mode();
- cref = 1;
- ALIGN(cursor_address);
- #ifdef ALIGN_VIEW
- if (view_address & (alignment - 1)) {
- ALIGN(view_address);
- wref = 1;
- }
- #endif
- break;
- case '[': /* double address display divisor -- bottom */
- divisor++;
- if (divisor > 29)
- divisor = 29;
- status_range(view_address, view_address + buf_size);
- break;
- case ']': /* halve address display divisor -- bottom */
- divisor--;
- if (divisor < 0)
- divisor = 0;
- status_range(view_address, view_address + buf_size);
- break;
- case '{': /* double address display divisor - left */
- divisor2++;
- if (divisor2 > 29)
- divisor2 = 29;
- status_range(view_address, view_address + buf_size);
- wref = 1;
- break;
- case '}': /* halve address display divisor - left */
- divisor2--;
- if (divisor2 < 0)
- divisor2 = 0;
- status_range(view_address, view_address + buf_size);
- wref = 1;
- break;
- case '"': /* toggle div or mod for bottom address disp */
- divmod = !divmod;
- status_range(view_address, view_address + buf_size);
- break;
- case '~': /* toggle div or mod for left address disp */
- divmod2 = !divmod2;
- wref = 1;
- break;
- #ifdef COLON_MODE
- case ':': /* enter colon command mode prompt */
- temp = colon_mode();
- if (temp == -1)
- running = 0;
- else {
- if (temp == 1) {
- wref = 1;
- status_filename();
- }
- status_range(view_address, view_address + buf_size);
- status_mode();
- }
- break;
- #endif
- }
- if (kbuffer_size) {
- if (wref) {
- refresh_buffer(1);
- if (cursor_address < view_address)
- cursor_address = view_address;
- else if (cursor_address >= view_address + buf_size) {
- cursor_address = view_address + buf_size - 1;
- ALIGN(cursor_address);
- }
- }
- } else
- if (wref | cref) {
- if (wref) {
- if (refresh_buffer(0)) {
- view_address = last_viewed;
- refresh_buffer(1);
- }
- if (cursor_address < view_address)
- cursor_address = view_address;
- else if (cursor_address >= view_address + buf_size) {
- cursor_address = view_address + buf_size - 1;
- ALIGN(cursor_address);
- }
- if (!noscreen)
- show_addr(view_address);
- }
-
- if (!noscreen) {
- update_cursor(ON);
- #ifndef Win32
- #ifdef AMIGA
- temp = main_window->_maxy - 1;
- temp2 = main_window->_maxx - 1;
- #else
- temp = main_window->_cury;
- temp2 = main_window->_curx - 1;
- #endif
- xmove(main_window, temp, temp2);
- ch = winch(main_window);
- xaddch(main_window, ch);
- #endif
-
- xmove(main_window, temp, temp2);
- xrefresh(main_window);
- if (wref)
- xrefresh(main_window);
- }
- wref = 0;
- cref = 0;
- }
- rollover = 1;
- }
- }
-
- save_changes(1);
-
- if (!noscreen) {
- update_cursor(OFF);
- xrefresh(main_window);
- xstandend(main_window);
-
- xmove(status_window, 0, COLS - 10);
- xclrtoeol(status_window);
- }
- return(running);
- }
-
-
- static void kbuffer_append(str)
- register char *str;
- {
- char ch;
- register char *ptr;
- int len;
-
- len = parse_string(str);
-
- if (kbuffer_size + len > KBUFMAX) {
- de_init();
- fprintf(stderr, "key buffer overflow\n");
- exit(1);
- }
-
- ptr = kbuffer + kbuffer_size + len;
- kbuffer_size += len;
-
- while ((ch = *str++) != '\0')
- *--ptr = ch;
- }
-
- int get_key()
- {
- if (kbuffer_size)
- return(kbuffer[--kbuffer_size]);
-
- #ifdef OS9
- {
- int ch = xgetch(main_window) & 255;
-
- if (ch == 0xff)
- return(ESC);
- else
- return(ch);
- }
- #else
- return(xgetch(main_window));
- #endif
-
- }
-
-
- void unget_key(ch)
- char ch;
- {
- kbuffer[kbuffer_size++] = ch;
- }
-
- #define LINE(text) fprintf(stderr, text, len, "")
-
-
- static void print_usage(progname, just_name)
- char *progname;
- int just_name;
- {
- int len;
- char *program;
-
- for (program = progname; *program != '\0'; program++);
- for (--program; program > progname; program--)
- if ((*program == '/') || (*program == '\\')) {
- program++;
- break;
- }
-
- if (just_name) {
- printf("%s", program);
- return;
- }
-
- len = strlen(program);
-
- fprintf(stderr, "Usage is:\n%s [ -hrsvw ] %s%sfilename [ filename(s) ... ]\n",
- program,
- #ifdef EDIT_MEMORY
- "[ -a RANGE ] ",
- #else
- "",
- #endif
- "[ -k STRING ] ");
-
- #ifdef EDIT_MEMORY
- LINE("%*s -a = edit memory at ADDRESS[-ENDADDR or :SIZE]\n");
- #endif
- LINE("%*s -h = display this help information\n");
- LINE("%*s -k = specify initial keystrokes to perform\n");
- LINE("%*s -r = force read only mode\n");
- LINE("%*s -s = perform editing with no screen\n");
- LINE("%*s -v = print version\n");
- LINE("%*s -w = force read / write mode\n");
- fprintf(stderr, "\n Environment FVINIT specifies startup keystrokes.\n");
-
- fprintf(stderr, "\n%s\n ", version);
- #if defined(Amiga)
- fprintf(stderr, " Amiga");
- #elif defined(Win32)
- fprintf(stderr, " Win32");
- #elif defined(Dynix)
- fprintf(stderr, " Dynix");
- #elif defined(Linux)
- fprintf(stderr, " Linux");
- #elif defined(NetBSD)
- fprintf(stderr, " NetBSD");
- #elif defined(FreeBSD)
- fprintf(stderr, " FreeBSD");
- #elif defined(HPUX)
- fprintf(stderr, " HPUX");
- #elif defined(OS9)
- # if defined _OS9000
- fprintf(stderr, " OS-9000");
- # else
- fprintf(stderr, " OS-9");
- # endif
- #elif defined(SunOS)
- fprintf(stderr, " SunOS");
- #elif defined(unix)
- fprintf(stderr, " UNIX");
- #else
- fprintf(stderr, " Unknown host");
- #endif
-
- #if defined(STRICT_VI)
- fprintf(stderr, " Strict_VI");
- #endif
-
- #if defined(ZERO_START)
- fprintf(stderr, " Zero_Start");
- #endif
-
- #if defined(EMACS_FEEL)
- fprintf(stderr, " Emacs_Feel");
- #endif
-
- #if defined(ALIGN_VIEW)
- fprintf(stderr, " Align_View");
- #endif
-
- #if defined(SHOW_EXTASCII)
- fprintf(stderr, " Show_ExtASCII");
- #endif
-
- #if defined(EDIT_MEMORY)
- fprintf(stderr, " Edit_Memory");
- #endif
-
- #if defined(COLON_MODE)
- fprintf(stderr, " Colon_Mode");
- #endif
-
- #if defined(HUGE_BUFFER)
- fprintf(stderr, " Huge_Buffer");
- #endif
-
- #if defined(COLOR_CURSES)
- fprintf(stderr, " Color_Curses");
- #endif
-
- #if defined(DEBUG)
- fprintf(stderr, " Debug");
- #endif
- fprintf(stderr, "\n");
-
- exit(1);
- }
-
-
- void sigint() /* catch ^C */
- {
- if (prompting) {
- stopping = 1;
- #if defined(Solaris2) || defined(OS9)
- signal(SIGINT, (void (*)(int)) sigint);
- #endif
- #ifdef OS9
- get_key();
- #endif
- return;
- }
-
- de_init();
- exit(0);
- }
-
- #if !defined(AMIGA) && !defined(Win32)
- void sigquit() /* catch ^\ */
- {
- de_init();
- exit(0);
- }
-
- #if !defined(OS9) && !defined(HPUX)
- void sigwinch() /* catch window size changes */
- {
- struct winsize buf;
-
- if (noscreen)
- return;
-
- de_init();
-
- ioctl(1, TIOCGWINSZ, &buf);
- COLS = buf.ws_col;
- LINES = buf.ws_row;
-
- init();
-
- status_filename();
- last_viewed = view_address;
-
- refresh_buffer(0);
- show_addr(view_address);
- if (cursor_address >= view_address + buf_size) {
- cursor_address = view_address + inbuf_size - 1;
- ALIGN(cursor_address);
- }
- update_cursor(ON);
- xrefresh(main_window);
- status_mode();
- #ifdef Solaris2
- signal(SIGWINCH, (void (*)(int)) sigwinch);
- #endif
- }
- #endif /* !OS9 */
- #endif /* !AMIGA */
-
-
- #ifndef isoctal
- #define isoctal(x) ((x >= '0') && (x <= '7'))
- #endif
-
- static int parse_string(str)
- char *str;
- {
- char ch;
- register char *nstr;
- register char *ostr;
-
- ostr = str;
- nstr = str;
-
- while ((ch = *ostr++) != '\0')
- if (ch != '\\')
- *nstr++ = ch;
- else
- if (isoctal(*ostr)) {
- ch = (*ostr++ - '0');
- if (isoctal(*ostr)) {
- ch <<= 3;
- ch += (*ostr++ - '0');
- if (isoctal(*ostr)) {
- ch <<= 3;
- ch += (*ostr++ - '0');
- }
- }
- *nstr++ = ch;
- } else
- switch ((ch = *ostr++)) {
- case '\0':
- ostr--;
- break;
- case 't':
- *nstr++ = '\t';
- break;
- case 'n':
- *nstr++ = '\n';
- break;
- case 'r':
- *nstr++ = '\r';
- break;
- case 'b':
- *nstr++ = '\b';
- break;
- default:
- *nstr++ = ch;
- break;
- }
-
- *nstr = '\0';
-
- return(nstr - str);
- }
-
- #ifdef OS9
- char *strdup(char *str)
- {
- int len;
- char *newstr;
-
- len = strlen(str) + 1;
- if ((newstr = (char *) malloc(len)) == NULL)
- return(NULL);
-
- return(memcpy(newstr, str, len));
- }
- #endif
-