HexEditor written in C, using curses written in Xcode 6


Open Xcode

File -> New Project

OSX -> Application -> Command Line Tool

Next

Product Name: Hexedit

Organization: com.skills421

Language: C

compile on the command line using: gcc -o hexedit hexedit.c -lcurses

#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OFF 0
#define ASC 1
#define HEX 2

void keyoffset();
void keysearch();
void showcurr();
void delcurr();
void hexent();
void currdown(int delcur);
void currup(int delcur);
void ascent();
int redrawfl();
int getinpstr(char *str,int mx);
int checkrest(char *str);

FILE *f1, *fopen();
int linebuf[18],  cyp=0, cxp=0, llp, lastline=FALSE, maxl, modeon=OFF, holdchar; WINDOW *win;
long fp=0, lfp; char modetp[15], wron[10];

int main(int argc, const char * argv[])
{
int c;

if(argc!=2)
{
printf("Incorrect number of arguments\nUse hexedit filename");
exit(1);
}

if((f1=fopen(argv[1],"r+"))==(FILE *) NULL)
{
printf("could not open file %s for input\n",argv[1]);
exit(1);
}

initscr();
curs_set(0);
win=newwin(23,80,1,0);
noecho();
cbreak();
nonl();
intrflush(win,FALSE);
keypad(win,TRUE);
idlok(win,TRUE);    // allow hardware scrolling
scrollok(win,TRUE);
lfp = fseek(f1,0L,2);
lfp = ftell(f1);
llp=(lfp-1) %16;
rewind(f1);
maxl=redrawfl();

strcpy(wron,"");
strcpy(modetp,"");
showcurr();

while((c=wgetch(win)) != KEY_F0 && c!=26 && c!='x' && c!='X')
{
switch(c)
{
case KEY_RIGHT:
case 12:
delcurr();
if(++cxp==16)
{
cxp=0;
currdown(0);
}
else
showcurr();

break;

case KEY_LEFT:
case 8:
delcurr();
if(--cxp==-1)
{
cxp=15;
currup(0);
}
else
showcurr();

break;

case KEY_UP:
case 11:
currup(1);
break;

case KEY_DOWN:
case 10:
currdown(1);
break;

case 'H':
case 'h':
modeon=HEX;
wmove(win,22,60);
strcpy(modetp,"MODE HEX");
wprintw(win,"%s   ",modetp);
wrefresh(win);
break;

case 'A':
case 'a':
modeon=ASC;
wmove(win,22,60);
strcpy(modetp,"MODE ASCII");
wprintw(win,"%s",modetp);
wrefresh(win);
break;

case 'W':
case 'w':
if(!modeon)
{
beep();
break;
}
if(modeon==ASC) ascent();
if(modeon==HEX) hexent();
break;

case 'O':
case 'o':
modeon=OFF;
wmove(win,22,60);
wclrtoeol(win);
wrefresh(win);
break;

case ':':
keyoffset();
break;

case '/':
keysearch();
break;

case 4:
if(fp+672<lfp)
{
delcurr();
fp+=336;
fseek(f1,fp,0);
redrawfl();
showcurr();
}
else
beep();

break;

case 21:
if(fp>335)
{
delcurr();
fp-=336;
redrawfl();
showcurr();
}
else
beep();

break;
}
}

endwin();
fclose(f1);

}

int read16(int pos)
{
int cnt;
long tfp;

tfp=fp+16*pos;
fseek(f1,tfp,0);

for(cnt=0;cnt<16;cnt++)
{
linebuf[cnt]=getc(f1);
if(linebuf[cnt]==EOF)
return(cnt);
}

return(16);
}

void displayline(int pos,int num)
{
int cnt,c;
long tfp;

tfp=fp+16*pos;
wmove(win,pos,0);
wprintw(win,"%06x:  ",(int) tfp);

for(cnt=0;cnt<num;cnt++)
{
wprintw(win,"%02x ",linebuf[cnt]);
}
wmove(win,pos,62);

for(cnt=0;cnt<num;cnt++)
{
c=(linebuf[cnt]>31 && linebuf[cnt]<126) ? linebuf[cnt] : '.';
waddch(win,c);
}

wrefresh(win);
}

