#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; 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; int result; char *ptv="12345678"; FILE *fp; int ipoint; data daten,*pdaten,*pfirst, *phelp; 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; 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(2)); 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; 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; } } /* 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=pfirst; for(;(*pdaten).pnext;pdaten=(*pdaten).pnext) ; 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(2)); 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] = ((((*pdaten).vals[z]) > 31)&&((*pdaten).vals[z] != 127))?((*pdaten).vals[z]):254; } 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++; } } void charin(char ch) { int i=0; // im Speicher zur Cusrorposition blättern while(i<(16-pos.y)&&((*pdaten).plast)) { i++; pdaten=(*pdaten).plast; } // Wert schreiben (*pdaten).vals[pos.x-1]=ch; // Ausgabe aktualisieren lineout(pos.y); // wieder zurückblättern while(i--) { pdaten=(*pdaten).pnext; } } 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; //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); mvwaddstr(wbot,1,1,argv[1]); //Hauptprogramm initout(); scrrefresh(); //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_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: 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"; // TODO hch korrekt füllen. if(pos.x%3) switchmode(); // um die Koordinaten umzurechnen charin(xto10(hch,16)); // Umrechnen Hex -> Ascii+charin switchmode(); // und wieder zurücksetzen moveright(); } } else { //if((inpch > 31)&&(inpch < 256)) if((inpch < 256)) { waddch(wascii,inpch); charin(inpch); moveright(); } } }; scrrefresh(); } sleep(1); endscr(); unallocmem(); return (fclose(fp)); }