#include #include #include #include #include struct data // Eine Zeile Speicher { struct data* plast; struct data* pnext; unsigned char vals[16]; unsigned long zeile; char len; }; struct cpos // Cursor-Position { char x,y; }pos; char insovr='O'; // Isert/Override-Mode int mode=1; WINDOW *stdscr,*woffs,*whex, *wascii, *wtop, *wbot; const char *topline= " Offset Hex ASCII "; char xoffs[] = "12345678",*soffs; char xhex[] = " 14 15 16 32 32 34 20 54 61 67 65 73 61 6D 74 0D ",*shex; char xascii[] = "1234567890123456",*sascii; char empty78[]=" "; int result; char *filename; char *ptv="12345678"; FILE *fp; int ipoint; data daten, *pdaten, *pfirst, *phelp, *pmax; void initvar() { pfirst=&daten; (*pfirst).plast=NULL; (*pfirst).pnext=NULL; (*pfirst).zeile=0; (*pfirst).len=0; soffs=xoffs; shex=xhex; sascii=xascii; } void miniinit() { xoffs = " "; xhex = " "; xascii = " "; } int screeninit() { int retval=0; stdscr= initscr(); if(start_color()) retval=1; nonl(); intrflush(stdscr, FALSE); keypad(stdscr, TRUE); // Zwei Fenster woffs =newwin(18,10,3 ,0 ); whex =newwin(18,52,3 ,10); wascii=newwin(18,18,3 ,62); wtop =newwin(3 ,80,0 ,0 ); wbot =newwin(4 ,80,21,0 ); // Scrollen erlauben scrollok(woffs,1); scrollok(whex,1); scrollok(wascii,1); // Tastatureingabe erlauben keypad(stdscr,1); keypad(whex,1); keypad(wascii,1); // Echo ausschalten noecho(); // Cursor auf Groß setzen // if(curs_set(2)==ERR) retval=1 ; // Color-Pairs anlegen (Farbkombinationen) if(init_pair(1,COLOR_BLUE,COLOR_BLACK)) retval=1; if(init_pair(2,COLOR_CYAN,COLOR_BLACK)) retval=1; if(init_pair(3,COLOR_MAGENTA,COLOR_BLACK)) retval=1; wattrset(woffs,COLOR_PAIR(1)); wattrset(whex,COLOR_PAIR(1)); wattrset(wascii,COLOR_PAIR(1)); wattrset(wbot,COLOR_PAIR(1)); wattrset(wtop,COLOR_PAIR(1)); box(woffs,0,0); box(whex,0,0); box(wascii,0,0); box(wtop,0,0); box(wbot,0,0); wattrset(woffs,COLOR_PAIR(2)); wattrset(whex,COLOR_PAIR(2)); wattrset(wascii,COLOR_PAIR(2)); wattrset(wtop,COLOR_PAIR(3)); wattrset(wbot,COLOR_PAIR(2)); return(retval); } char* tonumsysx(int base10,int newbase) { int erg; int rest=0; int pos=0; int i; static char swap[9]; char c[9]; swap="********"; c[pos]='0'+rest; while (base10 > 0) { erg=base10/newbase; rest=base10%newbase; if (rest <= 9) c[pos]='0'+rest; else c[pos]='A'+(rest-10); base10=erg; pos++; c[pos]='\0'; } while(pos < 8) { c[pos]='0'; pos++; } pos--; for (i=0;i<=pos;i++) { swap[i]=c[pos-i]; } return(swap); } unsigned long xto10(char *c, int oldbase) { unsigned long base10=0; unsigned long rest,erg; int pos=0; int i; for (i=0;c[i];i++, c[i]=toupper(c[i])); while(c[pos++]); pos--; int len=pos-1; while(pos--) { if(isdigit(c[len-pos])) { base10 = base10 + (unsigned long)( (double)(c[len-pos]-'0') * ( pow( (double)oldbase,(double)pos ) ) ) ; } else { base10 = base10 + (unsigned long)( ((double)(c[len-pos]-'A')+10) * ( pow( (double)oldbase,(double)pos ) ) ); } } return(base10); } int loadcontents() { int retval=0; int x; char ch; int k=0; unsigned long zeile=0; pdaten=pfirst; ch=fgetc(fp); printf("Printing hashmark for every 8 Kbytes.\n"); while (!(feof(fp))) { for(x=0;x<16;x++) { ((*pdaten).vals[x])=ch; if (feof(fp)) //(*pdaten).vals[x]==EOF) { (*pdaten).vals[x]=0; break; } (*pdaten).len=x+1; ch=fgetc(fp); } (*pdaten).zeile=zeile++; if(!(feof(fp))) { phelp=pdaten; if (!(zeile%500)) {fprintf(stderr,"%c",'#');} pdaten=((*pdaten).pnext)=(malloc(sizeof(daten))); // BUG: Check for Memory-Full does not work. if(!pdaten) {abort();} (*pdaten).plast=phelp; (*pdaten).pnext=NULL; } pmax=pdaten; } /* D E B U G O N L Y pdaten=pfirst; printf("%d\n",zeile); while (zeile--) { for(x=0;x<16;x++) { printf("%c-",(*pdaten).vals[x]); } pdaten=(*pdaten).pnext; } getchar(); --- END DEBUG ---*/ return (retval); } void endscr() { delwin(woffs); delwin(whex); delwin(wascii); delwin(wtop); delwin(wbot); endwin(); } void unallocmem() { int zv; /* DEBUG ONLY pdaten=pfirst; int zeile=16; int x; printf("%d\n",zeile); while (zeile--) { for(x=0;x<16;x++) { printf("%c-",(*pdaten).vals[x]); } pdaten=(*pdaten).pnext; } getchar(); --- END DEBUG ---*/ pdaten=pmax; while((*pdaten).plast) { phelp=(*pdaten).plast; free(pdaten); pdaten=phelp; } } void scrrefresh() { wattrset(woffs,COLOR_PAIR(1)); wattrset(whex,COLOR_PAIR(1)); wattrset(wascii,COLOR_PAIR(1)); wattrset(wbot,COLOR_PAIR(1)); wattrset(wtop,COLOR_PAIR(1)); box(woffs,0,0); box(whex,0,0); box(wascii,0,0); box(wtop,0,0); box(wbot,0,0); wattrset(woffs,COLOR_PAIR(2)); wattrset(whex,COLOR_PAIR(2)); wattrset(wascii,COLOR_PAIR(2)); wattrset(wtop,COLOR_PAIR(3)); wattrset(wbot,COLOR_PAIR(2)); !mode?wmove(whex,pos.y,pos.x):wmove(wascii,pos.y,pos.x); wrefresh(woffs); wrefresh(wtop); wrefresh(wbot); // die Reihenfolge wird anhand des Modus bestimmt (das letzte ist aktiv) !mode?wrefresh(wascii):wrefresh(whex); mode?wrefresh(wascii):wrefresh(whex); } void lineout(unsigned long zeile) { int z; miniinit(); ptv = tonumsysx((*pdaten).zeile*16,16); for(z=0;z<9;z++) { xoffs[z] = *(ptv+z); } mvwaddstr(woffs,zeile,1,soffs); for (z=0;z<(*pdaten).len;z++) { ptv = tonumsysx((*pdaten).vals[z],16); xhex[z*3+1] = *(ptv+6); xhex[z*3+2] = *(ptv+7); } mvwaddstr(whex,zeile,1,shex); for (z=0;z<(*pdaten).len;z++) { // BUG: Die Ober- und Untergrenze genau bestimmen. xascii[z] = (isgraph((*pdaten).vals[z]))?((*pdaten).vals[z]):'.'; } mvwaddstr(wascii,zeile,1,sascii); } void initout() { //Initiale Ausgabe (Alle) int i; bool schalter=false; unsigned long zeile=1; pdaten=pfirst; if ((*pdaten).pnext == NULL) schalter=true; for(i=0;i<16;i++) { lineout(i+1); if (schalter) break; pdaten=(*pdaten).pnext; if ((*pdaten).pnext == NULL) schalter=true; } scrrefresh(); if(i>15) pdaten=(*pdaten).plast; } void scrolld() { wscrl(woffs,1); wscrl(whex,1); wscrl(wascii,1); int z; miniinit(); lineout(16); } void scrollu() { wscrl(woffs,-1); wscrl(whex,-1); wscrl(wascii,-1); miniinit(); lineout(1); } void switchmode() { if(mode==0) { mode=1; // modus:Hex->Ascii // Umrechnen der Cursorposition pos.x=((pos.x+1)/3); } else { mode=0; // modue:Ascii->Hex // Umrechnen der Cursorposition pos.x=((pos.x*3)-1); } } void moveleft() { if(mode==0) { if(pos.x > 2)(pos.x%3)?pos.x-=2:pos.x--; } else { if(pos.x > 1)pos.x--; } } void moveright() { if(mode==0) { if(pos.x < 48)(pos.x%3)?pos.x++:pos.x+=2; } else { if(pos.x < 16)pos.x++; } } unsigned long getactpos() { int i=0; unsigned long actpos; int posxsave=9999; if (!mode) { posxsave=pos.x; switchmode(); } // im Speicher zur Cusrorposition blättern while(i<(16-pos.y)&&((*pdaten).plast)) { i++; pdaten=(*pdaten).plast; } // Position holen actpos=((*pdaten).zeile*16)+pos.x-1; // wieder zurückblättern while(i--) { pdaten=(*pdaten).pnext; } if (posxsave!=9999) { switchmode(); pos.x=posxsave; } return(actpos); } void charin(char ch) { int i=0; int z=0; int sicchar=9999; // Das eigentliche Enfügen des Zeichens // im Speicher zur Cusrorposition blättern while(i<(16-pos.y)&&((*pdaten).plast)) { i++; pdaten=(*pdaten).plast; } if (insovr=='I') // In Override-Mode { phelp=pdaten; pdaten=pmax; if ((*pdaten).len < 16) { (*pdaten).len++; } else { // allocate new element } while(pdaten!=phelp) { for(z=(*pdaten).len;z>0;z--) { (*pdaten).vals[z]=(*pdaten).vals[z-1]; } (*pdaten).vals[0]=(*(*pdaten).plast).vals[15]; pdaten=(*pdaten).plast; } for(z=(*pdaten).len;z+1>pos.x;z--) { (*pdaten).vals[z]=(*pdaten).vals[z-1]; } pdaten=phelp; } // Wert schreiben (*pdaten).vals[pos.x-1]=ch; // Ausgabe aktualisieren lineout(pos.y); // wieder zurückblättern while(i--) { pdaten=(*pdaten).pnext; } } int charout() { int i=0; int ch; // im Speicher zur Cusrorposition blättern while(i<(16-pos.y)&&((*pdaten).plast)) { i++; pdaten=(*pdaten).plast; } // Wert lesen ch=((*pdaten).vals[pos.x-1]); // wieder zurückblättern while(i--) { pdaten=(*pdaten).pnext; } return(ch); } void bottomout() { mvwaddstr(wbot,1,1,empty78); mvwaddstr(wbot,2,1,empty78); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,1,"CHR:"); wattrset(wbot,COLOR_PAIR(2)); mvwaddch(wbot,1,6,32); mvwaddch(wbot,1,5,(isgraph(charout()))?charout():'.'); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,9,"HEX:"); wattrset(wbot,COLOR_PAIR(2)); mvwaddstr(wbot,1,13,(tonumsysx(charout(),16))+6); mvwaddch(wbot,1,15,'h'); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,18,"DEC:"); wattrset(wbot,COLOR_PAIR(2)); mvwaddstr(wbot,1,22,(tonumsysx(charout(),10))+5); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,27,"OCT:"); wattrset(wbot,COLOR_PAIR(2)); mvwaddstr(wbot,1,31,(tonumsysx(charout(),8))+4); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,37,"BIN:"); wattrset(wbot,COLOR_PAIR(2)); mvwaddstr(wbot,1,41,tonumsysx(charout(),2)); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,52,"Offset:"); wattrset(wbot,COLOR_PAIR(2)); mvwaddstr(wbot,1,59,tonumsysx(getactpos(),16)); wattrset(wbot,COLOR_PAIR(3)); mvwaddstr(wbot,1,67,"h -"); wattrset(wbot,COLOR_PAIR(2)); mvwaddstr(wbot,1,71,tonumsysx(getactpos(),10)); mvwaddstr(wbot,2,1,filename); mvwaddstr(wbot,2,76,(insovr=='O')?"OVR":"INS"); } int main(int argc, char *argv[]) { /* --- DEBUG ONLY printf("DEBUG: 5-%u\n",xto10(tonumsysx(5,2),2)); printf("DEBUG: 16-%u\n",xto10(tonumsysx(16,16),16)); printf("DEBUG: 36-%u\n",xto10 (tonumsysx(36,36),36)); printf("DEBUG: 255-%u\n",xto10(tonumsysx(255,16),16)); printf("DEBUG: 255-%u\n",xto10("FF",16)); printf("DEBUG: 125-%u\n",xto10(tonumsysx(125,8),8)); printf("DEBUG: 255-%u\n",xto10(tonumsysx(255,8),8)); getchar(); --- END DEBUG */ //Variablen unsigned int i,z; // Allgemeine Zähler unsigned long zeile=0; // Zeilennummer bool schalter; // Schalter für lesevorlauf int inpch; // Eingabezeichen //Vorbereitung printf("GHEX Version 0.5\n"); //Parameter angegeben? if(argc < 2) { fprintf(stderr,"GHEX-MESSAGE:\n\nUSAGE: %s \n",argv[0]); exit(1); } //Datei öffnen fp=fopen(argv[1],"r"); if (fp == NULL) { fprintf(stderr,"GHEX-MESSAGE:\n\nERROR opening file: %s \n",argv[1]); exit(2); } // pointer setzen initvar(); // sonstige Variableninitialisierung pos.x = pos.y = 1; filename=argv[1]; //Datei -> Speicher if(loadcontents()) { fprintf(stderr,"GHEX-MESSAGE:\n\nERROR reading %s (too less RAM?)\n",argv[1]); exit(3); } // Terminal initialisieren if(screeninit()) { endscr(); fprintf(stderr,"!!!Terminal not supported!!! -> Abort \n"); exit(5); } mvwaddstr(wtop,1,1,topline); //Hauptprogramm initout(); bottomout(); scrrefresh(); /* --- DEBUG ONLY fprintf(stdout,"D%d\n",charout()); pos.x++; fprintf(stdout,"D%d\n",charout()); pos.x++; fprintf(stdout,"D%d\n",charout()); pos.x++; fprintf(stdout,"D%d\n",charout()); pos.x++; fprintf(stdout,"D%d\n",charout()); getchar(); -- END DEBUG */ //Eventschleife while(inpch!=KEY_F(10)) { if (mode==0) { inpch=wgetch(whex); } else { inpch=wgetch(wascii); } switch(inpch) { case KEY_F(9): switchmode(); break; case KEY_F(1): initout(); break; case KEY_EIC: //fallthru case KEY_IC : if (insovr=='O') { insovr='I'; } else { insovr='O'; } break; case KEY_LEFT: moveleft(); break; case KEY_RIGHT:moveright(); break; case KEY_DOWN: if(pos.y>15) { if ((*pdaten).pnext != NULL) { pdaten=(*pdaten).pnext; scrolld(); } } else { pos.y++; } break; case KEY_UP: if(pos.y<2) { z=0; while(((*pdaten).plast != NULL)&&(z < 16)) { pdaten=(*pdaten).plast; z++; } if(z>15) { z--; scrollu(); } while(z--) { if ((*pdaten).pnext != NULL) { pdaten=(*pdaten).pnext; } } } else { pos.y--; } break; case KEY_NPAGE: for(i=0;i<16;i++) { if ((*pdaten).pnext != NULL) { pdaten=(*pdaten).pnext; scrolld(); } } break; case KEY_PPAGE: for(i=0;i<16;i++) { z=0; while(((*pdaten).plast != NULL)&&(z < 16)) { pdaten=(*pdaten).plast; z++; } if(z>15) { z--; scrollu(); } while(z--) { if ((*pdaten).pnext != NULL) { pdaten=(*pdaten).pnext; } } } break; case KEY_HOME: initout(); break; case KEY_END: pdaten=pmax; for(i=0;((*pdaten).plast) && (i < 16);i++) { pdaten=(*pdaten).plast; } while((*pdaten).pnext) { if ((*pdaten).pnext != NULL) { pdaten=(*pdaten).pnext; scrolld(); } } break; default: if(mode==0) { if(isdigit(inpch) || (toupper(inpch)>='A' && toupper(inpch)<='F') ) { waddch(whex,toupper(inpch)); char hch[]="FF"; // hch korrekt füllen. int xpos=pos.x; // Position sichern switchmode(); // um die Koordinaten umzurechnen ptv=tonumsysx(charout(),16); // Aktuelles Zeichen in Hex. //* --- DEBUG ONLY mvwaddstr(wbot,2,30,tonumsysx(charout(),16)); // --- END DEBUG switchmode(); // Koordinaten zurückrechnen pos.x=xpos; // position restaurieren hch[0] = *(ptv+6); hch[1] = *(ptv+7); //* --- DEBUG ONLY mvwaddstr(wbot,2,1,hch); mvwaddstr(wbot,2,20,ptv); // --- END DEBUG hch[(pos.x%3)?0:1]=inpch; switchmode(); // um die Koordinaten umzurechnen charin(xto10(hch,16)); // Umrechnen Hex -> Ascii+charin switchmode(); // und wieder zurücksetzen pos.x=xpos; // position restaurieren moveright(); } } else { if((inpch < 256)) { waddch(wascii,inpch); charin(inpch); moveright(); } } }; bottomout(); scrrefresh(); // fprintf(stderr,"x: %d %d",pos.x,charout()); } sleep(1); endscr(); unallocmem(); return (fclose(fp)); }