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); }