From c2d6ad382f70f99f5f817380ee54ef05b7805570 Mon Sep 17 00:00:00 2001 From: singe Date: Thu, 7 May 2020 11:06:28 +0200 Subject: [PATCH 1/3] Added initial per-byte notes functionality. --- display.c | 1 + hexedit.c | 12 +++++++++--- hexedit.h | 9 ++++++++- interact.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/display.c b/display.c index 9b4df91..5993430 100644 --- a/display.c +++ b/display.c @@ -207,6 +207,7 @@ void display(void) if (MAX(fileSize, lastEditedLoc)) printw("/0x%llX", (long long) getfilesize()); printw("--%i%%", 100 * (base + cursor + getfilesize()/200) / getfilesize() ); if (mode == bySector) printw("--sector %lld", (long long) ((base + cursor) / SECTOR_SIZE)); + if (notes[base+cursor].note) printw("--note: %s", notes[base+cursor].note); move(cursor / lineLength, computeCursorXCurrentPos()); } diff --git a/hexedit.c b/hexedit.c index 6ab2ed7..addb312 100644 --- a/hexedit.c +++ b/hexedit.c @@ -30,9 +30,10 @@ int sizeCopyBuffer, *bufferAttr; char *progName, *fileName, *baseName; unsigned char *buffer, *copyBuffer; typePage *edited; +noteStruct *notes; +size_t notes_size=NOTE_SIZE; -char *lastFindFile = NULL, *lastYankToAFile = NULL, *lastAskHexString = NULL, *lastAskAsciiString = NULL, *lastFillWithStringHexa = NULL, *lastFillWithStringAscii = NULL; - +char *lastFindFile = NULL, *lastYankToAFile = NULL, *lastAskHexString = NULL, *lastAskAsciiString = NULL, *lastFillWithStringHexa = NULL, *lastFillWithStringAscii = NULL, *lastNote = NULL; const modeParams modes[LAST] = { { 8, 16, 256 }, @@ -53,6 +54,7 @@ const char * const usage = "usage: %s [-s | --sector] [-m | --maximize] [-l | /*******************************************************************************/ int main(int argc, char **argv) { + progName = basename(argv[0]); argv++; argc--; @@ -119,6 +121,7 @@ void init(void) hexOrAscii = TRUE; copyBuffer = NULL; edited = NULL; + notes = (noteStruct*) calloc(notes_size,sizeof(noteStruct)); } void quit(void) @@ -129,7 +132,10 @@ void quit(void) free(bufferAttr); FREE(copyBuffer); discardEdited(); - FREE(lastFindFile); FREE(lastYankToAFile); FREE(lastAskHexString); FREE(lastAskAsciiString); FREE(lastFillWithStringHexa); FREE(lastFillWithStringAscii); + FREE(lastFindFile); FREE(lastYankToAFile); FREE(lastAskHexString); FREE(lastAskAsciiString); FREE(lastFillWithStringHexa); FREE(lastFillWithStringAscii); FREE(lastNote); + for (int i=0; i notes_size) { + notes_size = base+cursor+NOTE_SIZE; + notes = (noteStruct*) realloc(notes,notes_size*sizeof(noteStruct)); + } + + char tmp[BLOCK_SEARCH_SIZE], msg[BLOCK_SEARCH_SIZE]; + + // Check if we're adding a new note or changing a existing note + if (notes[base+cursor].note) { + strlcpy(lastNote, notes[base+cursor].note, NOTE_SIZE); + snprintf(msg, BLOCK_SEARCH_SIZE, "Change the note for 0x%llx: ", base+cursor); + } else + snprintf(msg, BLOCK_SEARCH_SIZE, "Enter a note for 0x%llx: ", base+cursor); + free(notes[base+cursor].note); + notes[base+cursor].note = NULL; + notes[base+cursor].note = (char*) malloc(NOTE_SIZE); + char** last = &lastNote; + + if (!displayMessageAndGetString(msg, last, tmp, sizeof(tmp))) return; + + // Overly paranoid, but clear the note before copying it in + memset(notes[base+cursor].note,'\0',NOTE_SIZE); + strlcpy(notes[base+cursor].note,tmp,NOTE_SIZE); +} + +static void get_note(void) +{ + if (notes[base+cursor].note) + displayMessageAndWaitForKey(notes[base+cursor].note); + else + displayMessageAndWaitForKey("No note set for current position!"); +} + +static void delete_note(void) +{ + if (notes[base+cursor].note) { + free(notes[base+cursor].note); + notes[base+cursor].note = NULL; + displayMessageAndWaitForKey("Note deleted"); + } +} + static void firstTimeHelp(void) { static int firstTime = TRUE; @@ -611,6 +656,18 @@ static void escaped_command(void) truncate_file(); break; + case 'o': + add_note(); + break; + + case 'g': + get_note(); + break; + + case 'd': + delete_note(); + break; + case '': c = getch(); if (c == 'O') { From 70d5edfc79aad756b1a897985d60e57bac7a1aff Mon Sep 17 00:00:00 2001 From: singe Date: Fri, 8 May 2020 09:39:49 +0200 Subject: [PATCH 2/3] Added initial custome color tagging for bytes or byte ranges --- display.c | 6 +++++- hexedit.h | 1 + interact.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/display.c b/display.c index 5993430..8b3ca14 100644 --- a/display.c +++ b/display.c @@ -131,6 +131,9 @@ void initCurses(void) init_pair(1, COLOR_RED, -1); /* null zeros */ init_pair(2, COLOR_GREEN, -1); /* control chars */ init_pair(3, COLOR_BLUE, -1); /* extended chars */ + init_pair(5, COLOR_CYAN, -1); /* custom tag color */ + init_pair(6, COLOR_MAGENTA, -1); /* custom tag color */ + init_pair(7, COLOR_YELLOW, -1); /* custom tag color */ } init_pair(4, COLOR_BLUE, COLOR_YELLOW); /* current cursor position*/ #endif @@ -207,7 +210,7 @@ void display(void) if (MAX(fileSize, lastEditedLoc)) printw("/0x%llX", (long long) getfilesize()); printw("--%i%%", 100 * (base + cursor + getfilesize()/200) / getfilesize() ); if (mode == bySector) printw("--sector %lld", (long long) ((base + cursor) / SECTOR_SIZE)); - if (notes[base+cursor].note) printw("--note: %s", notes[base+cursor].note); + if (notes_size >= (base+cursor)) if (notes[base+cursor].note) printw("--note: %s", notes[base+cursor].note); move(cursor / lineLength, computeCursorXCurrentPos()); } @@ -226,6 +229,7 @@ void displayLine(int offset, int max) #ifdef HAVE_COLORS (!colored ? 0 : (cursor == i && hexOrAscii == 0 ? mark_color : + bufferAttr[i] & TAGGED ? 0 : buffer[i] == 0 ? (int) COLOR_PAIR(1) : buffer[i] < ' ' ? (int) COLOR_PAIR(2) : buffer[i] >= 127 ? (int) COLOR_PAIR(3) : 0) diff --git a/hexedit.h b/hexedit.h index 2abacec..a6dde14 100644 --- a/hexedit.h +++ b/hexedit.h @@ -51,6 +51,7 @@ #define NORMAL A_NORMAL #define MARKED A_REVERSE #define MODIFIED A_BOLD +#define TAGGED A_STANDOUT #define ATTRPRINTW(attr, a) do { if (oldattr != (attr)) attrset(attr), oldattr = (attr); printw a; } while (0) #define MAXATTRPRINTW(attr, a) do { if (oldattr & (~(attr))) attrset(attr & oldattr), oldattr &= (attr); printw a; } while (0) #define PRINTW(a) ATTRPRINTW(NORMAL, a) diff --git a/interact.c b/interact.c index 0396ec2..e83666c 100644 --- a/interact.c +++ b/interact.c @@ -200,6 +200,8 @@ static void add_note(void) if (!displayMessageAndGetString(msg, last, tmp, sizeof(tmp))) return; + // You don't actually see this, but it clears artifacts left on the screen + displayOneLineMessage("Note Set"); // Overly paranoid, but clear the note before copying it in memset(notes[base+cursor].note,'\0',NOTE_SIZE); strlcpy(notes[base+cursor].note,tmp,NOTE_SIZE); @@ -222,6 +224,44 @@ static void delete_note(void) } } +static void change_color(void) +{ + //CYAN MAGENTA YELLOW + displayOneLineMessage("Tag this byte with which color (1/2/3)?"); + int color=0; + switch (getch()) + { + case '1': color = (int) COLOR_PAIR(5); break; + case '2': color = (int) COLOR_PAIR(6); break; + case '3': color = (int) COLOR_PAIR(7); break; + default: displayMessageAndWaitForKey("Invalid choice, must be between 1-3"); return; + } + // Are we changing a range or a single byte? + if (mark_set) + for (int i = MAX(mark_min - base, 0); i <= MIN(mark_max - base, nbBytes - 1); i++) + { + // It's late and I'm too tired to work out how to nix the color but + // preserve the other bits + int m = bufferAttr[i] & MARKED; + int b = bufferAttr[i] & A_BOLD; + bufferAttr[i] = color; + bufferAttr[i] |= TAGGED; + bufferAttr[i] |= m; + bufferAttr[i] |= b; + } + else + { + // It's late and I'm too tired to work out how to nix the color but + // preserve the other bits + int m = bufferAttr[i] & MARKED; + int b = bufferAttr[i] & A_BOLD; + bufferAttr[cursor] = color; + bufferAttr[cursor] |= TAGGED; + bufferAttr[i] |= m; + bufferAttr[i] |= b; + } +} + static void firstTimeHelp(void) { static int firstTime = TRUE; @@ -340,7 +380,9 @@ static void save_buffer(void) edited = NULL; if (lastEditedLoc > fileSize) fileSize = lastEditedLoc; lastEditedLoc = 0; - memset(bufferAttr, A_NORMAL, page * sizeof(*bufferAttr)); + //memset(bufferAttr, A_NORMAL, page * sizeof(*bufferAttr)); + for (int i=base; i Date: Tue, 26 May 2020 17:19:01 +0200 Subject: [PATCH 3/3] Added tag file reading and writing. --- file.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hexedit.c | 6 ++- hexedit.h | 5 ++ interact.c | 29 ++++++---- 4 files changed, 181 insertions(+), 10 deletions(-) diff --git a/file.c b/file.c index b14fa4f..29a202e 100644 --- a/file.c +++ b/file.c @@ -134,4 +134,155 @@ int is_file(char *name) return stat(name, &st) != -1 && !S_ISDIR(st.st_mode); } +void openTagFile(void) +{ + // tagFile 0 - doesn't exist, 1 - problem, 2 - read only, 3 - read write + + char tagFileName[BLOCK_SEARCH_SIZE]; + snprintf(tagFileName, BLOCK_SEARCH_SIZE, "%s.tags", fileName); + + if (!is_file(tagFileName)) + tagFile = 0; + else { + tagfd = fopen(tagFileName, "rw"); + if (tagfd != NULL) + tagFile = 3; + else + { + tagfd = fopen(tagFileName, "r"); + tagFile = tagfd != NULL ? 2 : 1; + } + } + + if (tagfd != NULL && tagFile > 1) + readTagFile(); +} + +void readTagFile(void) +{ + char raw[BLOCK_SEARCH_SIZE], *line, *token; + + while (fgets(raw, BLOCK_SEARCH_SIZE, tagfd) != NULL) + { + line = (char*)&raw; + int loc = 0; + + token = strsep(&line, " "); + if (strncmp(token, "0x0", BLOCK_SEARCH_SIZE) == 0) + loc = 0; + else + { + loc = (int)strtol(token, NULL, 16); + if ( loc == 0) //Couldn't covert the position, skip the line + continue; + } + + token = strsep(&line, " "); + if ( token == NULL ) //Couldn't find a token skip rest of line + continue; + + // Note n: + if (strncmp(token,"n:",BLOCK_SEARCH_SIZE) == 0) + { + char *note = strsep(&line, "\n"); + if (loc > notes_size) + { + notes_size = loc+NOTE_SIZE; + notes = (noteStruct*) realloc(notes,notes_size*sizeof(noteStruct)); + } + notes[loc].note = (char*) malloc(NOTE_SIZE); + memset(notes[loc].note,'\0',NOTE_SIZE); + snprintf(notes[loc].note,NOTE_SIZE,"%s",note); + } + + // Colour c: 1-CYAN, 2-MAGENTA, 3-YELLOW + if (strncmp(token,"c:",BLOCK_SEARCH_SIZE) == 0) + { + char *restofline; + int end = 0, color = 0; + int col = (int)strtol(line, &restofline, 10); + if (col < 1 || col > 3) //conversion error or out of range + continue; + if (restofline) + end = (int)strtol(restofline, NULL, 10); + + switch (col) { + case 1: color = (int) COLOR_PAIR(5); break; + case 2: color = (int) COLOR_PAIR(6); break; + case 3: color = (int) COLOR_PAIR(7); break; + } + if (end != 0) + for (int i = loc; i < loc+end; i++) + { + int m = bufferAttr[i] & MARKED; + int b = bufferAttr[i] & A_BOLD; + bufferAttr[i] = color; + bufferAttr[i] |= TAGGED; + bufferAttr[i] |= m; + bufferAttr[i] |= b; + } + else + { + int m = bufferAttr[loc] & MARKED; + int b = bufferAttr[loc] & A_BOLD; + bufferAttr[loc] = color; + bufferAttr[loc] |= TAGGED; + bufferAttr[loc] |= m; + bufferAttr[loc] |= b; + } + } + } +} + +void writeTagFile(void) +{ + if (tagFile == 1 || tagFile == 2) return; // tag file not writeable + if (tagFile == 3 || tagFile == 0) // writeable and open + { + displayOneLineMessage("Write tags to file? (y/N)"); + if (tolower(getch()) != 'y') return; + + char tagFileName[BLOCK_SEARCH_SIZE]; + snprintf(tagFileName, BLOCK_SEARCH_SIZE, "%s.tags", fileName); + tagfd = freopen(tagFileName, "w", tagfd); + + int start=0, end=0, col=0, lastcol=0; + for (int i = 0; i < fileSize; i++) + { + if (notes[i].note) fprintf(tagfd, "0x%x n: %s\n", i, notes[i].note); + if (bufferAttr[i] & TAGGED) + { + col = (bufferAttr[i] & COLOR_PAIR(7)) == COLOR_PAIR(7) ? 3 : + (bufferAttr[i] & COLOR_PAIR(6)) == COLOR_PAIR(6) ? 2 : + (bufferAttr[i] & COLOR_PAIR(5)) == COLOR_PAIR(5) ? 1 : 0; + + if ( start != 0 && i == end+1 && col == lastcol ) + end = i; + if ( start != 0 && i == end+1 && col != lastcol ) + { + fprintf(tagfd, "0x%x c: %d %d\n", start, lastcol, 1+end-start); + start = i; + end = i; + } + if ( start == 0 ) + { + start = i; + end = i; + } + lastcol = col; + } + else + { + if ( start != 0 && i == end+1 ) + { + fprintf(tagfd, "0x%x c: %d %d\n", start, lastcol, 1+end-start); + start = 0; + end = 0; + } + } + } + + fclose(tagfd); + } +} diff --git a/hexedit.c b/hexedit.c index addb312..91b599e 100644 --- a/hexedit.c +++ b/hexedit.c @@ -31,7 +31,9 @@ char *progName, *fileName, *baseName; unsigned char *buffer, *copyBuffer; typePage *edited; noteStruct *notes; -size_t notes_size=NOTE_SIZE; +size_t notes_size = NOTE_SIZE; +int tagFile = 0; +FILE *tagfd; char *lastFindFile = NULL, *lastYankToAFile = NULL, *lastAskHexString = NULL, *lastAskAsciiString = NULL, *lastFillWithStringHexa = NULL, *lastFillWithStringAscii = NULL, *lastNote = NULL; @@ -103,6 +105,7 @@ int main(int argc, char **argv) openFile(); } readFile(); + openTagFile(); do display(); while (key_to_function(getch())); quit(); @@ -136,6 +139,7 @@ void quit(void) for (int i=0; i