📄 heme.c
字号:
beg_offset = 0; cur_offset = 0; cur_line = 0; } else cur_offset -= bpl * max_lines; for(i = 0; i < max_lines; i++) put_line(i, beg_offset + i * bpl); hilite(); break; case 'w': case 'W': /* search for string * FIXME: needs testing; improve speed(use memcmp() on blocks directly?) */ { const char *p; p = ask_user_string("Enter string to search for: "); if(*p == '\0') break; if(last_string_search) free(last_string_search); last_string_search = xstrdup(p); last_search = 1; string_search(p); } break; case 'n': case 'N': /* search for byte */ { byte b; ret = ask_user_byte("Enter byte to search for: ", &b); if(ret == -1) { print_message("Wrong byte value (must be in [0, 255])."); sleep(1); break; } last_search = 0; last_byte_search = b; byte_search(b); } break; case 'r': case 'R': /* repeat last search */ if(last_search == 0) byte_search(last_byte_search); else if(last_search == 1) string_search(last_string_search); break; case 'l': case 'L': /* fill range with byte */ { off_t of1, of2, of; byte fill_byte; ret = ask_user_offset("Enter start offset: ", &of1); if(ret == -1) { print_message("Invalid starting offset!"); sleep(1); break; } else if(of1 >= file_size) { print_message("Starting offset is beyond the end of file!"); sleep(1); break; } ret = ask_user_offset("Enter end offset: ", &of2); if(ret == -1) { print_message("Invalid end offset!"); sleep(1); break; } else if(of2 >= file_size) { print_message("End offset is beyond the end of file!"); sleep(1); break; } else if(of2 <= of1) { print_message("End offset is less than or equal to starting offset!"); sleep(1); break; } ret = ask_user_byte("Fill with byte: ", &fill_byte); if(ret == -1) { print_message("Wrong byte value (must be in [0, 255])."); sleep(1); break; } save_undo_fill_info(of1, of2); for(of = of1; of <= of2; of++) put_byte(of, fill_byte); /* refresh lines in view that have been changed */ of = of1; unhilite(); while(of >= beg_offset && of < beg_offset + bpl * max_lines) { put_line((of - beg_offset) / bpl, beg_offset + bpl * ((of - beg_offset) / bpl)); of += bpl; } hilite(); } break; case 'j': case 'J': /* jump to offset */ /* the offset can be given in hex(0xab, 0xAB), dec(171) or octal(0...) */ ret = ask_user_offset("Enter offset (e.g. 0x1a, 27, 033): ", &tmp_offset); if(ret == -1) { print_message("Invalid offset!"); sleep(1); break; } if(tmp_offset >= file_size) { print_message("Offset is beyond the end of file!"); sleep(1); break; } unhilite(); cur_offset = tmp_offset; if(cur_offset > end_offset) beg_offset = end_offset; else { for(beg_offset = cur_offset; beg_offset % (bpl * max_lines) != 0; beg_offset--) ; } for(i = 0; i < max_lines; i++) put_line(i, beg_offset + i * bpl); cur_line = (cur_offset - beg_offset) / bpl; hilite(); break; case '<': /* move to the begging of the current line */ if(cur_offset % bpl != 0) { unhilite(); while(--cur_offset % bpl) ; hilite(); } break; case '>': /* move to the end of the current line */ if((cur_offset + 1) % bpl != 0) { unhilite(); while(++cur_offset % bpl != 0 && cur_offset < file_size) ; cur_offset--; hilite(); } break; case 's': case 'S': /* save file */ /* if(uando_count > 0) */ if(!file_saved) { do ret = get_user_input("Are you sure you want to save (y/n)?"); while(ret != 'y' && ret != 'n'); if(ret == 'y') save_file(0); break; } break; case 'q': case 'Q': /* quit */ if(!file_saved) { /* ask the user to save file */ do ret = get_user_input("File was modified. Save (y/n/c)?"); while(ret != 'y' && ret != 'n' && ret != 'c'); if(ret == 'y') save_file(1); if(ret != 'c') running = 0; } else running = 0; break; case 'u': case 'U': do_undo(); break; case 'h': case 'H': show_helpwin(); break; default: ch = tolower(ch); if(isxdigit(ch)) { set_byte_part(ch); if(advance_after_edit) { advance_right(); } } break; } if(isxdigit(ch)) lastch = ch; else lastch = EOF; } while(running); scrollok(stdscr,FALSE); refresh(); delwin(w_main); delwin(w_offset); delwin(w_ascii); putchar('\n');}static void advance_right(){ if(cur_offset == file_size - 1 && (current_nibble == 1 || mode_ascii)) return; unhilite(); if(mode_ascii || current_nibble == 1) { cur_offset++; current_nibble=0; } else { current_nibble++; } if(cur_line == max_lines - 1 && (cur_offset) % bpl == 0 && current_nibble == 0) { /* move down one line */ scroll(w_offset); scroll(w_main); scroll(w_ascii); beg_offset += bpl; put_line(max_lines - 1, cur_offset); } if(cur_offset % bpl == 0 && current_nibble == 0 && cur_line < max_lines - 1) cur_line++; hilite();}static void init_blocksize(){#ifdef HAVE_MMAP# if defined(PAGESIZE) off_len = PAGESIZE;# elif defined(_PAGESIZE) off_len = _PAGESIZE;# else if((off_len = sysconf(_SC_PAGESIZE)) <= 1 && (off_len = sysconf(_SC_PAGE_SIZE)) <= 1) off_len = 4096;# endif off_len <<= 1;#else /* * we don't have mmap() so off_len is set in open_file() to * st.st_blksize */#endif}static void my_signal_handler(int sig){ /* don't save anything */ scrollok(stdscr, FALSE); refresh(); endwin(); pconfig_quit(); fprintf(stderr, "\n%s: received signal %d, exiting.\n", prog_name, sig); exit(sig);}static int str_to_color(const char *str){ if(strcmp(str, "black") == 0) return COLOR_BLACK; else if(strcmp(str, "red") == 0) return COLOR_RED; else if(strcmp(str, "green") == 0) return COLOR_GREEN; else if(strcmp(str, "yellow") == 0) return COLOR_YELLOW; else if(strcmp(str, "blue") == 0) return COLOR_BLUE; else if(strcmp(str, "magenta") == 0) return COLOR_MAGENTA; else if(strcmp(str, "cyan") == 0) return COLOR_CYAN; else if(strcmp(str, "white") == 0) return COLOR_WHITE; /* this should never happen */ return COLOR_BLACK;}/* init curses, set up colors ... */static void setup_curses(){ int fg_color, bg_color; initscr(); keypad(stdscr, TRUE); noecho(); cbreak(); if(use_colors) { use_colors = 1; /* because of unhilite() */ if(start_color() == ERR) { /* disable colors */ use_colors = 0; return; } bg_color = str_to_color(pconfig_get_string("bg_color")); fg_color = str_to_color(pconfig_get_string("fg_color")); init_pair(1, fg_color, bg_color); /* default */ bg_color = str_to_color(pconfig_get_string("bg_color_selected")); fg_color = str_to_color(pconfig_get_string("fg_color_selected")); init_pair(2, fg_color, bg_color); /* selected byte */ bg_color = str_to_color(pconfig_get_string("bg_color_status")); fg_color = str_to_color(pconfig_get_string("fg_color_status")); init_pair(3, fg_color, bg_color); /* status colors */ }}/* * supported options and their defaults * note: if the config file isn't present, * defaults will be used */static pconfig_option_t opts[] = { { PCONFIG_INT, "advance_after_edit", "1" }, { PCONFIG_INT, "make_backup_files", "1" }, { PCONFIG_INT, "use_colors", "1" }, { PCONFIG_STRING, "bg_color", "blue" }, { PCONFIG_STRING, "fg_color", "white" }, { PCONFIG_STRING, "bg_color_selected", "black" }, { PCONFIG_STRING, "fg_color_selected", "green" }, { PCONFIG_STRING, "bg_color_status", "cyan" }, { PCONFIG_STRING, "fg_color_status", "black" }, { 0, NULL, NULL }};static void read_config(){ struct passwd *pw; char cfg_file[1024]; if(config_file == NULL) { /* use default config file */ pw = getpwuid(getuid()); if(pw == NULL) return; sprintf(cfg_file, "%s/.hemerc", pw->pw_dir); config_file = cfg_file; } if(pconfig_init(0, opts) < 0) { fprintf(stderr, "%s: pconfig_init() failed\n", prog_name); exit(1); } pconfig_parse(config_file); /* error return? */ if(use_colors == -1) use_colors = pconfig_get_int("use_colors"); if(make_backup_files == -1) make_backup_files = pconfig_get_int("make_backup_files"); if(advance_after_edit == -1) advance_after_edit = pconfig_get_int("advance_after_edit");}static void print_usage(){ printf("Usage: %s [options] FILE\nAvailable options:\n", prog_name); puts(" -n, --no-backup-files \tdon't make backup files"); puts(" -c, --config-file CONFIGFILE \tread configuration from CONFIGFILE"); puts(" -d, --disable-colors \t\tdon't use colors"); puts(" -h, --help \t\thelp"); puts(" -v, --version \t\tversion"); puts("\nReport bugs to <pokemon@fly.srk.fer.hr>.");}static void save_prog_name(const char *str){ const char *p, *r; r = str + strlen(str); p = r; while(p >= str && *p != '/') p--; if(p < r) { prog_name = xmalloc(r - p); strcpy(prog_name, p + 1); } else prog_name = xstrdup("heme");}int main(int argc, char *argv[]){ int c; save_prog_name(argv[0]); /* set up the signal handler */ signal(SIGINT, my_signal_handler); signal(SIGTERM, my_signal_handler); while((c = pgetopt(argc, argv, " -n --no-backup-files -c: --config-file: " "-d --disable-colors -h --help -v --version")) != -1) { switch(c) { case 0: case 1: make_backup_files = 0; break; case 2: case 3: config_file = poptarg; break; case 4: case 5: use_colors = 0; break; case 6: case 7: print_usage(); return 0; break; case 8: case 9: printf("heme %s\n", heme_version); return 0; break; } } if(argv[poptindex] == 0) { printf("%s: missing file argument\n", prog_name); return 0; } read_config(); init_blocksize(); open_file(argv[poptindex]); setup_curses(); main_loop(); close(fd); pconfig_quit(); endwin(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -