From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 13 Feb 2007 01:07:36 -0000 Subject: [Cluster-devel] cluster/gfs2/edit gfs2hex.c hexedit.c hexedit.h Message-ID: <20070213010736.16246.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Changes by: rpeterso at sourceware.org 2007-02-13 01:07:35 Modified files: gfs2/edit : gfs2hex.c hexedit.c hexedit.h Log message: Misc improvements. Better scrolling. You can now scroll through the rindex. The superblock now has a pseudo-extended display. Fixed the file offset calculations for indirect pointers. It still has some bugs but it's better than it was. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/gfs2hex.c.diff?cvsroot=cluster&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.c.diff?cvsroot=cluster&r1=1.9&r2=1.10 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.h.diff?cvsroot=cluster&r1=1.7&r2=1.8 --- cluster/gfs2/edit/gfs2hex.c 2007/02/08 05:41:16 1.8 +++ cluster/gfs2/edit/gfs2hex.c 2007/02/13 01:07:35 1.9 @@ -44,7 +44,7 @@ extern char edit_string[1024]; extern int edit_mode INIT(0); extern int edit_row[DMODES], edit_col[DMODES]; -extern int edit_size[DMODES], edit_last[DMODES]; +extern int edit_size[DMODES], last_entry_onscreen[DMODES]; extern char edit_string[1024], edit_fmt[80]; extern enum dsp_mode dmode INIT(HEX_MODE); /* display mode */ @@ -76,6 +76,33 @@ va_end(args); } +void check_highlight(int highlight) +{ + if (!termlines || line >= termlines) /* If printing or out of bounds */ + return; + if (dmode == HEX_MODE) { + if (line == (edit_row[dmode] * lines_per_row[dmode]) + 4) { + if (highlight) { + COLORS_HIGHLIGHT; + last_entry_onscreen[dmode] = print_entry_ndx; + } + else + COLORS_NORMAL; + } + } + else { + if ((line * lines_per_row[dmode]) - 4 == + (edit_row[dmode] - start_row[dmode]) * lines_per_row[dmode]) { + if (highlight) { + COLORS_HIGHLIGHT; + last_entry_onscreen[dmode] = print_entry_ndx; + } + else + COLORS_NORMAL; + } + } +} + void print_it(const char *label, const char *fmt, const char *fmt2, ...) { va_list args; @@ -85,13 +112,10 @@ if (!termlines || line < termlines) { va_start(args, fmt2); + check_highlight(TRUE); if (termlines) { - if (line == edit_row[dmode] + 4) - COLORS_HIGHLIGHT; move(line,0); printw("%s", label); - if (line == edit_row[dmode] + 4) - COLORS_NORMAL; move(line,24); } else { @@ -102,28 +126,21 @@ } vsprintf(tmp_string, fmt, args); - if (termlines) { - if (line == edit_row[dmode] + 4) - COLORS_HIGHLIGHT; + if (termlines) printw(tmp_string); - if (line == edit_row[dmode] + 4) - COLORS_NORMAL; - } else printf(tmp_string); + check_highlight(FALSE); if (fmt2) { decimalsize = strlen(tmp_string); va_end(args); va_start(args, fmt2); vsprintf(tmp_string, fmt2, args); + check_highlight(TRUE); if (termlines) { move(line, 50); - if (line == edit_row[dmode] + 4) - COLORS_HIGHLIGHT; printw("%s", tmp_string); - if (line == edit_row[dmode] + 4) - COLORS_NORMAL; } else { int i; @@ -131,6 +148,7 @@ printf(" "); printf("%s", tmp_string); } + check_highlight(FALSE); } else { if (strstr(fmt,"X") || strstr(fmt,"x")) @@ -148,14 +166,13 @@ } if (termlines) { refresh(); - if (line == edit_row[dmode] + 4) { + if (line == (edit_row[dmode] * lines_per_row[dmode]) + 4) { strcpy(edit_string, tmp_string); strcpy(edit_fmt, fmt); edit_size[dmode] = strlen(edit_string); COLORS_NORMAL; } - if (line - 3 > edit_last[dmode]) - edit_last[dmode] = line - 4; + last_entry_onscreen[dmode] = (line / lines_per_row[dmode]) - 4; } eol(0); va_end(args); @@ -327,7 +344,7 @@ unsigned int x; eol(0); - printf("Directory Entries:"); + print_gfs2("Directory Entries:"); eol(0); for (x = sizeof(struct gfs2_leaf); x < bufsize; x += de.de_rec_len) { @@ -361,7 +378,7 @@ unsigned int x; eol(0); - printf("Eattr Entries:"); + print_gfs2("Eattr Entries:"); eol(0); for (x = sizeof(struct gfs2_meta_header); x < bufsize; x += ea.ea_rec_len) @@ -375,8 +392,10 @@ void gfs2_inum_print2(const char *title,struct gfs2_inum *no) { if (termlines) { + check_highlight(TRUE); move(line,2); printw(title); + check_highlight(FALSE); } else printf(" %s:",title); --- cluster/gfs2/edit/hexedit.c 2007/02/08 05:41:16 1.9 +++ cluster/gfs2/edit/hexedit.c 2007/02/13 01:07:35 1.10 @@ -42,7 +42,7 @@ #include -int display(enum dsp_mode dmode, int identify_only); +int display(int identify_only); extern void eol(int col); extern void do_indirect_extended(char *buf); @@ -70,7 +70,7 @@ else perror("Error: tgetent failed."); termlines--; /* last line is number of lines -1 */ - display(dmode, FALSE); + display(FALSE); signal(SIGWINCH, UpdateSize); } @@ -465,6 +465,7 @@ pointer = (unsigned char *)lpBuffer + offset; ptr2 = (unsigned char *)lpBuffer + offset; l = offset; + print_entry_ndx = 0; while (((termlines && line < termlines && line <= ((screen_chunk_size / 16) + 2)) || @@ -524,10 +525,11 @@ ptr2++; } print_gfs2("] "); - if (line - 3 > edit_last[dmode]) - edit_last[dmode] = line - 3; + if (line - 3 > last_entry_onscreen[dmode]) + last_entry_onscreen[dmode] = line - 3; eol(0); l+=16; + print_entry_ndx++; } /* while */ if (gfs1) { COLORS_NORMAL; @@ -556,24 +558,40 @@ /* ------------------------------------------------------------------------ */ int print_rindex(struct gfs2_inode *di) { - int rgs, error; + int error, start_line; struct gfs2_rindex ri; char buf[sizeof(struct gfs2_rindex)]; + start_line = line; error = 0; print_gfs2("RG index entries found: %d.", di->i_di.di_size / sizeof(struct gfs2_rindex)); eol(0); - for (rgs=0; ; rgs++) { - error = gfs2_readi(di, (void *)&buf, rgs * sizeof(struct gfs2_rindex), + lines_per_row[dmode] = 6; + for (print_entry_ndx=0; ; print_entry_ndx++) { + error = gfs2_readi(di, (void *)&buf, + print_entry_ndx * sizeof(struct gfs2_rindex), sizeof(struct gfs2_rindex)); gfs2_rindex_in(&ri, buf); if (!error) /* end of file */ break; - print_gfs2("RG #%d", rgs + 1); - eol(0); - gfs2_rindex_print(&ri); + if (!termlines || + (print_entry_ndx >= start_row[dmode] && + ((print_entry_ndx - start_row[dmode])+1) * lines_per_row[dmode] <= + termlines - start_line - 2)) { + if (edit_row[dmode] == print_entry_ndx) { + COLORS_HIGHLIGHT; + sprintf(edit_string, "%" PRIx64, ri.ri_addr); + } + print_gfs2("RG #%d", print_entry_ndx); + eol(0); + if (edit_row[dmode] == print_entry_ndx) + COLORS_NORMAL; + gfs2_rindex_print(&ri); + last_entry_onscreen[dmode] = print_entry_ndx; + } } + end_row[dmode] = print_entry_ndx; return error; } @@ -644,213 +662,251 @@ } /* ------------------------------------------------------------------------ */ -/* display_extended */ +/* has_indirect_blocks */ /* ------------------------------------------------------------------------ */ -int display_extended(void) +int has_indirect_blocks(void) { - int e, start_line, total_dirents, indir_blocks; - struct gfs2_inode *tmp_inode; + if (indirect_blocks || gfs2_struct_type == GFS2_METATYPE_SB || + (gfs2_struct_type == GFS2_METATYPE_DI && + (S_ISDIR(di.di_mode) || (gfs1 && di.__pad1 == GFS_FILE_DIR)))) + return TRUE; + return FALSE; +} - edit_last[dmode] = 0; +/* ------------------------------------------------------------------------ */ +/* print_inode_type */ +/* ------------------------------------------------------------------------ */ +void print_inode_type(__be16 de_type) +{ + switch(de_type) { + case DT_UNKNOWN: + print_gfs2("Unknown"); + break; + case DT_REG: + print_gfs2("File "); + break; + case DT_DIR: + print_gfs2("Dir "); + break; + case DT_LNK: + print_gfs2("Symlink"); + break; + case DT_BLK: + print_gfs2("BlkDev "); + break; + case DT_CHR: + print_gfs2("ChrDev "); + break; + case DT_FIFO: + print_gfs2("Fifo "); + break; + case DT_SOCK: + print_gfs2("Socket "); + break; + default: + print_gfs2("%04x ", de_type); + break; + } +} + +/* ------------------------------------------------------------------------ */ +/* display_indirect */ +/* ------------------------------------------------------------------------ */ +int display_indirect(void) +{ + int start_line, total_dirents, indir_blocks; + int i, cur_height = -1; + uint64_t factor[5]; + int offsets[5]; + + last_entry_onscreen[dmode] = 0; eol(0); start_line = line; - if (indirect_blocks || - (gfs2_struct_type == GFS2_METATYPE_DI && - (S_ISDIR(di.di_mode) || (gfs1 && di.__pad1 == GFS_FILE_DIR)))) { - int i, cur_height = -1; - uint64_t factor[5]; - int offsets[5]; + if (!has_indirect_blocks()) + return -01; - indir_blocks = indirect_blocks; - if (!indirect_blocks) { + indir_blocks = indirect_blocks; + if (!indirect_blocks) { + if (gfs2_struct_type == GFS2_METATYPE_SB) + print_gfs2("The superblock has 2 directories"); + else print_gfs2("This directory contains %d directory entries.", indirect[0].dirents); - indir_blocks = 1; /* not really an indirect block, but treat it as one */ - } - else { - if (gfs2_struct_type == GFS2_METATYPE_DI) { - if (S_ISDIR(di.di_mode)) - print_gfs2("This directory contains %d indirect blocks", - indirect_blocks); - else - print_gfs2("This inode contains %d indirect blocks", - indirect_blocks); - } + indir_blocks = 1; /* not really an indirect block, but treat it as one */ + } + else { + if (gfs2_struct_type == GFS2_METATYPE_DI) { + if (S_ISDIR(di.di_mode)) + print_gfs2("This directory contains %d indirect blocks", + indirect_blocks); else - print_gfs2("This indirect block contains %d indirect blocks", + print_gfs2("This inode contains %d indirect blocks", indirect_blocks); } - total_dirents = 0; - /* Figure out multiplication factors for indirect pointers. */ - if ((indir_blocks == indirect_blocks) && !S_ISDIR(di.di_mode)) { - memset(&offsets, 0, sizeof(offsets)); - /* See if we are on an inode or have one in history. */ + else + print_gfs2("This indirect block contains %d indirect blocks", + indirect_blocks); + } + total_dirents = 0; + /* Figure out multiplication factors for indirect pointers. */ + if ((indir_blocks == indirect_blocks) && !S_ISDIR(di.di_mode)) { + memset(&offsets, 0, sizeof(offsets)); + /* See if we are on an inode or have one in history. */ + cur_height = 0; + if (gfs2_struct_type != GFS2_METATYPE_DI) { cur_height = 0; - if (gfs2_struct_type != GFS2_METATYPE_DI) { - cur_height = 0; - for (i = 0; i <= blockhist && i < 5; i++) { - offsets[i] = blockstack[(blockhist - i) % BLOCK_STACK_SIZE].edit_row[dmode]; - if (blockstack[(blockhist - i) % BLOCK_STACK_SIZE].gfs2_struct_type == GFS2_METATYPE_DI) - break; - cur_height++; - } - } - if (cur_height >= 0) { - /* Multiply out the max factor based on inode height.*/ - /* This is how much data is represented by each */ - /* indirect pointer at each height. */ - factor[0] = 1ull; - for (i = 0; i < di.di_height; i++) - factor[i + 1] = factor[i] * 509; - } - print_gfs2(" (at height=%d)", cur_height); - } - if (indirect_blocks) { - eol(0); - print_gfs2("Indirect blocks for this inode:"); + for (i = 0; i <= blockhist && i < 5; i++) { + offsets[i] = blockstack[(blockhist - i) % BLOCK_STACK_SIZE].edit_row[dmode]; + if (blockstack[(blockhist - i) % BLOCK_STACK_SIZE].gfs2_struct_type == GFS2_METATYPE_DI) + break; + cur_height++; + } + } + if (cur_height >= 0) { + /* Multiply out the max factor based on inode height.*/ + /* This is how much data is represented by each */ + /* indirect pointer at each height. */ + factor[0] = 1ull; + for (i = 0; i < di.di_height; i++) + factor[i + 1] = factor[i] * (gfs1 ? 501 : 509); } + print_gfs2(" (at height=%d)", cur_height); + } + if (indirect_blocks) { eol(0); - for (e = start_row[dmode]; - (!termlines || - e < termlines - start_line - 2 + start_row[dmode]) && - e < indir_blocks; e++) { + print_gfs2("Indirect blocks:"); + } + eol(0); + for (print_entry_ndx = start_row[dmode]; + (!termlines || print_entry_ndx < termlines - start_line - 2 + + start_row[dmode]) && print_entry_ndx < indir_blocks; + print_entry_ndx++) { + if (termlines) { + if (edit_row[dmode] >= 0 && + line - start_line - 2 == edit_row[dmode] - + start_row[dmode]) + COLORS_HIGHLIGHT; + move(line, 1); + } + if (indir_blocks == indirect_blocks) { + print_gfs2("%d => ", print_entry_ndx); + if (termlines) + move(line,9); + print_gfs2("0x%llx / %lld", indirect[print_entry_ndx].block, + indirect[print_entry_ndx].block); if (termlines) { if (edit_row[dmode] >= 0 && line - start_line - 2 == edit_row[dmode] - - start_row[dmode]) - COLORS_HIGHLIGHT; - move(line, 1); - } - if (indir_blocks == indirect_blocks) { - print_gfs2("%d => ", e); - if (termlines) - move(line,9); - print_gfs2("0x%llx / %lld", indirect[e].block, - indirect[e].block); + start_row[dmode]) { + sprintf(edit_string, "%"PRIx64, + indirect[print_entry_ndx].block); + strcpy(edit_fmt, "%"PRIx64); + edit_size[dmode] = strlen(edit_string); + COLORS_NORMAL; + } + } + if (!S_ISDIR(di.di_mode)) { + int hgt; + uint64_t file_offset = 0ull; + float human_off; + char h; + + /* Now divide by how deep we are at the moment. */ + /* This is how much data is represented by each */ + /* indirect pointer for each height we've traversed. */ + offsets[0] = print_entry_ndx; + for (hgt = cur_height; hgt >= 0; hgt--) + file_offset += offsets[cur_height - hgt] * + factor[di.di_height - hgt - 1] * bufsize; + print_gfs2(" "); + h = 'K'; + human_off = (file_offset / 1024.0); + if (human_off > 1024.0) { h = 'M'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'G'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'T'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'P'; human_off /= 1024.0; } + if (human_off > 1024.0) { h = 'E'; human_off /= 1024.0; } + print_gfs2("(data offset 0x%llx / %lld / %6.2f%c)", + file_offset, file_offset, human_off, h); + print_gfs2(" "); + } + } + if (indirect[print_entry_ndx].is_dir) { + int d; + + if (indirect[print_entry_ndx].dirents > 1 && + indir_blocks == indirect_blocks) + print_gfs2("(directory leaf with %d entries)", + indirect[print_entry_ndx].dirents); + for (d = 0; d < indirect[print_entry_ndx].dirents; d++) { + total_dirents++; + if (indirect[print_entry_ndx].dirents > 1) { + eol(5); + if (termlines) { + if (edit_row[dmode] >=0 && + line - start_line - 2 == + edit_row[dmode] - + start_row[dmode]) { + COLORS_HIGHLIGHT; + sprintf(edit_string, "%"PRIx64, + indirect[print_entry_ndx].dirent[d].block); + strcpy(edit_fmt, "%"PRIx64); + } + } + print_gfs2("%d. (%d). %lld (0x%llx) / %lld (0x%llx): ", + total_dirents, d + 1, + indirect[print_entry_ndx].dirent[d].dirent.de_inum.no_formal_ino, + indirect[print_entry_ndx].dirent[d].dirent.de_inum.no_formal_ino, + indirect[print_entry_ndx].dirent[d].block, + indirect[print_entry_ndx].dirent[d].block); + } + print_inode_type(indirect[print_entry_ndx].dirent[d].dirent.de_type); + print_gfs2(" %s", indirect[print_entry_ndx].dirent[d].filename); if (termlines) { if (edit_row[dmode] >= 0 && line - start_line - 2 == edit_row[dmode] - - start_row[dmode]) { - sprintf(edit_string, "%"PRIx64, indirect[e].block); - strcpy(edit_fmt, "%"PRIx64); - edit_size[dmode] = strlen(edit_string); + start_row[dmode]) COLORS_NORMAL; - } - } - if (!S_ISDIR(di.di_mode)) { - int hgt; - uint64_t file_offset = 0ull; - - /* Now divide by how deep we are at the moment. */ - /* This is how much data is represented by each */ - /* indirect pointer for each height we've traversed. */ - offsets[0] = e; - for (hgt = cur_height; hgt >= 0; hgt--) - file_offset += offsets[cur_height - hgt] * - factor[di.di_height - hgt - 1] * - (bufsize - sizeof(struct gfs2_meta_header)); - print_gfs2(" "); - print_gfs2("(data offset 0x%llx / %lld)", file_offset, - file_offset); - print_gfs2(" "); - } - } - if (indirect[e].is_dir) { - int d; - - if (indirect[e].dirents > 1 && indir_blocks == indirect_blocks) - print_gfs2("(directory leaf with %d entries)", - indirect[e].dirents); - for (d = 0; d < indirect[e].dirents; d++) { - total_dirents++; - if (indirect[e].dirents > 1) { - eol(5); - if (termlines) { - if (edit_row[dmode] >=0 && - line - start_line - 2 == - edit_row[dmode] - - start_row[dmode]) { - COLORS_HIGHLIGHT; - sprintf(edit_string, "%"PRIx64, - indirect[e].dirent[d].block); - strcpy(edit_fmt, "%"PRIx64); - } - } - print_gfs2("%d. (%d). %lld (0x%llx) / %lld (0x%llx): ", - total_dirents, d + 1, - indirect[e].dirent[d].dirent.de_inum.no_formal_ino, - indirect[e].dirent[d].dirent.de_inum.no_formal_ino, - indirect[e].dirent[d].block, - indirect[e].dirent[d].block); - } - switch(indirect[e].dirent[d].dirent.de_type) { - case DT_UNKNOWN: - print_gfs2("Unknown"); - break; - case DT_REG: - print_gfs2("File "); - break; - case DT_DIR: - print_gfs2("Dir "); - break; - case DT_LNK: - print_gfs2("Symlink"); - break; - case DT_BLK: - print_gfs2("BlkDev "); - break; - case DT_CHR: - print_gfs2("ChrDev "); - break; - case DT_FIFO: - print_gfs2("Fifo "); - break; - case DT_SOCK: - print_gfs2("Socket "); - break; - default: - print_gfs2("%04x ", - indirect[e].dirent[d].dirent.de_type); - break; - } - - print_gfs2(" %s", indirect[e].dirent[d].filename); - if (termlines) { - if (edit_row[dmode] >= 0 && - line - start_line - 2 == edit_row[dmode] - - start_row[dmode]) - COLORS_NORMAL; - } } - } /* if isdir */ - eol(0); - } /* for termlines */ - if (line >= 7) /* 7 because it was bumped at the end */ - edit_last[dmode] = line - 7; - } /* if (indirect_blocks) */ - else - print_gfs2("This block does not have indirect blocks."); + } + } /* if isdir */ + eol(0); + } /* for each display row */ + if (line >= 7) /* 7 because it was bumped at the end */ + last_entry_onscreen[dmode] = line - 7; eol(0); + end_row[dmode] = (indirect_blocks ? indirect_blocks:indirect[0].dirents); + if (end_row[dmode] < last_entry_onscreen[dmode]) + end_row[dmode] = last_entry_onscreen[dmode]; + lines_per_row[dmode] = 1; + return 0; +} + +/* ------------------------------------------------------------------------ */ +/* display_extended */ +/* ------------------------------------------------------------------------ */ +int display_extended(void) +{ + struct gfs2_inode *tmp_inode; + struct gfs2_buffer_head *tmp_bh; + + /* Display any indirect pointers that we have. */ + if (display_indirect() < 0) + return -1; if ((gfs1 && block == sbd1->sb_rindex_di.no_addr) || (block == masterblock("rindex"))) { - struct gfs2_buffer_head *tmp_bh; - tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_rindex(tmp_inode); brelse(tmp_bh, not_updated); } else if (!gfs1 && block == masterblock("inum")) { - struct gfs2_buffer_head *tmp_bh; - tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_inum(tmp_inode); brelse(tmp_bh, not_updated); } else if (!gfs1 && block == masterblock("statfs")) { - struct gfs2_buffer_head *tmp_bh; - tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_statfs(tmp_inode); @@ -858,8 +914,6 @@ } else if ((gfs1 && block == gfs1_quota_di.no_addr) || (block == masterblock("quota"))) { - struct gfs2_buffer_head *tmp_bh; - tmp_bh = bread(&sbd, block); tmp_inode = inode_get(&sbd, tmp_bh); print_quota(tmp_inode); @@ -925,7 +979,7 @@ /* ------------------------------------------------------------------------ */ /* display */ /* ------------------------------------------------------------------------ */ -int display(enum dsp_mode dmode, int identify_only) +int display(int identify_only) { if (termlines) { display_title_lines(); @@ -943,8 +997,30 @@ if (identify_only) return 0; indirect_blocks = 0; - if (gfs2_struct_type == GFS2_METATYPE_SB || block == 0x10) + lines_per_row[dmode] = 1; + if (gfs2_struct_type == GFS2_METATYPE_SB || block == 0x10) { gfs2_sb_in(&sbd.sd_sb, buf); /* parse it out into the sb structure */ + memset(&indirect, 0, sizeof(indirect)); + indirect[0].block = sbd.sd_sb.sb_master_dir.no_addr; + indirect[0].is_dir = TRUE; + indirect[0].dirents = 2; + + memcpy(&indirect[0].dirent[0].filename, "root", 4); + indirect[0].dirent[0].dirent.de_inum.no_formal_ino = + sbd.sd_sb.sb_root_dir.no_formal_ino; + indirect[0].dirent[0].dirent.de_inum.no_addr = + sbd.sd_sb.sb_root_dir.no_addr; + indirect[0].dirent[0].block = sbd.sd_sb.sb_root_dir.no_addr; + indirect[0].dirent[0].dirent.de_type = DT_DIR; + + memcpy(&indirect[0].dirent[1].filename, "master", 7); + indirect[0].dirent[1].dirent.de_inum.no_formal_ino = + sbd.sd_sb.sb_master_dir.no_formal_ino; + indirect[0].dirent[1].dirent.de_inum.no_addr = + sbd.sd_sb.sb_master_dir.no_addr; + indirect[0].dirent[1].block = sbd.sd_sb.sb_master_dir.no_addr; + indirect[0].dirent[1].dirent.de_type = DT_DIR; + } else if (gfs2_struct_type == GFS2_METATYPE_DI) { gfs2_dinode_in(&di, buf); /* parse disk inode into structure */ do_dinode_extended(&di, buf); /* get extended data, if any */ @@ -973,14 +1049,22 @@ } } } - edit_last[dmode] = 0; + last_entry_onscreen[dmode] = 0; + if (dmode == EXTENDED_MODE && !has_indirect_blocks()) + dmode = HEX_MODE; + if (termlines) { + move(termlines, 63); + printw("Mode: %s", (dmode==HEX_MODE?"Hex edit ":(dmode==GFS2_MODE?"Structure":"Pointers "))); + move(line, 0); + } if (dmode == HEX_MODE) /* if hex display mode */ hexdump(dev_offset, buf, (gfs2_struct_type == GFS2_METATYPE_DI)? struct_len + di.di_size:bufsize); /* show block in hex */ else if (dmode == GFS2_MODE) /* if structure display */ display_gfs2(); /* display the gfs2 structure */ - else /* otherwise */ + else display_extended(); /* display extended blocks */ + /* No else here, because display_extended can switch back to hex mode */ if (termlines) refresh(); return(0); @@ -998,8 +1082,10 @@ blockstack[bhst].dmode = dmode; for (i = 0; i < DMODES; i++) { blockstack[bhst].start_row[i] = start_row[i]; + blockstack[bhst].end_row[i] = end_row[i]; blockstack[bhst].edit_row[i] = edit_row[i]; blockstack[bhst].edit_col[i] = edit_col[i]; + blockstack[bhst].lines_per_row[i] = lines_per_row[i]; } blockstack[bhst].gfs2_struct_type = gfs2_struct_type; blockhist++; @@ -1021,8 +1107,10 @@ dmode = blockstack[bhst].dmode; for (i = 0; i < DMODES; i++) { start_row[i] = blockstack[bhst].start_row[i]; + end_row[i] = blockstack[bhst].end_row[i]; edit_row[i] = blockstack[bhst].edit_row[i]; edit_col[i] = blockstack[bhst].edit_col[i]; + lines_per_row[i] = blockstack[bhst].lines_per_row[i]; } gfs2_struct_type = blockstack[bhst].gfs2_struct_type; return blockstack[bhst].block; @@ -1093,7 +1181,7 @@ init_pair(COLOR_NORMAL, COLOR_BLACK, COLOR_WHITE); /* normal text */ init_pair(COLOR_INVERSE, COLOR_WHITE, COLOR_BLACK); /* inverse text */ init_pair(COLOR_SPECIAL, COLOR_RED, COLOR_WHITE); /* special text */ - init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_WHITE); /* highlighted */ + init_pair(COLOR_HIGHLIGHT, COLOR_MAGENTA, COLOR_WHITE); /* highlighted */ init_pair(COLOR_OFFSETS, COLOR_CYAN, COLOR_WHITE); /* offsets */ init_pair(COLOR_CONTENTS, COLOR_BLUE, COLOR_WHITE); /* file data */ } @@ -1127,7 +1215,7 @@ /* Accept keystrokes and act on them accordingly */ Quit = FALSE; while (!Quit) { - display(dmode, FALSE); + display(FALSE); while ((ch=getch()) == 0); // wait for input switch (ch) { @@ -1144,7 +1232,7 @@ /* -------------------------------------------------------------- */ case KEY_HOME: if (dmode == EXTENDED_MODE) { - start_row[dmode] = 0; + start_row[dmode] = end_row[dmode] = 0; edit_row[dmode] = 0; } else { @@ -1189,16 +1277,14 @@ /* -------------------------------------------------------------- */ case KEY_DOWN: if (dmode == EXTENDED_MODE) { - if (edit_row[dmode] + 1 < - (indirect_blocks ? indirect_blocks:indirect[0].dirents)) { - if (edit_row[dmode] >= edit_last[dmode] + - start_row[dmode]) + if (edit_row[dmode] + 1 < end_row[dmode]) { + if (edit_row[dmode] >= last_entry_onscreen[dmode]) start_row[dmode]++; edit_row[dmode]++; } } else { - if (edit_row[dmode] < edit_last[dmode]) + if (edit_row[dmode] < last_entry_onscreen[dmode]) edit_row[dmode]++; } break; @@ -1251,7 +1337,7 @@ block = temp_blk; push_block(block); for (i = 0; i < DMODES; i++) { - start_row[i] = edit_row[i] = 0; + start_row[i] = end_row[i] = edit_row[i] = 0; edit_col[i] = 0; } } @@ -1269,10 +1355,16 @@ print_usage(); break; /* -------------------------------------------------------------- */ + /* e - change to extended mode */ + /* -------------------------------------------------------------- */ + case 'e': + dmode = EXTENDED_MODE; + break; + /* -------------------------------------------------------------- */ /* b - Back one 4K block */ /* -------------------------------------------------------------- */ case 'b': - start_row[dmode] = edit_row[dmode] = 0; + start_row[dmode] = end_row[dmode] = edit_row[dmode] = 0; if (block > 0) block--; offset = 0; @@ -1294,9 +1386,9 @@ if (dmode == EXTENDED_MODE) { int lines_of_display = termlines - 6; - if (edit_row[dmode] - lines_of_display > 0) { - start_row[dmode] -= lines_of_display; - edit_row[dmode] -= lines_of_display; + if (edit_row[dmode] - (lines_of_display / lines_per_row[dmode]) > 0) { + start_row[dmode] -= (lines_of_display / lines_per_row[dmode]); + edit_row[dmode] -= (lines_of_display / lines_per_row[dmode]); } else { start_row[dmode] = 0; @@ -1323,9 +1415,20 @@ /* -------------------------------------------------------------- */ case 0x168: if (dmode == EXTENDED_MODE) { - edit_row[dmode] = - (indirect_blocks? indirect_blocks - 1:indirect[0].dirents - 1); - start_row[dmode] = edit_row[dmode] - (termlines - 7); + int lines_of_display = termlines - 6; + int entries_per_screen = lines_of_display / + lines_per_row[dmode]; + + edit_row[dmode] = end_row[dmode] - 1; + if ((edit_row[dmode] - entries_per_screen) + 1 > 0) + start_row[dmode] = edit_row[dmode] - entries_per_screen + 1; + /* + if (edit_row[dmode] * lines_per_row[dmode] > (termlines - 7)) + start_row[dmode] = (edit_row[dmode] - (termlines - 7)) / + lines_per_row[dmode]; + */ + else + start_row[dmode] = 0; } /* TODO: Make "end" key work for other display modes. */ break; @@ -1333,7 +1436,8 @@ /* f - Forward one 4K block */ /* -------------------------------------------------------------- */ case 'f': - start_row[dmode] = edit_row[dmode] = 0; + start_row[dmode] = end_row[dmode] = edit_row[dmode] = 0; + lines_per_row[dmode] = 1; block++; offset = 0; break; @@ -1346,15 +1450,12 @@ if (dmode == EXTENDED_MODE) { int lines_of_display = termlines - 6; - if (edit_row[dmode] + lines_of_display + 1 < - (indirect_blocks ? indirect_blocks:indirect[0].dirents)) { - start_row[dmode] += lines_of_display; - edit_row[dmode] += lines_of_display; - } - else { - edit_row[dmode] = - (indirect_blocks ? indirect_blocks - 1:indirect[0].dirents - 1); + if ((edit_row[dmode] + lines_of_display) / lines_per_row[dmode] + 1 < end_row[dmode]) { + start_row[dmode] += lines_of_display / lines_per_row[dmode]; + edit_row[dmode] += lines_of_display / lines_per_row[dmode]; } + else + edit_row[dmode] = end_row[dmode] - 1; } else { start_row[dmode] = edit_row[dmode] = 0; @@ -1594,10 +1695,12 @@ prog_name = argv[0]; memset(start_row, 0, sizeof(start_row)); + memset(lines_per_row, 0, sizeof(lines_per_row)); + memset(end_row, 0, sizeof(end_row)); memset(edit_row, 0, sizeof(edit_row)); memset(edit_col, 0, sizeof(edit_col)); memset(edit_size, 0, sizeof(edit_size)); - memset(edit_last, 0, sizeof(edit_last)); + memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen)); dmode = HEX_MODE; type_alloc(buf, char, bufsize); /* allocate/malloc a new 4K buffer */ block = 0x10; @@ -1606,8 +1709,10 @@ blockstack[i].block = block; for (j = 0; j < DMODES; j++) { blockstack[i].start_row[j] = 0; + blockstack[i].end_row[j] = 0; blockstack[i].edit_row[j] = 0; blockstack[i].edit_col[j] = 0; + blockstack[i].lines_per_row[j] = 0; } } @@ -1632,7 +1737,7 @@ else { /* print all the structures requested */ for (i = 0; i <= blockhist; i++) { block = blockstack[i + 1].block; - display(dmode, identify); + display(identify); if (!identify) { display_extended(); printf("-------------------------------------" \ --- cluster/gfs2/edit/hexedit.h 2007/02/08 05:41:16 1.7 +++ cluster/gfs2/edit/hexedit.h 2007/02/13 01:07:35 1.8 @@ -76,9 +76,9 @@ EXTERN int line INIT(1); EXTERN int struct_len INIT(0); EXTERN unsigned int offset; -EXTERN int edit_row[DMODES], edit_col[DMODES]; -EXTERN int start_row[DMODES]; -EXTERN int edit_size[DMODES], edit_last[DMODES]; +EXTERN int edit_row[DMODES], edit_col[DMODES], print_entry_ndx; +EXTERN int start_row[DMODES], end_row[DMODES], lines_per_row[DMODES]; +EXTERN int edit_size[DMODES], last_entry_onscreen[DMODES]; EXTERN char edit_string[1024], edit_fmt[80]; EXTERN struct gfs2_sbd sbd; EXTERN struct gfs_sb *sbd1; @@ -116,6 +116,8 @@ struct blkstack_info { uint64_t block; int start_row[DMODES]; + int end_row[DMODES]; + int lines_per_row[DMODES]; int edit_row[DMODES]; int edit_col[DMODES]; enum dsp_mode dmode;