diff options
| author | Jonathan McCrohan <jmccrohan@gmail.com> | 2012-10-30 21:29:30 +0000 | 
|---|---|---|
| committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2012-10-30 21:29:30 +0000 | 
| commit | 62f81e5cafbacfb90ac0f86e52e8e3176aa5ba8f (patch) | |
| tree | 8f8f6028fa880b3296b1e42bc8d87cead73aaf78 /main.c | |
| download | dhex-upstream/0.65.tar.gz | |
Imported Upstream version 0.65upstream/0.65
Diffstat (limited to '')
| -rw-r--r-- | main.c | 704 | 
1 files changed, 704 insertions, 0 deletions
| @@ -0,0 +1,704 @@ +#define	MAJORVERSION	0 +#define	MINORVERSION	6 +#define	REVISION	5 +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <string.h> +#include <ncurses.h> +#include "menu.h" +#include "configfile.h" +#include "machine_type.h" +#include "input.h" +#include "output.h" +#include "buffers.h" +#include "ui.h" +#include "hexcalc.h" +#include "search.h" +#include "gpl.h" +#include "markers.h" +#include "correlation.h" + +void welcomescreen(char* argv0) +{ +	fprintf(stderr,"*** DHEX %i.%i%i\n",MAJORVERSION,MINORVERSION,REVISION); +	fprintf(stderr,"*** (C)opyleft 2011 by Thomas Dettbarn\n"); +	fprintf(stderr,"*** dettus@dettus.net (include DHEX somewhere in the subject)\n\n"); +	fprintf(stderr,"\n"); +	fprintf(stderr,"(start it with %s -gpl to see the license)\n",argv0); +	fprintf(stderr,"\n"); +	fprintf(stderr,"\n"); +	fprintf(stderr,"This program is free software; you can redistribute it and/or modify\n"); +	fprintf(stderr,"it under the terms of the GNU General Public License as published by\n"); +	fprintf(stderr,"the Free Software Foundation; either version 2 of the License, or\n"); +	fprintf(stderr,"(at your option) any later version.\n"); +	fprintf(stderr,"\n"); +	fprintf(stderr,"This program is distributed in the hope that it will be useful,\n"); +	fprintf(stderr,"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); +	fprintf(stderr,"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"); +	fprintf(stderr,"GNU General Public License for more details.\n"); +	fprintf(stderr,"\n"); +	fprintf(stderr,"You should have received a copy of the GNU General Public License\n"); +	fprintf(stderr,"along with this program; if not, write to the Free Software\n"); +	fprintf(stderr,"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n"); +	fprintf(stderr,"	\n\n"); +} +void helpscreen(char* argv0,int exitval) +{ +	welcomescreen(argv0); +	fprintf(stderr,"%s [Parameters]: General parameters\n",argv0); +	fprintf(stderr," -h, -H, -?                 show this help\n"); +	fprintf(stderr," -v, -V                     show the version number %i.%i%i\n",MAJORVERSION,MINORVERSION,REVISION); +        fprintf(stderr," -k, -K                     start the keyboard setup manually\n"); +	//fprintf(stderr," -x, -X                     start the hexcalc program (TODO)\n"); +	fprintf(stderr," -g, -G                     show the license\n"); +	fprintf(stderr," -f, -F [configfile]        read the config from [configfile]\n"); +	fprintf(stderr," -m, -M [markerfile]        read the bookmarks from [markerfile]\n"); +	fprintf(stderr,"\n"); +	fprintf(stderr,"%s [Parameters] [Filename]: Edit a single file\n",argv0); +	fprintf(stderr," -ob, -OB [x]                 set the cursor to [x] (binary)\n"); +	fprintf(stderr," -od, -OD [x]                 set the cursor to [x] (decimal)\n"); +	fprintf(stderr," -oh, -OH [x]                 set the cursor to [x] (hexadecimal)\n"); +	fprintf(stderr," -oo, -OO [x]                 set the cursor to [x] (octal)\n"); +	fprintf(stderr," -sa, -SA, -sab, -SAB [x]     find the ascii string x in file (b=backwards)\n"); +	fprintf(stderr," -sh, -SH, -shb, -SHB [x]     find the hex string x in file (b=backwards)\n"); +	fprintf(stderr," -r, -R [read searchlog]      read the search positions from this searchlog\n"); +	fprintf(stderr," -w, -W [write searchlog]     write the location of the occurances to this log\n"); +	fprintf(stderr,"\n"); +	fprintf(stderr,"%s [Parameters] [Filename1] [Filename2]: Diff mode\n",argv0); +	fprintf(stderr," -cd, -CD [x]                      correlate with the minimum difference\n"); +	fprintf(stderr," -cb, -CB, -cl, -CL                correlate with the best/longest match\n"); +	fprintf(stderr," -o1b, -O1B  [x] -o2b, -O2B  [y]   set the cursors to [x] and [y] (binary)\n"); +	fprintf(stderr," -o1d, -O1D  [x] -o2d, -O2D  [y]   set the cursors to [x] and [y] (decimal)\n"); +	fprintf(stderr," -o1h, -O1H  [x] -o2h, -O2H  [y]   set the cursors to [x] and [y] (hexadecimal)\n"); +	fprintf(stderr," -o1o, -O1O  [x] -o2o, -O2O  [y]   set the cursors to [x] and [y] (octal)\n"); +	fprintf(stderr," -s1a, -s1ab [x] -s2a, -s2ab [y]   find the ascii strings [x] and [y]\n"); +	fprintf(stderr," -s1h, -s1hb [x] -s2h, -s2hb [y]   find the hex strings [x] and [y]\n"); +	fprintf(stderr," -r1 [searchlog1] -r2 [searchlog2] read the search positions from searchlogs\n"); +	fprintf(stderr," -w1 [searchlog1] -w2 [searchlog2] write the search positions to searchlogs\n"); +	//fprintf(stderr," -c, -C [corrlen]           find the best correlation between the files (TODO)\n"); +	exit(exitval); +} +int parsecursorpos(tInt64* cursorpos1,tInt64* cursorpos2,char* lastopt,char* argv) +{ +	int i; +	int g; +	int d; +	char c; +	tInt64	x=0; + +	g=16;	// default: hex +	if (lastopt[1]=='D' || lastopt[2]=='D') g=10;	// -od: decimal +	if (lastopt[1]=='d' || lastopt[2]=='d') g=10;	// -od: decimal +	if (lastopt[1]=='H' || lastopt[2]=='H') g=16;	// -oh: hexadecimal +	if (lastopt[1]=='h' || lastopt[2]=='h') g=16;	// -oh: hexadecimal +	if (lastopt[1]=='B' || lastopt[2]=='B') g=2;	// -ob: binary +	if (lastopt[1]=='b' || lastopt[2]=='b') g=2;	// -ob: binary +	if (lastopt[1]=='O' || lastopt[2]=='O') g=8;	// -oo: octal +	if (lastopt[1]=='o' || lastopt[2]=='o') g=8;	// -oo: octal + +	 +	for (i=0;i<strlen(argv);i++) +	{ +		c=argv[i]; +		if (c>32) +		{ +			x=x*g; +			d=g; +			if (c>='0' && c<='9') d=c-'0'; +			if (c>='a' && c<='f') d=c-'a'+10; +			if (c>='A' && c<='F') d=c-'A'+10; +	 +			if (d>=g) return RETNOK; +			x=x+d; +		} +	} +	if (lastopt[1]=='1' || lastopt[2]=='1')	*cursorpos1=x;			// -o1: cursorpos1 +	else if (lastopt[1]=='2' || lastopt[2]=='2')	*cursorpos2=x;		// -o2:	cursorpos2 +	else { +		*cursorpos1=x;		// -o: both +		*cursorpos2=x;		// -o: both +	}	 +	return RETOK;	 +	 +} +int parsecommandlineoptions(int argc,char** argv,tInt64* cursorpos1,tInt64* cursorpos2,tBool* diffmode,int* filename1,int* filename2,tBool* keyboardsetupreq,char* markerfilename,char* configfile,tSearch* search1,tBool* gosearch1,tSearch* search2,tBool* gosearch2,tCorrelation* correlation,tBool* gocorr) +{ +	int filenamecnt=0; +	int i; +	int retval=RETOK; +	char lastopt[8]; +	tBool moreopts=1; + +	*gosearch1=0; +	*gosearch2=0; +	*gocorr=0; +	memset(lastopt,0,8);	 +	for (i=1;i<argc;i++) +	{ +		if (argv[i][0]=='-' && moreopts)  +		{ +			memcpy(lastopt,&argv[i][1],8); +			switch (lastopt[0])	// this is for parameters with just one part +			{ +				case '-':	lastopt[0]=0;	 // -- means: no more options +						if (argv[i][2]) retval=RETNOK; +						moreopts=0; +						break; +				case 'c':	// searching for a correlation could be a two-parted search. +				case 'C':	 +						*gocorr=1; +						if (lastopt[1]=='d' || lastopt[1]=='D')	correlation->algorithm=CORR_MIN_DIFF;		// min diff, this is two parted +						else if (lastopt[1]=='b' || lastopt[1]=='B')	{correlation->algorithm=CORR_BEST_MATCH;lastopt[0]=0;}	// best match +						else if (lastopt[1]=='l' || lastopt[1]=='L')	{correlation->algorithm=CORR_LONGEST_MATCH;lastopt[0]=0;}	// longest match +						else { +							fprintf(stderr,"unknown correlation algorithm. please provide -cb, -cd or -cl\n"); +							exit(1); +						} + +						break; +				case '?': +				case 'H':	 +				case 'h':	helpscreen(argv[0],0);	// print the helpscreen and be done with it +						lastopt[0]=0; +						break; +				case 'g': +				case 'G': +						print_gpl();		// print the gpl and be done with it +						exit(0); +						lastopt[0]=0; +						break;	 +				case 'X': +				case 'x':	printf("TODO:hexcalc\n"); +						break; +				case 'K':	 +				case 'k':	 +						*keyboardsetupreq=1; +						lastopt[0]=0; +						break; +				case 'v': +				case 'V': +						printf("%i.%i%i\n",MAJORVERSION,MINORVERSION,REVISION); +						exit(0); +						break; +				default:	 +						break; +				 +			} +		} +		else if (lastopt[0])	// two-parted parameters +		{ +			switch (lastopt[0]) +			{ +				case 'C': +				case 'c': +						correlation->start_mindiff=atoi(argv[i]);	 +						break; +				case 'F':	 +				case 'f': +						snprintf(configfile,512,"%s",argv[i]); +						break; +				case 'S': +				case 's': +						{	 +							tInt8	stringtype=0;	// 0=unknown, 1=ascii, 2=hex +							tBool	forward=1; +							tSearch* search; +							tBool* gosearch; +							int j; +							 +							search=search1; +							gosearch=gosearch1; +							for (j=1;j<8 && lastopt[j];j++) +							{ +								if (lastopt[j]=='a' || lastopt[j]=='A') stringtype=1; +								if (lastopt[j]=='h' || lastopt[j]=='H') stringtype=2; +								if (lastopt[j]=='b' || lastopt[j]=='B') forward=0; +								if (lastopt[j]=='1') +								{ +									search=search1; +									gosearch=gosearch1; +								} +								if (lastopt[j]=='2') +								{ +									search=search2; +									gosearch=gosearch2; +								} +								 +							} +							 +							*gosearch=1; +							search->forwardnotbackward=!(lastopt[2]=='b' || lastopt[2]=='B'); +							if (stringtype==1) +							{ +								memcpy(search->searchstring,argv[i],19); +								search->searchlen=strlen(argv[i]); +								if (search->searchlen>19) search->searchlen=19; +							} else if (stringtype==2) { +								int k=0; +								int x=0; +								search->searchlen=0; +								for (j=0;j<strlen(argv[i]) && search->searchlen<19;j++) +								{ +									int y; +									y=-1; +									x<<=4; +									y=(argv[i][j]>='0' && argv[i][j]<='9')?argv[i][j]-'0':y;	 +									y=(argv[i][j]>='a' && argv[i][j]<='f')?argv[i][j]-'a'+10:y; +									y=(argv[i][j]>='A' && argv[i][j]<='F')?argv[i][j]-'A'+10:y; +									if (y>=0)  +									{ +										x|=y; +										if (k&1) +										{ +											search->searchstring[search->searchlen++]=(x&0xff); +										} +										k++; +									} +									else if (argv[i][j]!=' ')  +									{ +										fprintf(stderr,"illegal character in hex searchstring.\n"); +										retval=RETNOK; +									} +								} +							} else { +								fprintf(stderr,"please select one of -sa or -sh\n"); +								retval=RETNOK;	 +							} +						} +						break; +				case 'r': +				case 'R': +						{ +							tSearch* search; +							if (lastopt[1]=='2') search=search2; else search=search1; +							memcpy(search->readlogfilename,argv[i],64); +							search->readsearchlog=1; +						} +						break; +				case 'w': +				case 'W': +						{ +							tSearch* search; +							if (lastopt[1]=='2') search=search2; else search=search1; +							memcpy(search->writelogfilename,argv[i],64); +							search->writesearchlog=1; +						} +						break; +				case 'O': +				case 'o':	 +						retval=parsecursorpos(cursorpos1,cursorpos2,lastopt,argv[i]); +						break; +				case 'm': +				case 'M': +						if (markerfilename) memcpy(markerfilename,argv[i],64); +						break; +				default: +						retval=RETNOK;	 +						break; +			}	 +			lastopt[0]=0;		 +		} +		else // no parameters, must be a filename +		{ +			if (filenamecnt==0)	 +			{ +				*filename1=i; +			} +			if (filenamecnt==1)	 +			{ +				*filename2=i; +				*diffmode=1; +			} +			filenamecnt++; +			if (filenamecnt>2) retval=RETNOK; +		} +	} +	return retval; +} +int main(int argc,char** argv) +{ +//	tBuffer buf1; +//	tBuffer buf2; +	thHexCalc*	hHexCalc=NULL; +	tBuffer*	buf1=NULL; +	tBuffer*	buf2=NULL; +	tOutput*	output=NULL; +	tInt64 cursorpos1; +	tInt64 firstpos1; +	tInt64 cursorpos2; +	tInt64 firstpos2; +	tInt64 oldcursorpos1; +	tInt64 oldfirstpos1; +	tInt64 oldcursorpos2; +	tInt64 oldfirstpos2; +	tSearch search1; +	tSearch search2; +	tMarkers* markers; +	tBool	gosearch1=0; +	tBool	gosearch2=0; +	tCorrelation correlation; +	char	markerfilename[64]; +	 +	tUInt8	windowfield=0;	// 0=hex field buffer 1, 1=ascii field buffer 1, 2=hex field buffer 2, 3=ascii field buffer 2 +	tBool	diffmode=0; +	tBool	keyboardsetupreq; +	tBool	gocorr=0; +	int	retval; +	 +	int ch; +	int filename1=-1; +	int filename2=-1; +	char* homedir; +	char configfile[512]; + +	memset(configfile,0,512); +	memset(markerfilename,0,64); +	markers=initmarkers(); +	output=malloc(sizeof(tOutput)); +	memset(output,0,sizeof(tOutput)); +	initcolors(output); +	initkeytab(output); +	 +	keyboardsetupreq=0; +	cursorpos1=0; +	cursorpos2=0; +	clearsearch(&search1); +	clearsearch(&search2); +	clear_correlation(&correlation); +	if (parsecommandlineoptions(argc,argv,&cursorpos1,&cursorpos2,&diffmode,&filename1,&filename2,&keyboardsetupreq,markerfilename,configfile,&search1,&gosearch1,&search2,&gosearch2,&correlation,&gocorr)!=RETOK) +	{ +		if (output) +		{ +			if (output->pKeyTab) free(output->pKeyTab); +			free(output); +		} +		if (markers) free(markers); +		helpscreen(argv[0],0); +	} +	if (configfile[0]==0) +	{ +		homedir=getenv("HOME"); +		if (homedir==NULL) +		{ +			fprintf(stderr,"$HOME-variable not set. \n\n"); +			fprintf(stderr,"I'm sorry, but you'll have to provide a config-file by using\n"); +			fprintf(stderr,"%s -f /PATHTOCONFIGFILE/.dhexrc\n",argv[0]); +			exit(1); +		} else { +			snprintf(configfile,512,"%s/.dhexrc",homedir); +		} +	} + +	if (markerfilename[0])	if (parsemarkerfile(markers,markerfilename)!=RETOK) +	{ +		if (output) +		{ +			if (output->pKeyTab) free(output->pKeyTab); +			free(output); +		} +		if (markers) free(markers); +		helpscreen(argv[0],0); +		 +	} +	 +	if (filename1==-1 || (filename2==-1 && diffmode)) helpscreen(argv[0],0); +	retval=readconfigfile(output,configfile); +	if (retval==1)		// config file did not exists. creating one +	{ +		tFptr f=fopen(configfile,"w"); +		if (!f) +		{ +			welcomescreen(argv[0]); +			fprintf(stderr,"config file %s did not exists, and i couldn't create it\n",configfile); +			exit(1); +		} +		fprintf(f,"#DHEXCOLORSCHEME\n"); +		fprintf(f,"#VERSION 0\n"); +		fprintf(f,"#possible colors are: BLACK,RED,GREEN,YELLOW,BLUE,MAGENTA,CYAN,WHITE\n"); +		fprintf(f,"#possible extra flags are: UNDERLINE,REVERSE,BLINK,DIM,BOLD\n"); +		fprintf(f,"\n"); +		fprintf(f,"BRACKETS:       FG=BLACK,BG=BLACK,BOLD\n"); +		fprintf(f,"HEXFIELD:       FG=WHITE,BG=BLACK\n"); +		fprintf(f,"INPUT:          FG=BLACK,BG=WHITE\n"); +		fprintf(f,"CURSOR:         FG=WHITE,BG=BLACK\n"); +		fprintf(f,"TEXT:           FG=LIGHTCYAN,BG=BLACK,BOLD\n"); +		fprintf(f,"MENU_NORMAL:    FG=LIGHTBLUE,BG=BLACK\n"); +		fprintf(f,"MENU_HIGHLIGHT: FG=LIGHTBLUE,BG=BLUE\n"); +		fprintf(f,"MENU_HOTKEY:    FG=CYAN,BG=BLACK\n"); +		fprintf(f,"MENU_HOTKEY_HI: FG=CYAN,BG=BLUE\n"); +		fprintf(f,"FRAME:          FG=BLUE,BG=BLACK\n"); +		fprintf(f,"NORMAL_DIFF:    FG=YELLOW,BG=BLACK,BOLD\n"); +		fprintf(f,"CURSOR_DIFF:    FG=YELLOW,BG=WHITE,BOLD\n"); +		fprintf(f,"HEADLINE:       FG=BLUE,BG=BLACK\n"); +		fprintf(f,"	\n"); +		fclose(f); +		retval=2; +	} +	if (retval==2) keyboardsetupreq=1; + +	hHexCalc=malloc(sizeof(thHexCalc)); +	memset(hHexCalc,0,sizeof(thHexCalc)); +	buf1=malloc(sizeof(tBuffer)); +	memset(buf1,0,sizeof(tBuffer)); +	if (diffmode) +	{ +		buf2=malloc(sizeof(tBuffer)); +		memset(buf2,0,sizeof(tBuffer)); +	} + +	if (openbuf(buf1,1,argv[filename1])!=RETOK) +	{ +		fprintf(stderr,"error opening inputfile %s\n",argv[filename1]); +		exit(1); +	} +	if (diffmode) if (openbuf(buf2,2,argv[filename2])!=RETOK) +	{ +		fprintf(stderr,"error opening second inputfile %s\n",argv[filename2]); +		exit(1); +	} +	if (gosearch1) searchfor(&search1,buf1,&cursorpos1,1); +	if (gosearch2 && diffmode) searchfor(&search2,buf2,&cursorpos2,1); +	if (gocorr && diffmode)	 +	{ +		fprintf(stderr,"correlating...\n"); +		find_correlation(NULL,&correlation,buf1,buf2,&cursorpos1,&cursorpos2); +	} +	if (!(gosearch1 && search1.writesearchlog) || (diffmode && !(gosearch2 && search2.writesearchlog))) +	{ +		output->win=initscr(); +		pairsinit(output); +		noecho(); +		nodelay(output->win,1); +		if (keyboardsetupreq) keyboardsetup(output,configfile); +		readbuf(buf1,0); +		firstpos1=cursorpos1; +		firstpos2=cursorpos2; +		ch=0; +		while (ch!=KEYF10) +		{	 +			printmainmenu(output,diffmode); +			if (diffmode) +				printbufferdiff(output,buf1,buf2,cursorpos1,cursorpos2); +			else		 +				printbuffersingle(output,buf1,cursorpos1,firstpos1,windowfield); +			ch=getkey((tKeyTab*)output->pKeyTab,1); + +#define	MOVEMENTDEFINE(KEY,VIKEY,mvchar,mvline,mvpage)	\ +			if (ch==KEY || (VIKEY && ch==VIKEY && windowfield==0))	\ +			{	\ +				tInt32	err;	\ +				oldfirstpos1=firstpos1;	\ +				oldcursorpos1=cursorpos1;	\ +				oldfirstpos2=firstpos2;	\ +				oldcursorpos2=cursorpos2;	\ +				\ +				err=movepositions(&cursorpos1,&firstpos1,buf1->bufsize,mvchar,mvline,mvpage,diffmode);	\ +				\ +				if (diffmode)	\ +				{	\ +					movepositions(&cursorpos2,&firstpos2,buf2->bufsize,mvchar,mvline,mvpage,diffmode);	\ +					err=((cursorpos1<0 && cursorpos2<0) || (cursorpos1>buf1->bufsize && cursorpos2>buf2->bufsize)); \ +				}	\ +				if (err)	\ +				{	\ +					firstpos1=oldfirstpos1;		\ +					cursorpos1=oldcursorpos1;	\ +					firstpos2=oldfirstpos2;		\ +					cursorpos2=oldcursorpos2;	\ +				}	\ +			} +			MOVEMENTDEFINE(KEYRIGHT,'l'	, 1, 0, 0); +			MOVEMENTDEFINE(KEYLEFT,'h'	,-1, 0, 0); +			MOVEMENTDEFINE(KEYDOWN,'j'	, 0, 1, 0); +			MOVEMENTDEFINE(KEYUP,'k'	, 0,-1, 0); +			MOVEMENTDEFINE(KEYPGDOWN,' '	, 0, 0, 1); +			MOVEMENTDEFINE(KEYPGUP,0	, 0, 0,-1); + +#undef	MOVEMENTDEFINE +			if (ch==KEYHOME || (ch=='^' && windowfield==0)) +			{ +				if (diffmode) +				{ +					tInt64	dmin,dmax; + +					dmin=MIN(cursorpos1,cursorpos2); +					dmax=MAX(cursorpos1,cursorpos2); +					if (dmin==0) +					{ +						cursorpos1-=dmax; +						cursorpos2-=dmax; +					} else { +						cursorpos1-=dmin; +						cursorpos2-=dmin; +					} +					firstpos1=cursorpos1; +					firstpos2=cursorpos2; + +				} else { +					firstpos1=cursorpos1=0; +				} +			} +			if (ch==KEYEND || (ch=='$' && windowfield==0)) +			{ +				if (diffmode) +				{ +					tInt64	dmin,dmax; +					dmin=MIN(buf1->bufsize-cursorpos1,buf2->bufsize-cursorpos2); +					dmax=MAX(buf1->bufsize-cursorpos1,buf2->bufsize-cursorpos2); + +					if (dmin==0) +					{ + +						cursorpos2+=dmax; +						cursorpos1+=dmax; +					} else { +						cursorpos1+=dmin; +						cursorpos2+=dmin; +					} +				} else { +					firstpos1=cursorpos1=buf1->bufsize; +				} +			} +			if (ch==KEYTAB) {windowfield=(windowfield+1)&1;} +			if ((ch==KEYF1 || (ch==':' && windowfield==0))&& !diffmode)	{ +				if (gotomask(output,markers,&cursorpos1)==RETOK) +				{ +					firstpos1=cursorpos1;	 +				} +			} +			if ((ch==KEYF2 || ((ch=='/' || ch=='?') && (windowfield==0))) && !diffmode)	 +			{ +				if (ch=='/')	search1.forwardnotbackward=1;	// / means forward +				if (ch=='?')	search1.forwardnotbackward=0;	// ? means backward +				searchmask(output,&search1,buf1,&cursorpos1); +				firstpos1=cursorpos1; +			} +			if (ch==KEYF3 || ch==KEYF4 || (windowfield==0 && (ch=='n' || ch=='N'))) +			{ +				if (ch=='n')	ch=KEYF3;	// n=next +				if (ch=='N')	ch=KEYF4;	// N=previous +				if (diffmode) +				{ +					tInt64	actcursorpos1=cursorpos1; +					tInt64	actcursorpos2=cursorpos2; +					tInt32	idx1,idx2; +					tBool	found; +					tBool	diffnotdiff; +					tUInt64	minbufsize=(buf1->bufsize<buf2->bufsize)?buf1->bufsize:buf2->bufsize;	// get the minimum of the filesizes +					tUInt64	searchcnt=minbufsize; + +					oldcursorpos1=cursorpos1; +					oldcursorpos2=cursorpos2; +					actcursorpos1=actcursorpos1+((ch==KEYF3)?1:-1);	// F3: next, F4:prev +					actcursorpos2=actcursorpos2+((ch==KEYF3)?1:-1);	// F3: next, F4:prev +					found=(!minbufsize); +					idx1=getbufferidx(buf1,actcursorpos1); +					idx2=getbufferidx(buf2,actcursorpos2); +					diffnotdiff=(buf1->data[idx1]!=buf2->data[idx2]);	// if the cursor is on something which is a diff, look for the next time the values are the same +					while (actcursorpos1!=oldcursorpos1 && actcursorpos2!=oldcursorpos2 && searchcnt && !found) +					{ +						idx1=getbufferidx(buf1,actcursorpos1); +						idx2=getbufferidx(buf2,actcursorpos2); +						if ((buf1->data[idx1]!=buf2->data[idx2]) != diffnotdiff) found=1; +						else 	{ +							actcursorpos1=actcursorpos1+((ch==KEYF3)?1:-1);	// F3: next, F4:prev +							actcursorpos2=actcursorpos2+((ch==KEYF3)?1:-1);	// F3: next, F4:prev +						} +						if (actcursorpos1<0 || actcursorpos2<0)  +						{ +							actcursorpos1+=minbufsize;	// start at the end of the smallest file +							actcursorpos2+=minbufsize;	// start at the end of the smallest file +						} +						if (actcursorpos1>=minbufsize && actcursorpos2>=minbufsize) +						{ +							actcursorpos1-=minbufsize;		// if you are at the end of the smallest file, start at the beginning +							actcursorpos2-=minbufsize;		// if you are at the end of the smallest file, start at the beginning +						} +						searchcnt--;	 +					} +					if (found)  +					{ +						cursorpos1=actcursorpos1; +						cursorpos2=actcursorpos2; +					} +				}  +				else if (search1.occurancesfound) +				{ +					searchfor(&search1,buf1,&cursorpos1,(ch==KEYF3));	// f3: next +					firstpos1=cursorpos1; +				} +			}	 +			if (ch==KEYF5)	hexcalc(output,hHexCalc); +			if (ch==KEYF6 && diffmode) +			{ +				correlation.start_mindiff=MIN(buf1->bufsize,buf2->bufsize); +				if (correlationmask(output,&correlation)==RETOK) +				{ +					find_correlation(output,&correlation,buf1,buf2,&cursorpos1,&cursorpos2); +				} +			} +			if ((ch==KEYF9 || (ch=='u' && windowfield==0)) && !diffmode) +			{ +				if (buf1->changesnum)  +				{ +					if ((buf1->changes[buf1->changesnum].pos==(buf1->bufsize-1) && (buf1->filesize<=buf1->changes[buf1->changesnum].pos))) buf1->bufsize--;	// if this was the last byte in the buffer, decrease its size +					cursorpos1=buf1->changes[--buf1->changesnum].pos; +					if (cursorpos1<firstpos1) firstpos1=cursorpos1; +					if ((firstpos1+100)>cursorpos1) firstpos1=cursorpos1;	// TODO: 100 depends on the size of the window +				} + +			} +			if (buf1->changesnum<CHANGEBUFSIZE-1 && !diffmode) +			{ +				if (((ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F')) && windowfield==0) +				{ +					buf1->nexthex<<=4; +					if (ch>='a') ch-=32; +					buf1->nexthex|=((ch>='A')?(ch-'A'+10):(ch-'0')); +					if (buf1->nibble) +					{ +						if (cursorpos1==buf1->bufsize) buf1->bufsize++;	// append the byte at the end +						buf1->changes[buf1->changesnum].pos=cursorpos1; +						buf1->changes[buf1->changesnum].after=buf1->nexthex; +						buf1->changesnum++; +						movepositions(&cursorpos1,&firstpos1,buf1->bufsize,1,0,0,diffmode); +					} +					buf1->nibble=!buf1->nibble; +					buf1->changepos=cursorpos1; +				} else buf1->nibble=0; +				if (ch>=32 && ch<127 && windowfield==1) +				{ +					if (cursorpos1==buf1->bufsize) buf1->bufsize++;	// append the byte at the end +					buf1->changes[buf1->changesnum].pos=cursorpos1; +					buf1->changes[buf1->changesnum].after=ch; +					buf1->changesnum++; +					movepositions(&cursorpos1,&firstpos1,buf1->bufsize,1,0,0,diffmode); +				} +			} +			if (ch==KEYF10) +			{ +				if (buf1->changesnum) if (savedialog(output,buf1)!=RETOK) +				{ +					ch=0; +				} +			} +		} +		if (output) +		{ +			if (output->pKeyTab) free(output->pKeyTab); +			free(output); +		} +		if (buf1) free(buf1); +		if (buf2) free(buf2); +		if (hHexCalc)	free(hHexCalc); +		if (markers)	free(markers); +		if (output->win) endwin(); +		welcomescreen(argv[0]); +	} else { +		if (gosearch1) fprintf(stderr,"%lli occurances found in %s\n",search1.occurancesfound,buf1->filename); +		if (gosearch2) fprintf(stderr,"%lli occurances found in %s\n",search2.occurancesfound,buf2->filename); +	} +	return 0; +} + | 