void showcurr()
{
int c;

if(cyp==maxl && lastline && cxp>llp) cxp=llp;
wmove(win,cyp,3*cxp+8);
waddch(win,'>');
wmove(win,cyp,3*cxp+11);
waddch(win,'<');
c=mvwinch(win,cyp,cxp+62);
wattrset(win,A_STANDOUT);
waddch(win,c);
wattrset(win,0);
holdchar=c;
wrefresh(win);
}

void delcurr()
{
wmove(win,cyp,3*cxp+8);
waddch(win,' ');
wmove(win,cyp,3*cxp+11);
waddch(win,' ');
wmove(win,cyp,cxp+62);
waddch(win,holdchar);
}

void currdown(int delcur)
{
int num;
long tfp;

if(delcur) delcurr();

if(++cyp<=maxl)
showcurr();
else
{
cyp=maxl;

if(fp+336<lfp)
{
tfp=ftell(f1);
fp+=16;
if(fp+336>=lfp) lastline=TRUE;
num=read16(20);
fseek(f1,tfp,0);
if(modeon)
{
wmove(win,22,45);
wclrtoeol(win);
scroll(win);
wmove(win,22,45);
wprintw(win,"%s",wron);
wmove(win,22,60);
wprintw(win,"%s",modetp);
}
else
scroll(win);

displayline(20,num);
}
else
beep();

showcurr();
}
}

void currup(int delcur)
{
if(delcur) delcurr();

if(--cyp!=-1)
showcurr();
else
{
cyp=0;
if(fp>15)
{
lastline=FALSE;
fp-=16;
read16(0);

wmove(win,0,0);
winsertln(win);
wmove(win,21,0);
wclrtoeol(win);

if(modeon)
{
wmove(win,22,45);
wprintw(win,"%s",wron);
wmove(win,22,60);
wprintw(win,"%s",modetp);
}

displayline(0,16);
}
else
beep();

showcurr();
}
}

void ascent()
{
int c;

wmove(win,22,45);
strcpy(wron,"WRITE ON");
wprintw(win,"%s",wron);
fseek(f1,fp+cxp+cyp*16,0);
while((c=wgetch(win))!=KEY_F0 && c!=26)
{
switch(c)
{
case KEY_RIGHT:
case 12:
delcurr();
if(++cxp==16)
{
cxp=0;
currdown(0);
}
else
showcurr();

fseek(f1,fp+cxp+cyp+16,0);
break;

case KEY_LEFT:
case 8:
delcurr();
if(--cxp == -1)
{
cxp=15;
currup(0);
}
else
showcurr();

fseek(f1,fp+cxp+cyp*16,0);
break;

case KEY_UP:
case 11:
currup(1);
fseek(f1,fp+cxp+cyp*16,0);
break;

case KEY_DOWN:
case 10:
currdown(1);
fseek(f1,fp+cxp+cyp*16,0);
break;

default:
putc(c,f1);
wmove(win,cyp,3*cxp+9);
wprintw(win,"%02x",c);
wmove(win,cyp,cxp+62);
if(c<32||c>125) c='.';
holdchar=c;
wprintw(win,"%c",c);
wrefresh(win);
delcurr();

if(++cxp==16)
{
cxp=0;
currdown(0);
}
else
showcurr();

break;
}
}

wmove(win,22,45);
strcpy(wron,"");
wprintw(win,"            ");
wrefresh(win);
}

void hexent()
{
int c, currval=0;

wmove(win,22,45);
strcpy(wron,"WRITE ON");
wprintw(win,"%s",wron);
fseek(f1,fp+cxp+cyp*16,0);
while((c=wgetch(win))!=KEY_F0 && c!=26)
{
switch(c)
{
case KEY_RIGHT:
case 12:
delcurr();
if(++cxp==16)
{
cxp=0;
currdown(0);
}
else
showcurr();

fseek(f1,fp+cxp+cyp*16,0);
currval=0;
break;

case KEY_LEFT:
case 8:
delcurr();
if(--cxp==-1)
{
cxp=15;
currup(0);
}
else
showcurr();

fseek(f1,fp+cxp+cyp*16,0);
currval=0;
break;

case KEY_UP:
case 11:
currup(1);
fseek(f1,fp+cxp+cyp*16,0);
currval=0;
break;

case KEY_DOWN:
case 10:
currdown(1);
fseek(f1,fp+cxp+cyp*16,0);
currval=0;
break;

default:
c = c |  32;
if((c>='0' && c<='9') || (c>='a' && c<='f'))
{
currval%=16;
currval*=16;
c=(c>'9') ? c-87 : c-48;
currval=currval+c;
putc(currval,f1);
fseek(f1,-1L,1);
wmove(win,cyp,3*cxp+9);
wprintw(win,"%02x",currval);
wmove(win,cyp,cxp+62);
c=(currval<32||currval>125)?'.':currval;
holdchar=c;
wprintw(win,"%c",c);
wrefresh(win);
break;
}
else
beep();
}
}

wmove(win,22,45);
strcpy(wron,"");
wprintw(win,"         ");
wrefresh(win);
}

