andy@uunet.UU.NET@mssx.UUCP (Andreas Pleschutznig) (06/28/88)
Posting-number: Volume 3, Issue 64 Submitted-by: "Andreas Pleschutznig" <andy@uunet.UU.NET@mssx.UUCP> Archive-name: bpe [The author called this "patch", perhaps he's not aware of lwall's magnum opus. Having seen "bp" and "bpatch", I named this "bpe" instead. ++bsa] I wrote this, because in std unix sometimes i failed to see the struc. of a file in a format I wanted to see it. I hope this program is useful to some of you, so i post it to comp.sources.unix to make it available to all of you. If you have any questions or suggestions or patches please kontact me. Andreas Pleschutznig Micro Systems Software 8044 Graz, Austria Teichhofweg 2 #------------------------------- cut here --------------------------- # To recreate the file(s) in this archive execute this file with sh # Do not use csh!!!. # # Created from : andy@mssx # date: Mon Jun 27 18:36:30 GMT 1988 echo x - makefile sed 's/^X//' >makefile << '+SHAR+MARK+' XCFLAGS = -O XLIBES = -lcurses XOBJS = bpe.o XSRCS = bpe.c XEXEC = bpe X X$(EXEC): $(OBJS) X cc $(OBJS) -o $(EXEC) $(LIBES) X X$(OBJS): $(SRCS) X cc -c $(CFLAGS) $(SRCS) +SHAR+MARK+ echo '-rw-r--r-- 1 andy other 166 Jun 6 12:22 makefile (as sent)' chmod u=rw,g=r,o=r makefile ls -l makefile echo x - bpe.c sed 's/^X//' >bpe.c << '+SHAR+MARK+' X/*************************************************************************** X XVersion History: X XVer.No Comment By X=========================================================================== X1.0 first version (seems to to things right) andy@mssx X XI declare this program as freeware, i.e. you may duplicate it, give it Xto your friends, and transfer it to any machine you like, as long as Xyou do not change or delete the build in copyright message. X X Andreas Pleschutznig X Teichhofweg 2 X 8044 Graz X Austria X XComments and bug reports to: X andy@mssx (mcvax!tuvie!mssx!andy) X X X*****************************************************************************/ X X X#include <curses.h> X#include <fcntl.h> X#include <signal.h> X X#define BELL 0x07 X#define ASCX 63 X#define ASCY 6 X#define HEXY 6 X#define HEXX 12 X Xint path; /* path to file to patch */ Xlong filpos; /* position in file */ Xchar secbuf[256]; /* sector read buffer */ X Xint donix(); /* default signal handling routine */ Xchar filename[60]; Xint length; /* length of read sector */ X Xmain(argc,argv) Xint argc; Xchar *argv[]; X X{ X if (argc != 2) { X fprintf(stderr,"Usage: %s filename\n",argv[0]); X exit(1); X } X if (( path = open(argv[1],O_RDWR)) == -1) { X fprintf(stderr,"%s: Can't open '%s'\n",argv[0],argv[1]); X exit(1); X } X sprintf(filename,"%s",argv[1]); X initscr(); X refresh(); X signal(SIGINT,donix); X signal(SIGQUIT,donix); X cbreak(); /* set single char input */ X noecho(); X keypad(stdscr,TRUE); X filpos = 0; /* set global position to 0 */ X length = 0; X command(); X endwin(); X close(path); X} X Xcommand() X X{ X int inval; X X header("PATCH Version 1.0",filename,"(C) 1988 MSS Graz"); X inval = 0; X while ((inval != 'q') && (inval != 'Q')) { X move(2,0); X mvprintw(2,0,"COMMAND : "); X refresh(); X inval = getch(); X switch (inval) { X case 'q': X case 'Q': X break; X case 'h': X case 'H': X case '?': X help(); X break; X case 'f': X case 'F': X find_string(); X dump(); X break; X case '+': X case 'n': X case 'N': X filpos += 256; X dump(); X break; X case '-': X case 'p': X case 'P': X filpos -= 256; X if (filpos < 0) X filpos = 0; X dump(); X break; X case 'D': X case 'd': X dump(); X break; X case 's': X case 'S': X set(); X dump(); X break; X case 'e': X edit_ascii(); X break; X case 'E': X edit_hex(); X break; X case 'w': X case 'W': X wrsec(); X break; X default: X werr("Invalid Command !"); X } X } X X} X Xedit_ascii() X{ X int inval = 0; X int cury,curx; X X if (length == 0) X length = dump(); X move(2,0); X clrtoeol(); X printw("End editing with CNTRL-C"); X curx = cury = 0; X while (inval != 0x03) { X move(ASCY+cury,ASCX+curx); X refresh(); X inval = getch(); X switch (inval) { X case KEY_UP: X if (cury) X cury--; X else X beep(); X break; X case KEY_DOWN: X if (cury < 15) X cury++; X else X beep(); X break; X case KEY_RIGHT: X if (curx < 15) X curx++; X else X beep(); X break; X case KEY_LEFT: X if (curx) X curx--; X else X beep(); X break; X default: X if ((inval >= 0x20) && (inval <= 0x7e)) { X secbuf[cury*16+curx] =inval; X curx++; X if (curx > 15) { X curx=0; X cury++; X } X if (cury > 15) X cury = 0; X disp(length); X } X break; X } X } X move(2,0); X clrtoeol(); X} X Xgethex(cury,curx) Xint cury,curx; X{ X int val; X int inlen; X int value; X X inlen = 0; X while (inlen < 2) { X val = getch(); X if (val > 255) X return(val); X if (val < '0') X return(-1); X if (val > '9') val &= ~0x20; X if (((val >= '0') && (val <='9')) || X ((val >= 'A') && (val <= 'F'))) { X if (val <= '9') X val -= '0'; X else X val = val - 'A' + 0x0a; X switch (inlen) { X case 0: X value = val << 4; X secbuf[cury*16+curx] = value; X disp(length); X move(HEXY+cury,HEXX+curx*3+1); X refresh(); X break; X case 1: X value += val ; X break; X } X inlen++; X } X } X return(value); X} X Xedit_hex() X{ X int inval = 0; X int cury,curx; X X if (length == 0) X length = dump(); X move(2,0); X clrtoeol(); X printw("End editing with CNTRL-C"); X curx = cury = 0; X while (inval != -1) { X move(HEXY+cury,HEXX+curx*3); X refresh(); X inval = gethex(cury,curx); X switch (inval) { X case KEY_UP: X if (cury) X cury--; X else X beep(); X break; X case KEY_DOWN: X if (cury < 15) X cury++; X else X beep(); X break; X case KEY_RIGHT: X if (curx < 15) X curx++; X else X beep(); X break; X case KEY_LEFT: X if (curx) X curx--; X else X beep(); X break; X default: X if ((inval >= 0x00) && (inval <= 0xff)) { X secbuf[cury*16+curx] =inval; X curx++; X if (curx > 15) { X curx=0; X cury++; X } X if (cury > 15) X cury = 0; X disp(length); X } X break; X } X } X move(2,0); X clrtoeol(); X} X Xfind_string() X X{ X int stlen; X char string[60]; X int found; X int searchpos; X X move(2,0); X clrtoeol(); X printw("String to search : "); X refresh(); X echo(); X getstr(string); X noecho(); X move(2,0); X clrtoeol(); X printw("Searching for '%s'",string); X found = 0; X searchpos = 0; X stlen = strlen(string); X while (found == 0) { X while ((256 - searchpos) >= stlen) { X if (testchar(secbuf+searchpos,string,stlen)) X searchpos++; X else { X filpos += searchpos; X found = 1; X break; X } X } X if (found == 0) { X filpos += searchpos; X searchpos = 0; X } X if (rdsec() == 0) { X found = 1; X } X refresh(); X } X move (2,0); X clrtoeol(); X} X Xtestchar(buffer,string,length) Xchar *buffer; Xchar *string; Xint length; X{ X register int i; X X i = 0; X while ( i < length) { X if (buffer[i] != string[i]) X break; X i++; X } X if ( i == length) X return(0); X return(1); X} X Xset() X X{ X echo(); X move(2,0); X clrtoeol(); X printw("New File Position : "); X refresh(); X scanw("%lx",&filpos); X move(2,0); X clrtoeol(); X noecho(); X} X Xdisp(length) Xint length; X{ X int i,j; X X j = 0; X mvprintw(4,0," ADDRESS 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII"); X mvprintw(5,0,"==============================================================================="); X for ( i = 0; i < 16; i++) { X mvprintw(ASCY+i,0,"%08lX",filpos+i*16+j); X for (j = 0; j < 16; j++) { X if (( i*16 + j ) >= length) { X clrtoeol(); X goto Disp1; X } X mvprintw(ASCY+i,HEXX+j*3,"%02X",secbuf[i*16+j] & 0xFF); X } XDisp1: X for (j = 0; j < 16; j++) { X if (( i*16 + j ) >= length) { X clrtobot(); X goto Disp2; X } X if (secbuf[i*16+j] >= ' ') X mvprintw(ASCY+i,ASCX+j,"%c",secbuf[i*16+j]); X else X mvprintw(ASCY+i,ASCX+j,"."); X } X } XDisp2: X refresh(); X} X X Xdump() X X{ X int i,j; X X length = rdsec(); X disp(length); X return(length); X} X Xrdsec() X X{ X mvprintw(2,55,"Rel. Position : %08lX",filpos); X lseek(path,filpos,0); X length = read(path,secbuf,256); X return(length); X} X Xwrsec() X{ X lseek(path,filpos,0); X write(path,secbuf,length); X} X Xhelp() X X{ X WINDOW *win; X X win = newwin(0,0,0,0); X wclear(win); X mvwprintw(win,3,10,"Valid Commands are :"); X mvwprintw(win,5,15,"D - Dump one page from current file position"); X mvwprintw(win,6,15,"S - Set current file pointer"); X mvwprintw(win,7,15,"F - Find string in file (beginning from curr. position)"); X mvwprintw(win,8,15,"H - Find hex string in file (beginnig from current position)"); X mvwprintw(win,9,15,"+ - Display next sector"); X mvwprintw(win,10,15,"N - Display next sector"); X mvwprintw(win,11,15,"- - Display previous sector"); X mvwprintw(win,12,15,"P - Display previous sector"); X mvwprintw(win,19,15,"Q - Quit Program"); X mvwprintw(win,13,15,"e - Edit ASCII portion of file"); X mvwprintw(win,14,15,"E - Edit binary portion of file"); X mvwprintw(win,15,15,"W - Write modified sector back to disk"); X mvwprintw(win,20,20,"Continue with any char."); X wrefresh(win); X getch(); X delwin(win); X touchwin(stdscr); X refresh(); X} X Xwerr(errstr) Xchar *errstr; X X{ X beep(); X move(LINES-1,0); X printw("%s",errstr); X refresh(); X sleep(2); X move(LINES-1,0); X clrtoeol(); X refresh(); X} X X X Xheader(left,mid,right) Xchar *left; Xchar *mid; Xchar *right; X X{ X mvprintw(0,0,"%s",left); X mvprintw(0,79-strlen(right),"%s",right); X mvprintw(0,40-strlen(mid)/2,"%s",mid); X} X Xdonix(sig) Xint sig; X X{ X signal(sig,donix); X} +SHAR+MARK+ echo '-rw-rw-r-- 1 andy other 8369 Jun 8 10:49 bpe.c (as sent)' chmod u=rw,g=rw,o=r bpe.c ls -l bpe.c exit 0