home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-09-11 | 52.4 KB | 2,250 lines |
- Subject: v13i074: Binary patch program, ported to 80286 etc.
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: rupley!local@ARIZONA.EDU
- Posting-number: Volume 13, Issue 74
- Archive-name: bpatch2
-
- Neat code and program. Dump or edit files (binary or acsii), displayed by
- 256-byte records in side-by-side hex and ascii formats. Various other
- features (eg, toggled swap within byte pairs). I spent some time tonight
- getting bpatch to work well on a Vax (at least one particular Vax) running
- BSD4.3 with NFS. The macros in ctype.h gave some problems. The code
- attached here compiles both on Microport SysV and BSD4.3, without change,
- if the proper Makefile is used. The program appears to work equally in
- the two environments. I expect that there should be little problem in
- adjusting for other flavors of BSD or SysV.
-
- There are two Makefiles now, for bsd and Sysv. Small changes in README
- and the man pages.
-
- John Rupley
- uucp: ..{ihnp4 | hao!noao}!arizona!rupley!local
- internet: rupley!local@megaron.arizona.edu
- telex: 9103508679(JARJAR)
- (H) 30 Calle Belleza, Tucson AZ 85716 - (602) 325-4533
- (O) Dept. Biochemistry, Univ. Arizona, Tucson AZ 85721 - (602) 621-3929
-
- ************************cut here******************************************
- # To unbundle, sh this file
- echo unbundling README 1>&2
- cat >README <<'AlBeRtEiNsTeIn'
-
- BPATCH.C
- Original code written by Garry M. Johnson and Steven Lisk.
-
- Neat code and program. Dump or edit files (binary or acsii), displayed
- by 256-byte records in side-by-side hex and ascii formats. Various
- other features (eg, toggled swap within byte pairs).
-
- Here converted to 80286 (Microport sysV/AT). More details in bpatch.c,
- under Change History. Some of the changes also serve to fix code that
- appeared to be broken even for a 32-bit environment.
-
- Makefile.sys5 is set for Microport SysV/AT.2.2. The code should compile
- under standard SysV environments.
-
- The man pages are changed only slightly from the original distribution.
-
- The code compiles on a Vax running BSD4.3, with Makefile.bsd, of
- course. Testing was with an AT compatible logged in as a terminal,
- with setenv TERM vt100. There may be curses/terminal problems for
- other environments. A terminal which was an adm3a equivalent was ok.
-
- Beware of using the shell escape feature!
-
- Like the previous authors, I would appreciate learning of further
- changes and improvements in the code:
-
- John Rupley
- uucp: ..{ihnp4 | hao!noao}!arizona!rupley!local
- internet: rupley!local@megaron.arizona.edu
- telex: 9103508679(JARJAR)
- (H) 30 Calle Belleza, Tucson AZ 85716 - (602) 325-4533
- (O) Dept. Biochemistry, Univ. Arizona, Tucson AZ 85721 - (602) 621-3929
-
- +++++++++++++++++++++original distribution README+++++++++++++++++++++++
- >Herewith find BPATCH - a marvelously utile utility. While not of
- >my original creation, I have been given permission to place in the
- >public domain. I have made substantial modifications to the original
- >source given to me. Specifically I cleaned it up a bit and made it
- >work with SVR2 curses. Personally, I think it's pretty neat.
- >
- >OK - for those of you who may scream by now "WHAT THE HELL IS IT ALREADY?"
- >I respond that it is a binary file editor and dump utility! That's
- >right! You can dump your file in the nicely laid out side-by-side
- >hex and ascii format or you can actually EDIT it at your terminal!
- >Yes, I have seen the BED editor that came across the network.
- >Unfortunately, it converted the entire file before and after editing.
- >Bpatch, on the other hand, works with one 256 byte page at a time.
- >It is marvelously useful for looking at things like raw disk UNIFY
- >databases and even raw disks! While the man page may not be absolutely
- >up to date, the online help is. Try the question mark (?) command.
- >
- >As always, I would love to hear about bugs/changes/enhancements/requests.
- > Steven List @ Benetics Corporation, Mt. View, CA
- > Just part of the stock at "Uncle Bene's Farm"
- > {cdp,engfocus,idi,oliveb,opusys,plx,pyramid,tolerant}!bene!luke!itkin
- >
- >Addition by the moderator:
- >I have added code, surrounded by #ifdef MOD_HAX, that gets bpatch
- >(barely?) working on my 4.2 system. I would be very interested in
- >publishing a set of diffs that's less of a hack. Oh yeah: I also
- >wrote the Makefile.
- > /Rich $alz
- +++++++++++++++++++++end of original distribution README++++++++++++++++++++
- AlBeRtEiNsTeIn
- echo unbundling Makefile.bsd 1>&2
- cat >Makefile.bsd <<'AlBeRtEiNsTeIn'
- # This may have to change on your system.
- # You may have to fiddle with various combinations of curses, termcap,
- # terminfo, etc. Good luck!
- LIBS = -lcurses -ltermcap
- #LIBS = -ltermlib
- #LIBS = -lterminfo
- #for sysV
- #LIBS = -lcurses
-
- # However you need getopt.
- #GETOPT = -lgetopt
- #not for sysV! (nor for some BSD)
- #GETOPT =
-
- # If you're running on a 4.[23] system, you probably want this.
- WORK = -DMOD_HAX
- #sysV
- #WORK =
-
- #BSD or thereabouts
- CFLAGS = -O $(WORK)
- #Microport sysV/AT, large model, for sdb debugger
- #CFLAGS = -g -Ml
-
- bpatch: bpatch.o
- $(CC) -o bpatch $(CFLAGS) bpatch.o $(GETOPT) $(LIBS)
-
- install:
- @echo Use cp to put things where you want them
- AlBeRtEiNsTeIn
- echo unbundling Makefile.sys5 1>&2
- cat >Makefile.sys5 <<'AlBeRtEiNsTeIn'
- # This may have to change on your system.
- # You may have to fiddle with various combinations of curses, termcap,
- # terminfo, etc. Good luck!
- #LIBS = -lcurses -ltermcap
- #LIBS = -ltermlib
- #LIBS = -lterminfo
- #for sysV
- LIBS = -lcurses
-
- # However you need getopt.
- #GETOPT = -lgetopt
- #not for sysV! (nor for some BSD)
- #GETOPT =
-
- # If you're running on a 4.[23] system, you probably want this.
- #WORK = -DMOD_HAX
- #sysV
- WORK =
-
- #BSD or thereabouts
- #CFLAGS = -O $(WORK)
- #Microport sysV/AT, large model, for sdb debugger
- CFLAGS = -g -Ml
-
- bpatch: bpatch.o
- $(CC) -o bpatch $(CFLAGS) bpatch.o $(GETOPT) $(LIBS)
-
- install:
- @echo Use cp to put things where you want them
- AlBeRtEiNsTeIn
- echo unbundling bpatch.1 1>&2
- cat >bpatch.1 <<'AlBeRtEiNsTeIn'
- .TH "bpatch" "1" "Benetics Local"
- .UC 4
- \" .if t .nr LL 7i
- \" .if t .nr IN .8i
- \" .if n .nr LL 70
- \" .if n .nr IN 8
- \" .fi
- \" .ad b
- .SH NAME
- bpatch - binary patch and dump file utility
- .SH SYNOPSIS
- bpatch [ -b blksize ] [ -d ] [ -D pagecnt ] [ -e ] [ -p ] [ -r reclen ] [ -s ] [ -x ] file...
- .SH DESCRIPTION
- \fIBpatch\fR allows the viewing and/or modification of files, independent of
- file type (text, executable, data file, and so forth). \fIBpatch\fR
- allows the data to either be examined at the terminal, dumped to a print
- device or file, or edited in the general manner of \fIvi(1)\fR. The
- data in the file is dumped or displayed in \fIpages\fR of 256 bytes.
- .SS Options
- .IP "-b blksize" 12
- The \fI-b\fR option specifies the blocksize of the data file. This is used
- primarily with tapes, and is allowed only with one of the dump (\fI-d\fR
- or \fI-D\fR) options. When this option is specified, the file is opened
- in readonly mode.
- .IP "-d" 12
- The \fI-d\fR option indicates that a dump (no terminal manipulation) is
- to be performed. The entire file will be dumped to standard output. No
- editing of the data is allowed and the file is opened in readonly mode.
- <DEL> interrupts a continuous display, producing a pause after the
- current record is displayed; at this point, a second <DEL> exits and
- and other character begins display of the next file.
- .IP "-D pagecnt" 12
- The \fI-D\fR option is similar to the \fI-d\fR option, with the
- following exception: the pagecnt argument limits the dump to the
- specified number of \fIpages\fR.
- .IP "-e" 12
- The \fI-e\fR option indicates that the file contains EBCDIC data and
- should be converted in the character portion of the dump.
- .IP "-p" 12
- Used with one of the \fIdump\fR options, this option causes the program
- to pause between \fIpages\fR. The program will then wait for the user
- to press either the \fIreturn\fR key to continue, or the \fIDEL\fR (or
- \fIrubout\fR) key to stop the dump.
- .IP "-r reclen" 12
- The \fI-r\fR option indicates the record length of the data within the
- dump. When specified, this option causes \fIbpatch\fR to place a colon
- (:) between the last byte of one record and the first byte of the next.
- .IP "-s" 12
- This option turns on the byte swap option. It may be toggled dynamically
- during execution (see \fI-x\fP under Commands below).
- .IP "-x" 12
- This option specifies the suppression of pages that contain only NUL
- characters. The result is that only the page header (name and page
- number) will appear for such a page. This option may only be used with
- one of the dump options.
- .SS Arguments
- .IP file 12
- Any number of files may be specified.
- .SS Commands
- All commands are valid only in the non-dump, interactive mode. Commands
- may be entered in either upper or lower case. Commands of the form '^x'
- indicate that the control character \fIx\fR is to be entered.
- .P
- All commands that request movement within a file or between files cannot
- be executed if any changes have been made. To proceed in this case, the
- user must either enter the \fIw\fR command, the \fIu\fR command, or the
- \fIr\fR command.
- .P
- Requesting a next or previous file when there is no such will cause the
- issuance of an error message.
- .P
- Note that certain commands allow/require either some text or numeric
- value. In those cases, the user should type in characters and end the
- string with either a <cr> or <DEL>.
- .IP ? 6
- Display the help screen. The help screen will remain until the user
- either redraws the screen (see \fI^r\fR) or changes pages or files.
- .IP ! 6
- Execute the following command in the shell.
- .IP backslash 6
- Display the previous page.
- .IP <cr> 6
- Display the next page.
- .IP DEL 6
- Quit the program if no changes have been made.
- .IP / 6
- This command initiates an ASCII search. The text entered on the command
- line will be used as a search string, and the file will be searched
- starting with the current page. When the string is found, the page
- containing the string will be displayed. If the string is not found, an
- apapropriate message will be displayed.
- .IP ^f 6
- Open a named file whose name will be entered on the command line and
- followed either by <cr> or DEL.
- .IP ^n 6
- Open the next file and display the first page.
- .IP ^p 6
- Open the previous file and display the first page.
- .IP ^q 6
- Quit without writing current changes.
- .IP ^r 6
- Redraw the screen.
- .IP NNN 6
- Entering a numeric value requests that the specified page be displayed.
- .IP -x 6
- Toggle the command line option represented by \fIx\fR:
- .RS 12
- .IP a 6
- Toggle display to ascii (assume data is ascii).
- .IP e 6
- Toggle display to dbcdic (assume data is ebcdic).
- .IP s 6
- Toggle byte swap.
- .RE
- .IP a 6
- Edit the ASCII display. End edits by pressing the DEL key. All other
- characters will be treated as valid input. Cursor movement keys (arrows
- and home) allow movement within the edit window. Nonprinting
- characters are displayed as dot (.) in this window.
- .IP f 6
- Display the first page in the current file.
- .IP g 6
- Display the page containing the byte address typed in following the command.
- .IP h 6
- Edit the HEXADECIMAL display. End edits by pressing DEL key. Cursor
- movement keys (arrows and home) allow movement within the edit window.
- Two keystrokes are required to modify a byte, and both must be valid
- hexadecimal values (0-9 and a-f). To cancel a change after typing one
- character, press DEL.
- .IP l 6
- Display the last page in the current file.
- .IP q 6
- Quit the file. A warning will be issued if any changes have been made
- but not written out.
- .IP r 6
- Reread the current page.
- .IP u 6
- Undo all changes to the current page.
- .IP w 6
- Write out the current page.
- .SH "SEE ALSO"
- od(1)
- AlBeRtEiNsTeIn
- echo unbundling bpatch.c 1>&2
- cat >bpatch.c <<'AlBeRtEiNsTeIn'
- /*T bpatch - A binary file patch/dump utility */
- /*S Introduction */
- /*F bpatch ***********************************************************
- * bpatch
- * by Garry M Johnson - 09/17/84
- * (C) Copyright 1984, 1985
- *
- * Change History:
- *
- * 11/29/87 - PORT TO 80286 SYSTEM (MICROPORT SYSV/AT, 2.2)
- *
- * -> sorted out nonportable int -ne char * and int -ne long (ever-
- * annoying problems for the 286); the changes should not have broken
- * the code for 32-bit int -eq char * machines; indeed, some of the
- * changes fix apparently broken code
- * -> calls to outstr() now pass only a string address; where values are to
- * be displayed, they are entered into the string with a prior
- * sprintf();
- * -> calls to errmsg() handled as for outstr(), except there is a second
- * parameter, "sleep_time", to specify the length of a sleep after message
- * display; this is *not* implemented; call of sleep dumps core -- signal
- * handling problem??
- * -> after "windowed" is set, forced all exit()'s into passing first
- * through reset() and likewise everywhere follow reset() with immediate
- * exit()
- * -> in the segment following "not interactive - keep dumping ...",
- * repaired broken code that controlled flow for the -d and -D options;
- * allow DEL interrupt of continuous dump of long file, in order to
- * quit or go to next file
- * -> in reset(), ioctl'd terminal to be as at entry
- * -> in arrow(), added vi-like cursor control
- * -> cleaned up code for formats where specification did not agree with
- * declared type for variable; same for function parameter lists; checked
- * casts and conversions to/from long; miscellaneous general cleanup
- * of the code
- * -> cleaned up the display, but lots left to be done
- *
- *
- * REMAINING MINOR BUGS AND INFELICITIES AND WISH LIST --
- *
- * -> spawn a properly working interactive shell; probably just need
- * a fork and a full reset() under "!" option
- * -> easy repeat of string search to find next occurrence; highlight
- * string positions in the display; put edit cursor at start of string
- * -> in debug mode, allow backspace over command entered, to cancel it
- * -> errmsg() display not nice, if have several messages output in
- * sequence; no pause in errmsg() (sleep not working?)
- * -> column under pointer not always erased (local clrtoeol problem ??)
- * -> irregular passing of pointers to record and related arrays
- * -> most of the external vars should be local to main()
- * -> signal handling?
- * -> file closing?
- *
- * COMMENTS --
- *
- * -> thanks to Steven List and Garry Johnson for a very useful program;
- * it's a nice way for one who is lazy to avoid a lot of compilation
- * when what is wanted is a small change in data; the code is easy to
- * read -- again compliments to the authors;
- * -> these modifications are hacks of the previous authors' code; the
- * modified program has not been hardened, although I tried to check
- * its operation under limit conditions; please be careful in using it
- * -> like the authors, I would appreciate receiving a copy of any
- * improvements
- *
- * John Rupley, Dept. Biochemistry, Univ. Arizona, Tucson, AZ 85721
- * {ihnp4 | hao!noao}!arizona!rupley!local or rupley!local@megaron.arizona.edu
- *
- ******************************************************************************
- *
- * 03/05/86 - added further terminal independence
- * added use of ioctl (see main and mstdin)
- * added -D versus -d command line option
- * added use of standard getopt
- * cleaned up code, eliminated function "ikf"
- * added original versions of ezlib functions, such as
- * icc, setterm, cm, mstdin, erase, length, move
- * added ^R, ^Q, ^N, and ^P commands
- * added ^F, !, and ^X (-X) commands
- * changed name to "bpatch"
- * added direct address command (g)
- * added ASCII search capability
- * 07/07/86 - converted to use curses
- * modified direct addressing to use suffixes
- * updated HELP function
- *
- * Steven List @ Benetics Corporation, Mt. View, CA
- * {cdp,engfocus,idi,oliveb,plx,tolerant}!bene!luke!itkin
- *********************************************************************/
- /*E*/
- /*S includes, globals, and defines */
- /*Page Eject*/
- #include <curses.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- static int pbrk = 0;
- struct stat sb;
-
- void icc ();
- void copyrec ();
- void schwapp ();
-
- /* added declarations, mostly for cleanliness */
- extern long lseek();
- extern long atol();
- extern char *strncpy();
- extern void exit();
- extern unsigned sleep(); /* signal problems ??? if sleep called */
- extern void perror();
-
- /* set up for calls to outstr and errmsg, etc, */
- /* by use of sprintf to fill outbuf */
- char outbuf[512];
-
- /* ------------------------------------------------------------ */
- /* Some defines added by the moderator to get it work on 4.2 */
- /* ------------------------------------------------------------ */
- #ifdef MOD_HAX
- /* Fifos? We ain't got no steenkin' fifos. */
- /* #define S_IFIFO 123450 */
- /* "Spelling differences." */
- #define beep() fprintf (stderr, "\007")
- /* #define cbreak() crmode() */
- /* Our curses doesn't translate keypad keys to single characters. */
- #define keypad(a, b) /* null */ /* orig defines */
- #define KEY_UP '\0' /* '^' */ /* by MOD_HAX */
- #define KEY_DOWN '\0' /* 'v' */ /* not portable */
- #define KEY_LEFT '\0' /* '<' */
- #define KEY_RIGHT '\0' /* '>' */
- #define KEY_HOME '\0' /* '@' */
- #endif /* MOD_HAX */
-
- /* vi-like cursor control = vi keys, as control characters */
- /* this is a hack, and I hope does not interfere with keypad() */
- #define VI_UP ('K' - 0x40)
- #define VI_DOWN ('J' - 0x40)
- #define VI_LEFT ('H' - 0x40)
- #define VI_RIGHT ('L' - 0x40)
- #define VI_HOME ('G' - 0x40)
-
- #define SLEEP_TIME (unsigned )0 /* a small pause after errmsg */
- /* does not work -- signals?? */
- /* ------------------------------------------------------------ */
- /* Some convenient defines */
- /* ------------------------------------------------------------ */
-
- #define DEL '\177'
- #define HEX 1
- #define ALPHA 0
-
- /* ------------------------------------------------------------ */
- /* general purpose identification and control variables */
- /* ------------------------------------------------------------ */
-
- char filename[64]; /* current file being examined */
- char record[16][16]; /* record (page) buffer */
- char unch_rec[16][16]; /* record before any changes */
- int zp; /* current input character */
-
- int block = 0; /* block size if -b in command */
- int block_spec; /* true if file is block special */
- int bytes = 0; /* number of bytes from last read */
- int char_spec; /* true if file is char special */
- int debug = 0; /* true if debug is turned on */
- int dir_spec; /* true if file is directory */
- int dump = 0; /* nonzero if dump instead of change */
- int Dump = 0; /* store of value with -D option */
- int ebcdic = 0; /* true if -e option */
- int fifo_spec; /* true if file is fifo */
- int honly = 0; /* true if dump is to be hex only */
- int mod = 0; /* true if record has been modified */
- int pause_opt = 0; /* true if -p option */
- int rawfile = 0; /* true if file is c/b/p */
- int reclen = 0; /* record length, if -r */
- int recno = 0; /* current record (page) number */
- int stay = 0; /* true if no position change */
- int swab_opt = 0; /* true if byte swapping is on */
- int windowed = 0; /* true if windowing - not dump */
-
- long position = 0; /* byte address in file */
-
- WINDOW *hexwin = NULL;
- WINDOW *alphawin = NULL;
- WINDOW *errwin = NULL;
-
- #ifdef MOD_HAX
- #else /* use original code... */
- /* plus some more for restoring terminal function */
- struct termio asis, aswas;
- #endif /* MOD_HAX */
-
- /*S main - control all the work from here */
- /*H main *************************************************************
- *
- * main
- *
- * set up the globals, initilize the state, and process the file
- *
- *********************************************************************/
- /*E*/
- main (argc, argv)
- int argc;
- char *argv[];
- {
- extern WINDOW *subwin ();
- extern WINDOW *newwin ();
-
- register char *cp; /* general purpose char ptr */
- extern char *gets (); /* get string from stdin */
- char m = '\017'; /* mask for hex edit */
- char response[512]; /* general purpose buffer */
- int z; /* character read in */
-
- int breakp (); /* signal trapping function */
- int c; /* current screen column */
- int change = 0; /* true if cmd line option toggled */
- int fid; /* file descriptor */
- int firstfile; /* arg # of first file in cmd line */
- int h; /* temp for hex edit */
- int i; /* general purpose loop index */
- int j; /* general purpose loop index */
- int r; /* current screen row */
- int hexc; /* current cursor column in hexwin */
-
- long byteaddr; /* planned byte address for 'G' */
- long size; /* file size in bytes */
- long status; /* EOF if at end of file or error */
-
- extern int optind; /* getopt index into argv */
- extern char *optarg; /* getopt pointer to opt arg */
-
- extern long getnum ();
- extern char *instr (); /* get a string from the cmd line */
- extern int reset (); /* exit function - reset terminal */
-
- /* ------------------------------------------------------------ */
- /* set up signal handling */
- /* ------------------------------------------------------------ */
-
- if (!dump) signal (SIGINT, breakp);
-
- signal (SIGTERM, reset);
-
- /* ------------------------------------------------------------ */
- /* process command line arguments */
- /* ------------------------------------------------------------ */
-
- while ((i = getopt (argc, argv, "r:dD:b:pxXse")) != EOF)
- {
- switch (i)
- {
- case 'b': /* blocking */
- block = atoi (optarg);
- if (block < 1 || block > 10240)
- {
- fprintf (stderr,
- "invalid block size: %d\n", block);
- exit (1);
- }
- break;
- case 'd': /* straight dump - no limit */
- dump = -1;
- break;
- case 'D': /* dump - page count spec */
- dump = atoi (optarg);
- Dump = dump;
- break;
- case 'e': /* file is ebcdic */
- ebcdic = 1;
- break;
- case 'p': /* pause between pages - dump */
- pause_opt = 1;
- break;
- case 'r': /* record length for dump */
- reclen = atoi (optarg);
- break;
- case 's': /* byte swapping required */
- swab_opt = 1;
- break;
- case 'x': /* hex dump only */
- honly = 1;
- break;
- case 'X':
- debug = 1;
- break;
- default: /* uhoh */
- fprintf (stderr,
- "usage: bpatch [ -b blocksz ] [ -d<ump> ] [ -D pagecnt ] [ -e<bcdic> ]\n");
- fprintf (stderr,
- " [ -p<ause> ] [ -r reclen ] [ -s<wap bytes> ] [ -x<only> ]\n");
- exit (1);
- }
- }
-
- /* ------------------------------------------------------------ */
- /* check for valid combinations of options */
- /* ------------------------------------------------------------ */
-
- if ((honly || block || reclen || pause_opt ) && !dump)
- {
- fprintf (stderr, "-x|-b|-r|-p requires -d or -D\n");
- exit (2);
- }
-
- /* ------------------------------------------------------------ */
- /* At least one file name must be specified on the cmd line */
- /* ------------------------------------------------------------ */
-
- if (optind == argc)
- {
- fprintf (stderr, "no file name(s) specified\n");
- exit (2);
- }
-
- /* ------------------------------------------------------------ */
- /* set up the screen, if this is an interactive session */
- /* ------------------------------------------------------------ */
-
- if (!dump)
- {
- windowed = 1;
- initscr ();
- nonl ();
- noecho ();
- cbreak ();
- keypad (stdscr, TRUE);
- hexwin = subwin (stdscr, 16, 48, 4, 4);
- keypad (hexwin, TRUE);
- alphawin = subwin (stdscr, 16, 16, 4, 57);
- keypad (alphawin, TRUE);
- errwin = subwin (stdscr, 1, 80, 23, 0);
-
- #ifdef MOD_HAX
- /* This is not exactly what the original code does,
- but it's good enough. -r$ */
- raw();
- #else /* use original code... */
- ioctl (0, TCGETA, &asis);
- aswas = asis; /* save termio stuff for later restore */
- asis.c_cc[VINTR] = '\0';
- asis.c_iflag &= ~IXON;
- asis.c_iflag &= ~IXOFF;
- asis.c_iflag &= ~IXANY;
- ioctl (0, TCSETA, &asis);
- #endif /* MOD_HAX */
- }
-
- /* ------------------------------------------------------------ */
- /* save the first file's index for backing up later */
- /* ------------------------------------------------------------ */
-
- firstfile = optind;
-
- /* ------------------------------------------------------------ */
- /* open the first file */
- /* ------------------------------------------------------------ */
-
- for (fid = -1; fid < 0 && optind < argc;)
- {
- fid = ckfile (argv[optind], &size);
- if (fid < 0) optind++;
- }
- if (fid < 0)
- {
- fprintf (stderr, "could not handle the file list\n");
- reset (0);
- exit (2);
- }
-
- strncpy (filename, argv[optind], sizeof filename);
-
- if (block != 0)
- {
- size = -1;
- }
-
- recno = 0;
- stay = 0;
- mod = 0;
- status = 0;
-
- /* ------------------------------------------------------------ */
- /* Until the user exits... */
- /* ------------------------------------------------------------ */
-
- if (!dump) clear ();
-
- while (status != EOF)
- {
- /* ------------------------------------------------------------ */
- /* change of location - read and display */
- /* ------------------------------------------------------------ */
- if (stay == 0)
- {
- position = lseek (fid, ((long )recno) * 256, 0);
-
- if ((bytes = bread (fid, record, 256, block)) < 0)
- {
- sprintf(outbuf, "error on reading file %s", filename);
- errmsg (outbuf, SLEEP_TIME);
- status = EOF;
- continue;
- }
- if (bytes > 0)
- {
- if (swab_opt) schwapp (record, 256);
-
- copyrec (record, unch_rec, sizeof record);
-
- if (!dump) clear ();
- show (bytes, record, filename, size, recno,
- position, m,reclen, dump, ebcdic, swab_opt,
- block, honly);
- }
- mod = 0;
- }
- /* ------------------------------------------------------------ */
- /* not interactive - keep dumping or open next file */
- /* ------------------------------------------------------------ */
- /* major changes in control of flow */
- /* first records of multiple-files now dump */
- /* core is not dumped at end of filelist */
- /* can break with DEL into a long dump */
- if (dump)
- {
- if (dump > 0) dump--;
- if ((dump < 0 && bytes == 0) || dump == 0)
- {
- if (Dump) dump = Dump;
- if (optind == argc) status = EOF;
- else
- {
- close (fid);
- fid = -1;
- for (optind++; fid < 0 && optind < argc;)
- {
- fid = ckfile (argv[optind], &size);
- if (fid < 0) optind++;
- }
- if (fid < 0)
- {
- status = EOF;
- continue;
- }
-
- strncpy (filename, argv[optind], sizeof filename);
-
- if (block != 0)
- {
- size = -1;
- }
- recno = 0;
- stay = 0;
- status = lseek (fid, (long)0, 0);
- }
- }
- else
- {
- ++recno;
- }
- /* ------------------------------------------------------------ */
- /* if pause, beep and wait */
- /* ------------------------------------------------------------ */
- /* settings to bypass show() */
- /* and go to read of next file */
- /* if type DEL during file display */
- if (status != EOF && (pause_opt || pbrk))
- {
- if (pbrk)
- {
- bytes = 0;
- dump = -1;
- stay = 1;
- }
- pbrk = 0;
- fprintf (stderr, "\007");
- gets (response);
-
- if (pbrk) status = EOF;
- }
-
- continue;
- }
- /* ------------------------------------------------------------ */
- /* if we got here, this is an interactive session */
- /* ------------------------------------------------------------ */
- stay = 0;
- /* ------------------------------------------------------------ */
- /* get the user's command */
- /* ------------------------------------------------------------ */
- response[0] = EOF;
- mvaddstr (22, 0, "> ");
- clrtoeol ();
- refresh ();
- zp = getch ();
-
- if (debug && !dump)
- {
- /* cheap cleanup of errwin */
- errmsg ("", SLEEP_TIME);
- if (isascii (zp) && isprint (zp))
- {
- sprintf (outbuf, "command entered is %c", (char )zp);
- errmsg (outbuf, 0);
- }
- else
- {
- sprintf (outbuf, "command entered is ^%c (%#x)", (char )zp + '@', zp);
- errmsg (outbuf, 0);
- }
- getch ();
- }
-
- /* assume normal ascii character sequence */
- if ((zp >= 'a') && (zp <= 'z'))
- zp = zp - 0x20;
- /* ------------------------------------------------------------ */
- /* here we go - what does the user want? */
- /* ------------------------------------------------------------ */
- refresh ();
- errmsg ("", SLEEP_TIME);
- switch (zp)
- {
- case '!': /* shell escape */
- echo ();
- move (23,0);
- clrtoeol ();
- addstr ("shell command: ");
- refresh ();
- getstr (response);
- clear ();
- nl ();
- system (response);
- noecho ();
- nonl ();
- move (23,0);
- standout ();
- addstr (" <Press any key> ");
- standend ();
- clrtoeol ();
- refresh ();
- getch ();
- break;
-
- case '?': /* HELP */
- clear ();
- dbg_msg ("Help");
- dohelp ();
- break;
-
- case '/': /* search for a string */
- stay = 1;
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- }
- else search (fid);
- break;
-
- case '-': /* toggle options */
- zp = getch ();
- stay = 1;
- change = 0;
- switch (zp)
- {
- case 'a': /* ascii */
- if (ebcdic)
- {
- dbg_msg ("toggle to ascii");
- change = 1;
- }
- ebcdic = 0;
- break;
-
- case 'e': /* ebcdic */
- if (ebcdic == 0)
- {
- dbg_msg ("toggle to ebcdic");
- change = 1;
- }
- ebcdic = 1;
- break;
-
- case 's': /* swab */
- dbg_msg ("toggle byte swap");
- change = 1;
- schwapp (record, 256);
- swab_opt = !swab_opt;
- break;
- }
- if (change)
- {
- clear ();
- show (bytes, record, filename, size,
- recno, position, m,reclen, dump,
- ebcdic, swab_opt, block, honly);
- }
-
- break;
-
- case '\022': /* redraw screen (^R) */
- clear ();
- show (bytes, record, filename, size, recno,
- position, m, reclen, dump, ebcdic,
- swab_opt, block, honly);
- stay = 1;
- break;
-
- case '\030': /* toggle debug (^X) */
- debug = !debug;
- stay = 1;
- break;
-
- case '\006': /* new file (^F) */
- close (fid);
- fid = ckfile (cp = instr (), &size);
- if (fid < 0)
- {
- fid = ckfile (filename, &size);
- }
- else
- {
- strncpy (filename, cp, sizeof filename);
- stay = 0;
- recno = 0;
- }
- break;
-
- case '\016': /* next file (^N) */
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else if (optind == (argc - 1))
- {
- errmsg ("No more files", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- close (fid);
- for (fid = -1, optind++; fid < 0 && optind < argc;)
- {
- fid = ckfile (argv[optind], &size);
- if (fid < 0) optind++;
- }
- if (fid < 0)
- {
- errmsg ("could not handle the file list", SLEEP_TIME);
- reset (0);
- exit (0);
- }
- strncpy (filename, argv[optind], sizeof filename);
- stay = 0;
- recno = 0;
- }
- break;
-
- case '\020': /* prev file (^P) */
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else if (optind == firstfile)
- {
- errmsg ("No previous file", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- close (fid);
- for (fid = -1, optind--; fid < 0 && optind >= firstfile;)
- {
- fid = ckfile (argv[optind], &size);
- if (fid < 0) optind--;
- }
- if (fid < 0)
- {
- errmsg ("could not handle the file list", SLEEP_TIME);
- reset (0);
- exit (0);
- }
- strncpy (filename, argv[optind], sizeof filename);
- stay = 0;
- recno = 0;
- }
- break;
-
- case '\021': /* quit absolutely (^Q) */
- status = EOF;
- break;
-
- case DEL: /* quit with check */
- case 'Q': /* quit */
- if (mod)
- {
- errmsg ("No write since last change!", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- status = EOF;
- }
- break;
-
- case '\\': /* back up 1 record */
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- if (recno > 0)
- {
- --recno;
- stay = 0;
-
- status = lseek (fid, ((long )recno) * 256, 0);
- if (status < 0)
- {
- move (22, 0);
- clrtoeol ();
- perror (filename);
- errmsg ("error positioning in file", SLEEP_TIME);
- beep ();
- ++recno;
- stay = 1;
- }
- }
- else
- {
- errmsg ("No previous records", SLEEP_TIME);
- beep ();
- stay = 1;
- }
- }
- break;
-
- case 'F': /* go to first record */
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- status = lseek (fid, (long)0, 0);
- recno = 0;
- }
- break;
-
- case 'L': /* go to last record */
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- position = lseek (fid, (long)0, 2);
- recno = position / 256;
- j = position % 256;
- if (j == 0) --recno;
- status = lseek (fid, ((long )recno)*256, 0);
- }
- break;
-
- case 'U': /* undo changes */
- stay = 1;
- mod = 0;
- copyrec (unch_rec, record, sizeof record);
- clear ();
- show (bytes, record, filename, size, recno,
- position, m,reclen, dump, ebcdic, swab_opt,
- block, honly);
- break;
-
- case 'R': /* re-read record */
- status = lseek (fid, ((long )recno)*256, 0);
- break;
-
- case '0': /* go to some address */
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- byteaddr = getnum (zp, FALSE);
- stay = 1;
- sprintf (outbuf, "Position to byte %ld", byteaddr);
- errmsg (outbuf, 0);
- if (!rawfile && byteaddr > size)
- {
- errmsg ("Address outside file", SLEEP_TIME);
- beep ();
- }
- else if ((int )(byteaddr / 256) != recno)
- {
- recno = byteaddr / 256;
- status = lseek (fid, ((long )recno)*256, 0);
- stay = 0;
- }
- }
- break;
-
- case 'A': /* alpha modify */
- stay = 1;
- r = c = 0;
- dbg_msg ("edit ascii");
- if (bytes == 0) break;
- touchwin (stdscr);
- refresh ();
- wmove (alphawin, r, c);
- touchwin (alphawin);
- wrefresh (alphawin);
-
- while ((z = wgetch (alphawin)) != DEL)
- {
- if (!arrow (z, &r, &c))
- {
- if (isascii (z))
- {
- if (isprint (z)) waddch (alphawin, z);
- else waddch (alphawin, '.');
-
- if (ebcdic) icc (&z, 1,"AE");
-
- record[r][c] = z;
- mod = 1;
-
- hexc = c * 3;
- wmove (hexwin, r, hexc);
- if (record[r][c] < '\0')
- {
- wprintw (hexwin, "%x%x", (record[r][c] >> 4) & m, record[r][c] & m);
- }
- else
- {
- wprintw (hexwin, "%02x", record[r][c]);
- }
- wrefresh (hexwin);
-
- }
- else
- {
- beep ();
- }
-
- if (c == 15)
- {
- if (r == 15) beep ();
- else
- {
- c = 0;
- ++r;
- }
- }
- else
- {
- c++;
- }
- }
- if (r * 16 + c >= bytes)
- {
- beep ();
- r = (bytes - 1) / 16;
- c = (bytes - 1) % 16;
- }
-
- wmove (alphawin, r, c);
- wrefresh (alphawin);
- }
-
- break;
-
- case 'H': /* hex modify */
- dbg_msg ("edit hex");
- stay = 1;
- r = c = hexc = 0;
- if (bytes == 0) break;
- touchwin (stdscr);
- refresh ();
- wmove (hexwin, r, hexc);
- touchwin (hexwin);
- wrefresh (hexwin);
-
- while ((z = wgetch (hexwin)) != DEL)
- {
- if (!arrow (z, &r, &c))
- {
- hexc = c * 3;
- if ((z >= 'a') && (z <= 'z'))
- z = z - 0x20;
- if (!(((z >= '0') && (z <= '9')) || ((z >= 'A') && (z <= 'F'))))
- {
- beep ();
- }
- else
- {
- if (z >= 'A')
- waddch (hexwin, tolower (z));
- else
- waddch (hexwin, z);
- wrefresh (hexwin);
-
- if (z > '9') z -= 7;
-
- h = (z & m) << 4;
-
- while (2)
- {
- z = EOF;
- z = getch ();
- if (z == EOF)
- {
- pbrk = 0;
- h = -1;
- break;
- }
- if ((z >= 'a') && (z <= 'z'))
- z = z - 0x20;
- if (!(((z >= '0') && (z <= '9')) || ((z >= 'A') && (z <= 'F'))))
- {
- beep ();
- }
- else
- {
- if (z >= 'A')
- waddch (hexwin, tolower (z));
- else
- waddch (hexwin, z);
- wrefresh (hexwin);
- if (z > '9') z -= 7;
-
- h |= z & m;
- break;
- }
- }
-
- if (h < 0)
- {
- wmove (hexwin, r, hexc);
- if (record[r][c] < '\0')
- {
- wprintw (hexwin, "%x%x",
- (record[r][c] >> 4) & m,
- record[r][c] & m);
- }
- else
- {
- wprintw (hexwin, "%02x", record[r][c]);
- }
- wrefresh (hexwin);
- break;
- }
-
- record[r][c] = z = h;
- mod = 1;
-
- if (ebcdic) icc (&z, 1,"EA");
-
- wmove (alphawin, r, c);
- if (isascii (z) && isprint (z))
- waddch (alphawin, z);
- else waddch (alphawin, '.');
- wrefresh (alphawin);
-
- if (c == 15)
- {
- if (r == 15) beep ();
- else
- {
- c = 0;
- ++r;
- }
- }
- else
- {
- c++;
- }
- }
- }
-
- if (r * 16 + c >= bytes)
- {
- beep ();
- r = (bytes - 1) / 16;
- c = (bytes - 1) % 16;
- }
-
- hexc = c * 3;
- wmove (hexwin, r, hexc);
- wrefresh (hexwin);
- }
- break;
-
- case 'W': /* write record */
- stay = 1;
- status = lseek (fid, position, 0);
- if (status != position)
- {
- move (22, 0);
- clrtoeol ();
- perror (filename);
- errmsg ("error positioning in file", SLEEP_TIME);
- beep ();
- }
- if (swab_opt) schwapp (record, 256);
- if (write (fid, record, bytes) != bytes)
- {
- errmsg ("error writing to file", SLEEP_TIME);
- reset (0);
- exit (0);
- }
- if (swab_opt) schwapp (record, 256);
- mod = 0;
- errmsg ("Record written", SLEEP_TIME);
- break;
-
- case '\n': /* newline - next page */
- case '\r':
- if (mod)
- {
- errmsg ("No write since last change", SLEEP_TIME);
- stay = 1;
- }
- else
- {
- ++recno;
- if (!rawfile && (((long )recno) * 256) >= size)
- {
- recno--;
- beep ();
- errmsg ("No more records in file", SLEEP_TIME);
- stay = 1;
- }
- else stay = 0;
- }
- break;
-
- default:
- if (isascii (zp) && isprint (zp))
- {
- sprintf (outbuf, "Unknown command: %d", zp);
- errmsg (outbuf, 0);
- }
- else
- {
- sprintf (outbuf, "Unknown command: %d", zp + '@');
- errmsg (outbuf, 0);
- }
- beep ();
- stay = 1;
- break;
- } /* end switch zp */
- refresh ();
- }
-
- reset (0);
- if (fid > 0) return (close (fid));
- else return (0);
- }
- /*S show - display a record on the terminal */
- /*H show */
- /*E*/
- /*checked typing of parameters as declared in fucntion */
- /* versus declarations at call */
- show (bytes, record, filename, size, recno, position,
- m,reclen, dump, ebcdic, swab_opt, block, honly)
- int bytes;
- char record[16][16];
- char *filename;
- long size;
- int recno;
- long position;
- char m;
- int reclen;
- int dump;
- int ebcdic;
- int swab_opt;
- int block;
- int honly;
- {
- int i;
- int j;
- char s;
- char temp[16];
- char *look = NULL;
-
- int row = 0;
- int col = 0;
-
- if (dump)
- printf ("\n\n");
- if (!dump)
- move (0, 0);
- sprintf (outbuf, "FILE: %s ", filename);
- outstr (outbuf);
- if (block_spec) outstr ("(block special)");
- else if (char_spec) outstr ("(character special)");
- else if (fifo_spec) outstr ("(fifo (named pipe))");
- else if (dir_spec)
- {
- sprintf (outbuf, "(directory - %ld)", size);
- outstr (outbuf);
- }
- else
- {
- sprintf (outbuf, "(%ld)", size);
- outstr (outbuf);
- }
- if (ebcdic) outstr (" - EBCDIC");
- else outstr (" - ASCII");
- if (swab_opt) outstr (" - SWAP");
- if (block)
- {
- sprintf (outbuf, " - BLOCK (%d)", block);
- outstr (outbuf);
- }
- if (reclen)
- {
- sprintf (outbuf, " - RECORD (%d)", reclen);
- outstr (outbuf);
- }
- if (!dump)
- {
- clrtoeol ();
- move (1,0);
- printw ("PAGE: %d (%ld)", recno, position);
- clrtoeol ();
- row = 2;
- }
- else
- {
- printf ("\nPAGE: %d (%ld)\n", recno, position);
- }
-
- if (honly)
- {
- look = (char *) record;
- for (j=0;j<256;++j)
- {
- if (*look++ != '\0')
- {
- look = NULL;
- break;
- }
- }
- }
-
- if (!dump) move (row, col);
-
- outstr (" x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf");
- outstr (" 0123456789abcdef");
-
- if (!dump)
- {
- row += 2;
- move (row, col);
- }
- else
- {
- printf ("\n\n");
- }
- for (i=0; i<=bytes/16; ++i)
- {
- if (honly && look != NULL)
- {
- i = 16;
- continue;
- }
- if (i*16+1 > bytes)
- {
- if (!dump) move (++row, 0);
- continue;
- }
-
- sprintf (outbuf, "%02x: ", i);
- outstr (outbuf);
-
- for (j=0; j<16; ++j)
- {
- if (i*16+j < bytes)
- {
- if (record[i][j] < '\0')
- {
- sprintf (outbuf, "%x%x ",
- (record[i][j] >> 4) & m, record[i][j] & m);
- outstr (outbuf);
- }
- else
- {
- sprintf (outbuf, "%02x ", record[i][j]);
- outstr (outbuf);
- }
- s = ' ';
- if (reclen > 0 && (position+i*16+j+1)%reclen == 0)
- s = ':';
- if (block > 0 && (position+i*16+j+1)%block == 0)
- {
- if (s == ' ')
- s = '/';
- else
- s = '%';
- }
- if (s != ' ')
- {
- sprintf (outbuf, "\b%c", s);
- outstr (outbuf);
- }
- }
- else
- {
- outstr (" "); /* set at 3 spaces */
- }
- }
-
- outstr (" "); /* set at tab + 1 space */
-
- copyrec (record[i], temp, 16);
-
- if (ebcdic) icc (temp, 16, "EA");
-
- for (j = 0; j < 16 && i*16+j < bytes; ++j)
- {
- if (temp[j] < ' ') outch ('.');
- else
- {
- sprintf (outbuf, "%c", temp[j]);
- outstr (outbuf);
- }
- }
-
- if (!dump)
- {
- move (++row, col);
- }
- else
- {
- printf ("\n");
- }
- }
-
- /* moved debug output so it would display + other related changes */
- if (!dump) clrtobot ();
- if (debug && !dump)
- {
- getyx (stdscr, row, col);
- move (23,0);
- printw ("show: %d|%ld|%s|%ld|%d|%ld|%#x|%d|%d|%d|%d|%d|%d",
- bytes, record, filename, size, recno, position,
- m, reclen, dump, ebcdic, swab_opt, block, honly);
- move (row, col);
- }
- if (!dump)
- {
- touchwin (stdscr);
- refresh ();
- }
-
- return;
- }
- /*S breakp - set pbrk on interrupt */
- /*H breakp */
- /*E*/
- int breakp (i)
- int i;
- {
- int s;
- extern int pbrk;
- s = (int) signal (SIGINT, breakp);
- pbrk = i;
- }
- /*S bread - buffered read */
- /*H bread */
- /*E*/
- int bread (fid, record, want, block)
- int fid, want, block;
- char *record;
- {
- int i, j, k;
- int what, bytes, orig;
- static char buffer[10240];
- static int left, xarrow;
- static int flag = 1;
-
- if (flag)
- {
- left = 0;
- xarrow = 0;
- flag = 0;
- }
-
- if (block == 0)
- return (read (fid, record, want));
-
- if (block & 1) ++block;
-
- orig = what = want;
- while (1)
- {
- if (left < want)
- {
- if (left)
- {
- copyrec (&buffer[xarrow], record, left);
- record += left;
- want -= left;
- }
-
- xarrow = 0;
- left = 0;
-
- if ((bytes = read (fid, buffer, block)) < 0)
- {
- what = bytes;
- break;
- }
-
- if (bytes == 0)
- {
- what = orig - want;
- break;
- }
-
- left = bytes;
- }
- else
- {
- copyrec (&buffer[xarrow], record, want);
- xarrow += want;
- left -= want;
- break;
- }
- }
-
- return (what);
- }
- /*S schwapp - swap bytes in place */
- /*H schwapp */
- /*E*/
- void
- schwapp (ptr, nch)
- register char *ptr;
- register int nch;
- {
- register int i;
- register char c;
- register char *ptra = ptr + 1;
-
- if (nch & 1) --nch;
-
- for (i = 0; i < nch; i += 2, ptr += 2, ptra += 2)
- {
- c = *ptr;
- *ptr = *ptra;
- *ptra = c;
- }
- return;
- }
- /*S copyrec - transfer bytes from f to t for nbytes bytes */
- /*H copyrec */
- /*E*/
- void
- copyrec (f, t, nbytes)
- register char *f;
- register char *t;
- register int nbytes;
- {
- register int i;
-
- for (i = 0; i < nbytes; i++, f++, t++) *t = *f;
-
- return;
- }
- /*S ebcdic codes corresponding to ascii - translation table */
- /*Page Eject*/
- char xebcdic_codes[] = {
- 0, 0x1, 0x2, 0x3, 0x37, 0x2d, 0x2e, 0x2f, 0x16,
- 0x5, 0x25, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
- 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, 0x18, 0x19, 0x3f,
- 0x27, 0x1c, 0x1d, 0x1e, 0x1f, 0x40, 0x5a, 0x7f, 0x7b,
- 0x5b, 0x6c, 0x50, 0x7d, 0x4d, 0x5d, 0x5c, 0x4e, 0x6b,
- 0x60, 0x4b, 0x61, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
- 0xf6, 0xf7, 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e,
- 0x6f, 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
- 0xe9, 0xad, 0xe0, 0xbd, 0x9a, 0x6d, 0x79, 0x81, 0x82,
- 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92,
- 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xa2, 0xa3,
- 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0,
- 0x5f, 0x7 };
- /*S icc - internal code conversion */
- /*H icc */
- /*E*/
- void
- icc (buf, nch, type)
- register char *buf;
- register int nch;
- char *type;
- {
- register int i;
- register int j;
-
- if (!strcmp (type, "AE"))
- {
- for (i = 0; i < nch; i++, buf++)
- {
- *buf = xebcdic_codes[*buf];
- }
- }
- else if (!strcmp (type, "EA"))
- {
- for (i = 0; i < nch; i++, buf++)
- {
- for (j = 0; j < 128; j++)
- {
- if (*buf == xebcdic_codes[j])
- {
- *buf = j;
- break;
- }
- }
- }
- }
-
- return;
- }
- /*S ckfile - check on existence, accessibility, and type of file */
- /*H ckfile */
- /*E*/
- ckfile (filename, sizep)
- char *filename;
- long *sizep;
- {
- register int fid = 0;
-
- if (access (filename, 0) < 0)
- {
- sprintf (outbuf, "file not found (%s)", filename);
- errmsg (outbuf, SLEEP_TIME);
- fid = -1;
- }
-
- if (block || pause_opt || dump)
- {
- fid = open (filename, O_RDONLY, 0);
- }
- else
- {
- fid = open (filename, O_RDWR, 0);
- }
-
- if (fid < 0)
- {
- sprintf (outbuf, "error opening file %s", filename);
- errmsg (outbuf, SLEEP_TIME);
- perror (filename);
- fid = -1;
- }
- else
- {
- sprintf (outbuf, "File %s opened successfully ", filename);
- errmsg (outbuf, 0);
- if (fstat (fid, &sb) == -1)
- {
- fprintf (stderr, "Can't stat\n");
- perror (filename);
- fid = -1;
- }
- else
- {
- block_spec = (sb.st_mode & S_IFMT) == S_IFBLK;
- char_spec = (sb.st_mode & S_IFMT) == S_IFCHR;
- fifo_spec = (sb.st_mode & S_IFMT) == S_IFIFO;
- dir_spec = (sb.st_mode & S_IFMT) == S_IFDIR;
- rawfile = block_spec || char_spec || fifo_spec;
-
- if (rawfile) *sizep = -1;
- else
- {
- if (sb.st_size == 0)
- {
- fprintf (stderr,
- "file %s is empty (zero bytes)\n",
- filename);
- fid = -1;
- }
- *sizep = sb.st_size;
- }
- }
- }
-
- return fid;
- }
- /*S dohelp - display help text */
- /*H dohelp */
- /*E*/
- dohelp ()
- {
- static char *helptxt[] = {
- "? - display this help text", "h - edit hexadecimal portion",
- "! - execute command in the shell", "a - edit ascii portion",
- "q,DEL - quit the program", "DEL - exit edit->command mode",
- "^q - quit without writing changes", NULL,
- "-x - toggle command line option", "f - display first page of file",
- " ({a|e}->{e|a}, s->!s)", "l - display last page of file",
- "<cr> - display next page", NULL,
- "\\ - display previous page", "nnn - direct addressing",
- "/ - search for ASCII string", NULL,
- "^f - select named file", "r - reread the current page",
- "^n - select next file", "u - undo all changes to page",
- "^p - select previous file", "w - write out changed page",
- "^r - redraw the screen", NULL,
- "^x - turn on debug", NULL,
- "----------------------------------------------------------------", NULL,
- "direct addressing: nnnS, where nnn = some number, and", NULL,
- " S = type suffix", "b = block (512)",
- NULL, "k = kilobyte (1024)",
- NULL, "l = long word (4)",
- NULL, "p = page (256)",
- NULL, "w = word (2)",
- NULL, "<cr> = byte",
- };
-
- static int nmsg = sizeof helptxt / sizeof (char *);
- register int row = 0;
- register int i;
-
- register WINDOW *helpwin;
- extern WINDOW *newwin ();
-
- helpwin = newwin (LINES, COLS, 0, 0);
- wclear (helpwin);
-
- wrefresh (helpwin);
-
- wmove (helpwin, 0, 1);
- waddstr (helpwin,
- "---------------------------------- HELP ----------------------------------");
-
- for (row = 1, i = 0; i < nmsg; i+=2)
- {
- if (helptxt[i])
- {
- wmove (helpwin, row, 1);
- waddstr (helpwin, helptxt[i]);
- }
- if (i+1 <= nmsg && helptxt[i+1])
- {
- wmove (helpwin, row, 41);
- waddstr (helpwin, helptxt[i+1]);
- }
- row++;
- }
-
- wmove (helpwin, 23, 0);
- wstandout (helpwin);
- waddstr (helpwin, " <Press any key> ");
- wstandend (helpwin);
- wclrtoeol (helpwin);
- wrefresh (helpwin);
- wgetch (helpwin);
- /*
- wclear (helpwin);
- wmove (helpwin, 0, 0);
- wrefresh (helpwin);
- */
- delwin (helpwin);
-
- return;
- }
- /*S reset - reset terminal to original state */
- /*H reset */
- /*E*/
- reset (sig)
- int sig;
- {
- if (windowed)
- {
- move (23, 0);
- refresh ();
- #ifndef MOD_HAX
- ioctl (0, TCSETA, &aswas);
- #endif
- endwin ();
- }
- fprintf (stderr, "\n");
- if (sig)
- {
- fprintf (stderr, "killed with signal %d\n", sig);
- exit (sig);
- }
- return (0);
- }
- /*S arrow - determine if current character is a cursor control key */
- /*H arrow */
- /*E*/
- arrow (k, r, c)
- register int k;
- register int *r;
- register int *c;
- {
- register ret = 1;
-
- /* watch out for conflict of VI_* amd KEY_* definitions */
- if (k == KEY_UP || k == VI_UP)
- {
- if (*r == 0) beep ();
- else (*r)--;
- }
- else if (k == KEY_DOWN || k == VI_DOWN)
- {
- if (*r == 15) beep ();
- else (*r)++;
- }
- else if (k == KEY_LEFT || k == VI_LEFT)
- {
- if (*c == 0)
- {
- if (*r == 0) beep ();
- else
- {
- *c = 15;
- (*r)--;
- }
- }
- else (*c)--;
- }
- else if (k == KEY_RIGHT || k == VI_RIGHT)
- {
- if (*c == 15)
- {
- if (*r == 15) beep ();
- else
- {
- *c = 0;
- (*r)++;
- }
- }
- else (*c)++;
- }
- else if (k == KEY_HOME || k == VI_HOME)
- {
- *r = *c = 0;
- }
- else
- {
- ret = 0;
- }
-
- return ret;
- }
- /*S dbg_msg - print a debug message */
- /*H dbg_msg */
- /*E*/
- dbg_msg (msg)
- register char *msg;
- {
- if (debug && !dump)
- {
- errmsg (msg, SLEEP_TIME);
- }
-
- return;
- }
- /*S instr - get a character string from the terminal */
- /*H instr */
- /*E*/
- char *
- instr ()
- {
- static char buf[512];
-
- register int c;
- register char *p = buf;
- register int col = 0;
-
- move (22, 0);
- clrtoeol ();
- refresh ();
-
- while ((c = getch ()) != '\r')
- {
- if (isascii (c) && isprint (c))
- {
- move (22, col);
- addch (c);
- *p++ = c;
- col++;
- }
- else if (c == '\b')
- {
- p--;
- col--;
- move (22, col);
- addch (' ');
- move (22, col);
- }
- refresh ();
- }
-
- refresh ();
-
- *p = '\0';
-
- return buf;
- }
- /*S getnum - retrieve a number from the terminal */
- /*H getnum */
- /*E*/
- long
- getnum (frst_char, hex)
- register int frst_char;
- register int hex;
- {
- static char buf[64];
-
- register int c;
- register char *p = buf;
- register int col = 0;
-
- register long retval = 0;
-
- move (22, 0);
- clrtoeol ();
- if (frst_char)
- {
- addch (frst_char);
- *p++ = frst_char;
- col++;
- refresh ();
- }
-
- while ((c = getch()) != '\r')
- {
- if (isascii (c))
- {
- if ((hex && isxdigit (c)) || isdigit (c))
- {
- move (22, col);
- addch (c);
- *p++ = c;
- col++;
- }
- else if (c == '\b')
- {
- p--;
- col--;
- move (22, col);
- addch (' ');
- move (22, col);
- }
- else
- {
- break; /* some character typing the value */
- }
- refresh ();
- }
- }
-
- *p = '\0';
-
- retval = atol (buf);
-
- mvprintw (22, 0, "%ld", retval);
- switch (c)
- {
- case 'b': /* block - 512 bytes */
- retval *= 512;
- break;
- case 'k': /* 1024 bytes */
- retval *= 1024;
- break;
- case 'l': /* long word - 4 bytes */
- retval *= 4;
- break;
- case 'p': /* page - 256 bytes */
- retval *= 256;
- break;
- case 'w': /* word - 2 bytes */
- retval *= 2;
- break;
- case '\r': /* just clear it for display */
- c = '\0';
- break;
- }
-
- printw ("%c -> %ld byte offset", c, retval);
- clrtoeol ();
-
- refresh ();
-
- return retval;
- }
- /*S search - look for an ascii string in the file */
- /*H search */
- /*E*/
- search (fid)
- register int fid;
- {
- long curpos = position;
- long currec = recno;
-
- char lrecord[sizeof record + 1];
-
- register int i;
- register int matched = 0;
- register int srch_len;
-
- register char *cp = instr ();
- register char *rp;
-
- int row, col;
-
- srch_len = strlen (cp);
- copyrec (record, lrecord, sizeof record);
- lrecord[256] = '\0';
-
- pbrk = 0;
-
- wmove (errwin, 0, 0);
- wstandout (errwin);
- wmove (errwin, 0, 40);
- wstandend (errwin);
- wmove (errwin, 0, 1);
- waddstr (errwin, "..searching record ");
- getyx (errwin, row, col);
-
- do
- {
- mvwprintw (errwin, row, col, "%ld", currec);
- touchwin (errwin);
- wrefresh (errwin);
-
- for (i = 0, rp = lrecord, matched = 0;
- !matched && i < 256;
- rp++, i++)
- {
- if (*cp == *rp && !strncmp (cp, rp, srch_len))
- {
- matched = 1;
- break;
- }
- }
-
- if (!matched)
- {
- bytes = bread (fid, lrecord, 256, block);
- currec++;
- lrecord[256] = '\0';
- }
- } while (!pbrk && bytes && !matched);
-
- if (matched)
- {
- recno = currec;
- stay = 0;
- copyrec (record, unch_rec, sizeof record);
- werase (errwin);
- touchwin (errwin);
- wrefresh (errwin);
- }
- else
- {
- sprintf (outbuf, "String %s not found", cp);
- errmsg (outbuf, SLEEP_TIME);
- stay = 1;
- }
-
- return;
- }
- /* simplified call to errmsg(), by using sprintf to load format */
- /* sleep_time is not implemented and awaits cleaning up of the signals (?) */
- errmsg (fmt, sleep_time)
- unsigned sleep_time;
- char *fmt;
- {
- int y, x;
-
- if (windowed)
- {
- getyx (stdscr, y, x);
- wmove (errwin, 0, 0);
- wstandout (errwin);
- wprintw (errwin, fmt);
- wstandend (errwin);
- wclrtoeol (errwin);
- touchwin (errwin);
- wrefresh (errwin);
- move (y, x);
- }
- else
- {
- fprintf (stderr, fmt);
- fprintf (stderr, "\n");
- }
- /* signal problem ?? if sleep called
- if (sleep_time)
- sleep (sleep_time);
- */
- return;
- }
- /* simplified call to outstr(), by using sprintf to load format */
- outstr (fmt)
- char *fmt;
- {
- if (dump) printf (fmt);
- else printw (fmt);
-
- return;
- }
- outch (ch)
- register char ch;
- {
- if (dump) putchar (ch);
- else addch (ch);
-
- return;
- }
- AlBeRtEiNsTeIn
-