void keyoffset()
{
int tmpvar;
char instr[8];
long dval;

wmove(win,22,0);
wechochar(win,':');
if(getinpstr(instr,6)) return;
if(instr[0]=='$')
{
if(lfp<337)
{
beep();
return;
}

fp=lfp-336;
tmpvar=lfp%16;
fp-=tmpvar;
if(tmpvar) fp+=16;
fseek(f1,fp,0);
cyp=redrawfl();
cxp=((lfp-1)%16);
lastline=TRUE;
showcurr();
return;
}

dval=strtol(instr,(char **)NULL,16);

if(dval>lfp-336)
{
beep();
return;
}

cxp=tmpvar=dval%16;
cyp=0;
fp=dval-cxp;
fseek(f1,fp,0);
redrawfl();
showcurr();
return;
}

int getinp(char *str,int mx)
{
int cnt=0, c;

while((c=wgetch(win))!=KEY_F0 && c!=26 && c!=13 && cnt<mx)
{
if((c>='0' && c<='9') || (c>='a' && c<='f'))
{
str[cnt++]=c;
wechochar(win,c);
}

if(cnt==0 && c=='$')
{
str[cnt++]='$';
break;
}
}

str[cnt]='\0';
wmove(win,22,0);
wclrtoeol(win);
wrefresh(win);
if(c==KEY_F0 || c==26) return(1);
return(0);
}

int redrawfl()
{
int cnt,tmaxl,num;

werase(win);

for(cnt=0;cnt<=20;cnt++)
{
num=read16(cnt);

if(num)
displayline(cnt,num);
else
cnt--;

if(num<16)
{
lastline=TRUE;
break;
}
}

tmaxl=(cnt==21) ? 20 : cnt;
return(tmaxl);
}

void keysearch()
{
int c;
char instr[22];
long rel,tfp;

tfp=(long) fp+cxp+cyp*16;
fseek(f1,++tfp,0);
wmove(win,22,0);
wechochar(win,'/');

if(getinpstr(instr,20)) return;

while((c=getc(f1))!=EOF)
{
if(c==instr[0])
{
if(checkrest(instr))
{
delcurr();
tfp=ftell(f1)-1;
rel=tfp-(fp+cxp+cyp*16);

if(rel+cxp+cyp*16<336)
{
cyp=cyp+(int)((rel+cxp)/16);
cxp=(rel+cxp)%16;
showcurr();
}
else
{
fp=fp+rel+cxp+cyp*16-320;
cxp=(rel+cxp)%16;
cyp=20;
fp-=cxp;
fseek(f1,fp,1);
redrawfl();
showcurr();
}

return;
}
}
}

beep();
}

int checkrest(char *str)
{
int cnt,c=1;
char findstr[22];
long tfp;

for(cnt=1;cnt<strlen(str)&&c!=EOF;cnt++)
{
c=getc(f1);
findstr[cnt]=c;
}

if(c==EOF) return(0);
tfp=1-cnt;
fseek(f1,tfp,1);
findstr[cnt]='\0';
if(strcmp(&str[1],&findstr[1])==0) return(1);
return(0);
}

int getinpstr(char *str,int mx)
{
int cnt=0,c;

while((c=wgetch(win)) !=KEY_F0 && c!=26 && c!=13 && cnt<mx)
{
str[cnt++]=c;
wechochar(win,c);
}

str[cnt]='\0';
wmove(win,22,0);
wclrtoeol(win);
wrefresh(win);

if(c==KEY_F0 || c==26) return(1);
return(0);
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Up ↑

%d bloggers like this: