From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 10 Jul 2006 23:30:57 -0000 Subject: [Cluster-devel] cluster/gfs/gfs_edit Makefile gfshex.c gfshex. ... Message-ID: <20060710233057.26118.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 2006-07-10 23:30:56 Modified files: gfs/gfs_edit : Makefile gfshex.c gfshex.h hexedit.c hexedit.h ondisk.c Log message: New ncurses-based gfs_edit synced from RHEL4 and STABLE branches. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_edit/Makefile.diff?cvsroot=cluster&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_edit/gfshex.c.diff?cvsroot=cluster&r1=1.2&r2=1.3 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_edit/gfshex.h.diff?cvsroot=cluster&r1=1.1&r2=1.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_edit/hexedit.c.diff?cvsroot=cluster&r1=1.1&r2=1.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_edit/hexedit.h.diff?cvsroot=cluster&r1=1.1&r2=1.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs/gfs_edit/ondisk.c.diff?cvsroot=cluster&r1=1.2&r2=1.3 --- cluster/gfs/gfs_edit/Makefile 2005/05/19 19:51:06 1.4 +++ cluster/gfs/gfs_edit/Makefile 2006/07/10 23:30:56 1.5 @@ -15,8 +15,7 @@ SOURCE= \ gfshex.c \ - hexedit.c \ - ondisk.c + hexedit.c top_srcdir=.. include ${top_srcdir}/make/defines.mk @@ -31,15 +30,15 @@ # should be installed INCLUDE += $(shell if [ -e ${KERNEL_SRC}/include/linux/gfs_ondisk.h ]; then \ echo '-I${KERNEL_SRC}/include'; else \ - echo '-I${incdir}'; fi) + echo '-I${gfskincdir}'; fi) else -INCLUDE += -I${incdir} +INCLUDE += -I${gfskincdir} endif all: gfs_edit gfs_edit: ${SOURCE} - ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -o $@ + ${CC} ${CFLAGS} ${INCLUDE} ${LDFLAGS} ${SOURCE} ${LOADLIBES} ${LDLIBS} -lncurses -o $@ copytobin: all cp ${TARGET} ${top_srcdir}/bin --- cluster/gfs/gfs_edit/gfshex.c 2004/10/05 19:44:56 1.2 +++ cluster/gfs/gfs_edit/gfshex.c 2006/07/10 23:30:56 1.3 @@ -19,17 +19,21 @@ #include #include #include +#include #include "global.h" -#include +#include "hexedit.h" #include "linux_endian.h" -#include "hexedit.h" +#define WANT_GFS_CONVERSION_FUNCTIONS +#include "gfs_ondisk.h" #include "gfshex.h" - - - +extern int line; +extern struct gfs_sb sb; +extern char *buf; +extern struct gfs_dinode di; +extern uint64 bufsize; /****************************************************************************** ******************************************************************************* @@ -49,70 +53,60 @@ void do_dinode_extended(struct gfs_dinode *di, char *buf) { - unsigned int x, y, count; - struct gfs_dirent de; - uint64 p, last; - - - if (di->di_height > 0) - { - printf("\nIndirect Pointers\n\n"); - - for (x = sizeof(struct gfs_dinode), y = 0; - x < bsize; - x += sizeof(uint64), y++) - { - p = gfs64_to_cpu(*(uint64 *)(buf + x)); - - if (p) - printf(" %u -> %"PRIu64"\n", y, p); - } - } - - - else if (di->di_type == GFS_FILE_DIR && - !(di->di_flags & GFS_DIF_EXHASH)) - { - printf("\nDirectory Entries:\n"); - - for (x = sizeof(struct gfs_dinode); x < bsize; x += de.de_rec_len) - { - printf("\n"); - gfs_dirent_in(&de, buf + x); - if (de.de_inum.no_formal_ino) - gfs_dirent_print(&de, buf + x + sizeof(struct gfs_dirent)); - } - } - - - else if (di->di_type == GFS_FILE_DIR && - (di->di_flags & GFS_DIF_EXHASH) && - di->di_height == 0) - { - printf("\nLeaf Pointers:\n\n"); - - last = gfs64_to_cpu(*(uint64 *)(buf + sizeof(struct gfs_dinode))); - count = 0; + unsigned int x, y, count; + struct gfs_dirent de; + uint64 p, last; + + indirect_blocks = 0; + memset(indirect_block, 0, sizeof(indirect_block)); + if (di->di_height > 0) { + /* Indirect pointers */ + for (x = sizeof(struct gfs_dinode), y = 0; + x < bufsize; + x += sizeof(uint64), y++) { + p = gfs64_to_cpu(*(uint64 *)(buf + x)); + if (p) + indirect_block[indirect_blocks++] = p; + } + } + else if (di->di_type == GFS_FILE_DIR && + !(di->di_flags & GFS_DIF_EXHASH)) { + /* Directory Entries: */ + for (x = sizeof(struct gfs_dinode); x < bufsize && + de.de_rec_len > sizeof(struct gfs_dirent) && + de.de_rec_len < 256; x += de.de_rec_len) { + gfs_dirent_in(&de, buf + x); + if (de.de_inum.no_formal_ino) + indirect_block[indirect_blocks++] = de.de_inum.no_formal_ino; + } + } + else if (di->di_type == GFS_FILE_DIR && + (di->di_flags & GFS_DIF_EXHASH) && + di->di_height == 0) { + /* Leaf Pointers: */ + + last = gfs64_to_cpu(*(uint64 *)(buf + sizeof(struct gfs_dinode))); + count = 0; - for (x = sizeof(struct gfs_dinode), y = 0; - y < (1 << di->di_depth); - x += sizeof(uint64), y++) - { - p = gfs64_to_cpu(*(uint64 *)(buf + x)); - - if (p != last) - { - printf(" %u: %"PRIu64"\n", count, last); - last = p; - count = 1; - } - else - count++; - - if ((y + 1) * sizeof(uint64) == di->di_size) - printf(" %u: %"PRIu64"\n", count, last); - } - } + for (x = sizeof(struct gfs_dinode), y = 0; + y < (1 << di->di_depth); + x += sizeof(uint64), y++) { + p = gfs64_to_cpu(*(uint64 *)(buf + x)); + + if (p != last) { + indirect_block[indirect_blocks++] = last; + /*printf(" %u: %"PRIu64"\n", count, last);*/ + last = p; + count = 1; + } + else + count++; + + if ((y + 1) * sizeof(uint64) == di->di_size) + indirect_block[indirect_blocks++] = last; + ; /*printf(" %u: %"PRIu64"\n", count, last);*/ + } + } } @@ -139,7 +133,7 @@ printf("\nPointers\n\n"); - for (x = sizeof(struct gfs_indirect), y = 0; x < bsize; x += 8, y++) + for (x = sizeof(struct gfs_indirect), y = 0; x < bufsize; x += 8, y++) { p = gfs64_to_cpu(*(uint64 *)(buf + x)); @@ -173,7 +167,7 @@ printf("\nDirectory Entries:\n"); - for (x = sizeof(struct gfs_leaf); x < bsize; x += de.de_rec_len) + for (x = sizeof(struct gfs_leaf); x < bufsize; x += de.de_rec_len) { printf("\n"); gfs_dirent_in(&de, buf + x); @@ -207,7 +201,7 @@ printf("\nEattr Entries:\n"); - for (x = sizeof(struct gfs_meta_header); x < bsize; x += ea.ea_rec_len) + for (x = sizeof(struct gfs_meta_header); x < bufsize; x += ea.ea_rec_len) { printf("\n"); gfs_ea_header_in(&ea, buf + x); @@ -215,6 +209,42 @@ } } +void gfs_inum_print2(const char *title,struct gfs_inum *no) +{ + move(line,2); + printw(title); + pv2(no, no_formal_ino, "%"PRIX64); + pv2(no, no_addr, "%"PRIX64); +} + +/** + * gfs_sb_print2 - Print out a superblock + * @sb: the cpu-order buffer + */ +void gfs_sb_print2(struct gfs_sb *sb) +{ + gfs_meta_header_print(&sb->sb_header); + + pv(sb, sb_fs_format, "%u"); + pv(sb, sb_multihost_format, "%u"); + pv(sb, sb_flags, "%u"); + + pv(sb, sb_bsize, "%u"); + pv(sb, sb_bsize_shift, "%u"); + pv(sb, sb_seg_size, "%u"); + + gfs_inum_print2("jindex inode",&sb->sb_jindex_di); + gfs_inum_print2("rindex inode",&sb->sb_rindex_di); + gfs_inum_print2("root inode",&sb->sb_root_di); + + pv(sb, sb_lockproto, "%s"); + pv(sb, sb_locktable, "%s"); + + gfs_inum_print2("quota inode",&sb->sb_quota_di); + gfs_inum_print2("license inode",&sb->sb_license_di); + + pa(sb, sb_reserved, 96); +} /****************************************************************************** ******************************************************************************* @@ -233,30 +263,18 @@ ** ******************************************************************************* ******************************************************************************/ - -int display_gfs(int extended) +int display_gfs(void) { struct gfs_meta_header mh; - struct gfs_sb sb; struct gfs_rgrp rg; - struct gfs_dinode di; struct gfs_leaf lf; struct gfs_log_header lh; struct gfs_log_descriptor ld; - char *buf; uint32 magic; - - type_alloc(buf, char, bsize); - - do_lseek(fd, block * bsize); - do_read(fd, buf, bsize); - - magic = gfs32_to_cpu(*(uint32 *)buf); - switch (magic) { case GFS_MAGIC: @@ -265,222 +283,75 @@ switch (mh.mh_type) { case GFS_METATYPE_SB: - printf("Superblock:\n\n"); + printw("Superblock:\n\n"); gfs_sb_in(&sb, buf); - gfs_sb_print(&sb); - - if (extended) - printf("\nNo Extended data\n"); - + gfs_sb_print2(&sb); break; - case GFS_METATYPE_RG: - printf("Resource Group Header:\n\n"); + printw("Resource Group Header:\n\n"); gfs_rgrp_in(&rg, buf); gfs_rgrp_print(&rg); - - if (extended) - printf("\nNo Extended data\n"); - break; - case GFS_METATYPE_RB: - printf("Resource Group Bitmap:\n\n"); + printw("Resource Group Bitmap:\n\n"); gfs_meta_header_print(&mh); - - if (extended) - printf("\nNo Extended data\n"); - break; - case GFS_METATYPE_DI: - printf("Dinode:\n\n"); - gfs_dinode_in(&di, buf); + printw("Dinode:\n\n"); gfs_dinode_print(&di); - - if (extended) - do_dinode_extended(&di, buf); - break; - case GFS_METATYPE_LF: - printf("Leaf:\n\n"); + printw("Leaf:\n\n"); gfs_leaf_in(&lf, buf); gfs_leaf_print(&lf); - - if (extended) - do_leaf_extended(buf); - break; - case GFS_METATYPE_IN: - printf("Indirect Block:\n\n"); + printw("Indirect Block:\n\n"); gfs_meta_header_print(&mh); - - if (extended) - do_indirect_extended(buf); - break; - case GFS_METATYPE_JD: printf("Journaled File Block:\n\n"); gfs_meta_header_print(&mh); - - if (extended) - printf("\nNo Extended data\n"); - break; - case GFS_METATYPE_LH: - printf("Log Header:\n\n"); + printw("Log Header:\n\n"); gfs_log_header_in(&lh, buf); gfs_log_header_print(&lh); - - if (extended) - printf("\nNo Extended data\n"); - break; case GFS_METATYPE_LD: - printf("Log Descriptor:\n\n"); + printw("Log Descriptor:\n\n"); gfs_desc_in(&ld, buf); gfs_desc_print(&ld); - - if (extended) - printf("\nNo Extended data\n"); - break; - case GFS_METATYPE_EA: - printf("Eattr Block:\n\n"); + printw("Eattr Block:\n\n"); gfs_meta_header_print(&mh); - - if (extended) - do_eattr_extended(buf); - break; - case GFS_METATYPE_ED: - printf("Eattr Data Block:\n\n"); + printw("Eattr Data Block:\n\n"); gfs_meta_header_print(&mh); - - if (extended) - printf("\nNo Extended data\n"); - break; - default: - printf("Unknown metadata type\n"); + printw("Unknown metadata type\n"); break; } - break; - default: - printf("Unknown block type\n"); + printw("Unknown block type\n"); break; }; - - - free(buf); - - return(0); } - - -/****************************************************************************** -******************************************************************************* -** -** int edit_gfs() -** -** Description: -** This routine... -** -** Input(s): -** *buffer - -** extended - -** -** Returns: -** 0 if OK, 1 on error. -** -******************************************************************************* -******************************************************************************/ - -int edit_gfs(char *arg1, char *arg2, char *arg3) -{ - char buf[512]; - unsigned int row, col, byte; - uint64 dev_offset; - unsigned int offset; - - - if (!strncmp(arg3, "", 1)) - { - fprintf(stderr, "%s: invalid number of arguments\n", prog_name); - return(-EINVAL); - } - - - row = atoi(arg1); - col = atoi(arg2); - sscanf(arg3, "%x", &byte); - - - if (row >= SCREEN_HEIGHT) - { - fprintf(stderr, "%s: row is out of range for set\n", prog_name); - return(-EINVAL); - } - - if (col >= SCREEN_WIDTH) - { - fprintf(stderr, "%s: column is out of range for set\n", prog_name); - return(-EINVAL); - } - - if (byte > 255) - { - fprintf(stderr, "%s: byte value is out of range for set\n", prog_name); - return(-EINVAL); - } - - - - /* Make sure all I/O is 512-byte aligned */ - - dev_offset = (block * bsize + start * SCREEN_WIDTH + row * SCREEN_WIDTH + col) >> 9 << 9; - offset = (block * bsize + start * SCREEN_WIDTH + row * SCREEN_WIDTH + col) - dev_offset; - - - do_lseek(fd, dev_offset); - do_read(fd, buf, 512); - - buf[offset] = (unsigned char)byte; - - do_lseek(fd, dev_offset); - do_write(fd, buf, 512); - - - fsync(fd); - - return(0); -} - - - - - - --- cluster/gfs/gfs_edit/gfshex.h 2004/06/24 08:53:22 1.1 +++ cluster/gfs/gfs_edit/gfshex.h 2006/07/10 23:30:56 1.2 @@ -15,8 +15,9 @@ #define __GFSHEX_DOT_H__ -int display_gfs(int extended); -int edit_gfs(); +int display_gfs(void); +int edit_gfs(void); +void do_dinode_extended(struct gfs_dinode *di, char *buf); #endif /* __GFSHEX_DOT_H__ */ --- cluster/gfs/gfs_edit/hexedit.c 2004/06/24 08:53:22 1.1 +++ cluster/gfs/gfs_edit/hexedit.c 2006/07/10 23:30:56 1.2 @@ -20,281 +20,496 @@ #include #include #include +#include +#include +#include +#include +#include #include "global.h" -#include #include "copyright.cf" #define EXTERN #include "hexedit.h" #include "gfshex.h" +#include "gfs_ondisk.h" +#include "linux_endian.h" +#include +#define TITLE1 "gfs_edit - Global File System Editor (use with extreme caution)" +#define TITLE2 "Copyright (C) 2006 Red Hat, Inc. - Press H for help" +int display(void); -/****************************************************************************** -******************************************************************************* -** -** void print_usage() -** -** Description: -** This routine prints out the appropriate commands for this application. -** -******************************************************************************* -******************************************************************************/ - -void print_usage(void) +/* ------------------------------------------------------------------------ */ +/* UpdateSize - screen size changed, so update it */ +/* ------------------------------------------------------------------------ */ +void UpdateSize(int sig) { - fprintf(stderr, "\n\nSupported commands:\n"); + static char term_buffer[2048]; + int rc; - fprintf(stderr, "b \t- Block size\n"); - fprintf(stderr, "d\t\t- Display GFS structure\n"); - fprintf(stderr, "dx\t\t- Display GFS extended structure\n"); - fprintf(stderr, "e\t\t- Edit mode on and off\n"); - fprintf(stderr, "l\t\t- More Lines\n"); - fprintf(stderr, "n\t\t- Next\n"); - fprintf(stderr, "p\t\t- Previous\n"); - fprintf(stderr, "q\t\t- Quit\n"); - fprintf(stderr, "r\t\t- Reprint\n"); - fprintf(stderr, "s \t\t- Search\n"); - fprintf(stderr, "sx \t\t- Search to hex block\n"); - - fprintf(stderr, "\nEdit mode operations:\n"); - fprintf(stderr, "set \n"); - fprintf(stderr, " A particular byte within the current window is specified\n"); - fprintf(stderr, " by row and column numbers. The third argument is the\n"); - fprintf(stderr, " new value in hex (00 to FF).\n\n"); + termlines=30; + termtype=getenv("TERM"); + if (termtype==NULL) + return; + rc=tgetent(term_buffer,termtype); + if (rc>=0) { + termlines=tgetnum("li"); + if (termlines<10) + termlines=30; + } + else + perror("Error: tgetent failed."); + termlines--; /* last line is number of lines -1 */ + display(); + signal(SIGWINCH, UpdateSize); } - -/****************************************************************************** -******************************************************************************* -** -** int display() -** -** Description: -** This routine... -** -** Input(s): -** start - -** end - -** -** Returns: -** -** -******************************************************************************* -******************************************************************************/ - -int display() +/* ------------------------------------------------------------------------- */ +/* display_title_lines */ +/* ------------------------------------------------------------------------- */ +void display_title_lines(void) { - char *buf; - unsigned int row, col; - uint64 dev_offset; - unsigned int size, offset; - - - /* Make sure all I/O is 512-byte aligned */ - - dev_offset = (block * bsize + start * SCREEN_WIDTH) >> 9 << 9; - offset = (block * bsize + start * SCREEN_WIDTH) - dev_offset; - size = DIV_RU(SCREEN_HEIGHT * SCREEN_WIDTH, 512) * 512; - - - type_alloc(buf, char, size); - - do_lseek(fd, dev_offset); - do_read(fd, buf, size); - - - printf("\n\nblock size = %u\n", bsize); - printf("block = %"PRIu64" = 0x%.16"PRIX64"\n", - block, block); - printf("offset in block = %u\n\n", start * SCREEN_WIDTH); - - if (edit_mode) - { - printf(" "); - for (col = 0; col < SCREEN_WIDTH; col++) - printf("%.2u ", col); - printf("\n\n"); - } - - for (row = 0; row < SCREEN_HEIGHT; row++) - { - if (edit_mode) - printf("%.2u ", row); - - for (col = 0; col < SCREEN_WIDTH; col++) - printf("%.2X ", (unsigned char)buf[offset + SCREEN_WIDTH * row + col]); - - printf(" "); - - for (col = 0; col < SCREEN_WIDTH; col++) - { - if (isprint(buf[offset + SCREEN_WIDTH * row + col])) - printf("%c", buf[offset + SCREEN_WIDTH * row + col]); - else - printf(" "); - } - - printf("\n"); - } - - - free(buf); - - - return(0); + clear(); + attrset(COLOR_PAIR(1)); + move(0, 0); + printw("%-80s",TITLE1); + move(termlines, 0); + printw("%-79s",TITLE2); + attrset(COLOR_PAIR(2)); } +/* ------------------------------------------------------------------------- */ +/* bobgets - get a string */ +/* returns: 1 if user exited by hitting enter */ +/* 0 if user exited by hitting escape */ +/* ------------------------------------------------------------------------- */ +int bobgets(char string[],int x,int y,int sz) +{ + int done,ch,runningy,rc; + + move(x,y); + done=FALSE; + attrset(COLOR_PAIR(3)); + move(x,y); + addstr(string); + move(x,y); + curs_set(2); + refresh(); + runningy=y; + rc=0; + while (!done) { + ch=getch(); + + if(ch < 0x0100 && isprint(ch)) { + char *p=string+strlen(string); // end of the string + *(p+1)='\0'; + while (insert && p > &string[runningy-y]) { + *p=*(p-1); + p--; + } + string[runningy-y]=ch; + runningy++; + move(x,y); + addstr(string); + } + else { + // special character, is it one we recognize? + switch(ch) + { + case(KEY_ENTER): + case('\n'): + case('\r'): + rc=1; + done=TRUE; + break; + case(KEY_CANCEL): + case(0x01B): + rc=0; + done=TRUE; + break; + case(KEY_LEFT): + if (runningy>y) + runningy--; + break; + case(KEY_RIGHT): + runningy++; + break; + case(KEY_DC): + case(0x07F): + if (runningy>=y) { + char *p; + p = &string[runningy-y]; + while (*p) { + *p = *(p+1); + p++; + } + *p='\0'; + runningy--; + // remove the character from the string + move(x,y); + addstr(string); + attrset(COLOR_PAIR(2)); + addstr(" "); + attrset(COLOR_PAIR(3)); + runningy++; + } + break; + case(KEY_BACKSPACE): + if (runningy>y) { + char *p; + + p = &string[runningy-y-1]; + while (*p) { + *p = *(p+1); + p++; + } + *p='\0'; + runningy--; + // remove the character from the string + move(x,y); + addstr(string); + attrset(COLOR_PAIR(2)); + addstr(" "); + attrset(COLOR_PAIR(3)); + } + break; + case KEY_DOWN: // Down + rc=0x5000U; + done=TRUE; + break; + case KEY_UP: // Up + rc=0x4800U; + done=TRUE; + break; + case 0x014b: + insert=!insert; + move(0,68); + if (insert) + printw("insert "); + else + printw("replace"); + break; + default: + move(0,70); + printw("%08X",ch); + // ignore all other characters + break; + } // end switch on non-printable character + } // end non-printable character + move(x,runningy); + refresh(); + } // while !done + if (sz>0) + string[sz]='\0'; + attrset(COLOR_PAIR(2)); + return rc; +}/* bobgets */ /****************************************************************************** ******************************************************************************* ** -** int run_command() +** void print_usage() ** ** Description: -** This routine... -** -** Input(s): -** *cmd - -** *arg1 - -** *arg2 - -** -** Output(s): -** -** -** Returns: -** 0 if OK, 1 on error. +** This routine prints out the appropriate commands for this application. ** ******************************************************************************* ******************************************************************************/ -int run_command(char *cmd, char *arg1, char *arg2, char *arg3) +void print_usage(void) { - int error; - - if (*cmd == 'b') /* Change block size */ - { - bsize = atoi(arg1); - if (!bsize) - bsize = GFS_BASIC_BLOCK; - - block = 0; - start = 0; - - display(); - } - - - else if (!strncmp(cmd, "dx", 2)) /* Display GFS structure */ - { - display_gfs(TRUE); - } - - - else if (*cmd == 'd') /* Display GFS structure */ - { - display_gfs(FALSE); - } - - - else if (*cmd == 'e') /* Edit GFS structure */ - { - edit_mode = !edit_mode; - } - - - else if (*cmd == 'l') /* Next few lines */ - { - start += SCREEN_HEIGHT; - - if (start * SCREEN_WIDTH >= bsize) - { - start = 0; - block++; - } - - display(); - } - - - else if (*cmd == 'n') /* Next */ - { - start = 0; - block++; - display(); - } - - - else if (*cmd == 'p') /* Previous */ - { - start = 0; - block--; - if (block < 0) - block = 0; - - display(); - } - - - else if (*cmd == 'q') /* Quit */ - { - printf("\n\n"); - exit(0); - } - - - else if (*cmd == 'r') /* Reprint */ - { - start = 0; - - display(); - } - - - else if (!strncmp(cmd, "sx", 2)) /* Search in Hex */ - { - start = 0; - sscanf(arg1, "%"SCNx64, &block); - - display(); - } - - - else if (!strncmp(cmd, "set", 3)) /* Set byte in current window */ - { - if (!edit_mode) - { - fprintf(stderr, "%s: not in edit mode\n", prog_name); - print_usage(); - return(0); - } - - error = edit_gfs(arg1, arg2, arg3); - - if (!error) - display(); - } + int ch; + line = 2; + clear(); + display_title_lines(); + move(line++,0); + printw("Supported commands: (roughly conforming to the rules of 'less')"); + line++; + move(line++,0); + printw(" b - Backward one 4K block"); + move(line++,0); + printw(" f - Forward one 4K block"); + move(line++,0); + printw(" g - Goto a given block in hex"); + move(line++,0); + printw(" h - This Help display"); + move(line++,0); + printw(" j - Jump to the highlighted 64-bit block number."); + move(line++,0); + printw(" m - Switch display mode: hex -> GFS structure -> Extended"); + move(line++,0); + printw(" q - Quit (same as hitting key)"); + move(line++,0); + printw(" - Forward one 4K block (same as 'f')"); + move(line++,0); + printw("/ - move up or down one screen full"); + move(line++,0); + printw("/ - move up or down one line"); + move(line++,0); + printw("/ - move left or right one byte"); + move(line++,0); + printw(" - return to the superblock."); + move(line++,0); + printw(" - edit a value (enter to save, esc to discard)"); + move(line++,0); + printw(" - return to previous block"); + move(line++,0); + printw(" - Quit the program"); + move(line++,0); + move(line++,0); + printw("Notes: Areas shown in red are outside the bounds of the struct."); + move(line++,0); + printw(" Fields shown in green are selected for edit on ."); + move(line++,0); + move(line++,0); + printw("Press any key to return."); + refresh(); + while ((ch=getch()) == 0); // wait for input + clear(); +} - else if (*cmd == 's') /* Search */ - { - start = 0; - sscanf(arg1, "%"SCNd64, &block); +/* ------------------------------------------------------------------------ */ +/* display_block_type */ +/* returns: metatype if block is a GFS structure block type */ +/* 0 if block is not a GFS structure */ +/* ------------------------------------------------------------------------ */ +int display_block_type(const char *lpBuffer) +{ + int ret_type = 0; /* return type */ - display(); - } + /* first, print out the kind of GFS block this is */ + line = 1; + move(line, 0); + printw("Block #"); + if (edit_row[display_mode] == -1) + attrset(COLOR_PAIR(5));; + printw("%"PRIX64,block); + if (edit_row[display_mode] == -1) + attrset(COLOR_PAIR(2)); + move(line,25); + printw("of %"PRIX64,max_block); + move(line, 45); + + if (*(lpBuffer+0)==0x01 && *(lpBuffer+1)==0x16 && *(lpBuffer+2)==0x19 && + *(lpBuffer+3)==0x70 && *(lpBuffer+4)==0x00 && *(lpBuffer+5)==0x00 && + *(lpBuffer+6)==0x00) { /* If magic number appears at the start */ + ret_type = *(lpBuffer+7); + switch (*(lpBuffer+7)) { + case GFS_METATYPE_SB: /* 1 */ + printw("(superblock)"); + struct_len = sizeof(struct gfs_sb); + break; + case GFS_METATYPE_RG: /* 2 */ + printw("(rsrc grp hdr)"); + struct_len = sizeof(struct gfs_rgrp); + break; + case GFS_METATYPE_RB: /* 3 */ + printw("(rsrc grp bitblk)"); + struct_len = 512; + break; + case GFS_METATYPE_DI: /* 4 */ + printw("(disk inode)"); + struct_len = sizeof(struct gfs_dinode); + break; + case GFS_METATYPE_IN: /* 5 */ + printw("(indir inode blklst)"); + struct_len = sizeof(struct gfs_indirect); + break; + case GFS_METATYPE_LF: /* 6 */ + printw("(leaf dinode blklst)"); + struct_len = sizeof(struct gfs_leaf); + break; + case GFS_METATYPE_JD: + printw("(journal data)"); + struct_len = sizeof(struct gfs_meta_header); + break; + case GFS_METATYPE_LH: + printw("(log header)"); + struct_len = sizeof(struct gfs_log_header); + break; + case GFS_METATYPE_LD: + printw("(log descriptor)"); + struct_len = sizeof(struct gfs_log_descriptor); + break; + case GFS_METATYPE_EA: + printw("(extended attr hdr)"); + struct_len = sizeof(struct gfs_ea_header); + break; + case GFS_METATYPE_ED: + printw("(extended attr data)"); + struct_len = 512; + break; + default: + printw("(wtf?)"); + struct_len = 512; + break; + } + } + else + struct_len = 512; + line++; + move(line, 0); + if (display_mode == HEX_MODE) { + /* calculate how much of the buffer we can fit on screen */ + screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8; + if (!screen_chunk_size) + screen_chunk_size = 256; + printw("(%d of %d)", (offset / screen_chunk_size) + 1, + (bufsize % screen_chunk_size) > 0 ? + bufsize / screen_chunk_size + 1 : bufsize / screen_chunk_size); + } + move(line, 9); + if (block == sb.sb_jindex_di.no_addr) + printw("----------------- Journal Index file -----------------"); + else if (block == sb.sb_rindex_di.no_addr) + printw("-------------- Resource Group Index file -------------"); + else if (block == sb.sb_quota_di.no_addr) + printw("---------------------- Quota file --------------------"); + else if (block == sb.sb_root_di.no_addr) + printw("-------------------- Root direcory -------------------"); + else if (block == sb.sb_license_di.no_addr) + printw("--------------------- License file -------------------"); + line++; + return ret_type; +} +/* ------------------------------------------------------------------------ */ +/* hexdump - hex dump the filesystem block to the screen */ +/* ------------------------------------------------------------------------ */ +int hexdump(uint64 startaddr, const char *lpBuffer, int len) +{ + const unsigned char *pointer,*ptr2; + int i; + uint64 l; + + strcpy(edit_fmt,"%02X"); + pointer = (unsigned char *)lpBuffer + offset; + ptr2 = (unsigned char *)lpBuffer + offset; + l = offset; + while (line < termlines && + line <= ((screen_chunk_size / 16) + 2) && + l < bufsize) { + move(line, 0); + attrset(COLOR_PAIR(6)); /* yellow for offsets */ + if (startaddr < 0xffffffff) + printw("%.8"PRIX64,startaddr + l); + else + printw("%.16"PRIX64,startaddr + l); + if (l < struct_len) + attrset(COLOR_PAIR(2)); /* normal part of the structure */ + else + attrset(COLOR_PAIR(4)); /* beyond the end of the structure */ + for (i=0; i<16; i++) { /* first print it in hex */ + if (l+i < struct_len) + attrset(COLOR_PAIR(2)); /* normal part of the structure */ + else + attrset(COLOR_PAIR(4)); /* beyond the end of the structure */ + if (i%4 == 0) + printw(" "); + if (line == edit_row[display_mode] + 3 && + i == edit_col[display_mode]) { + attrset(COLOR_PAIR(5)); /* normal part of the structure */ + memset(edit_string,0,3); + sprintf(edit_string,"%02X",*pointer); + } + printw("%02X",*pointer); + if (line == edit_row[display_mode] + 3 && + i == edit_col[display_mode]) { + if (l < struct_len + offset) + attrset(COLOR_PAIR(2)); /* normal part of the structure */ + else + attrset(COLOR_PAIR(4)); /* beyond end of the structure */ + } + pointer++; + } + printw(" ["); + for (i=0; i<16; i++) { /* now print it in character format */ + if ((*ptr2 >=' ') && (*ptr2 <= '~')) + printw("%c",*ptr2); + else + printw("."); + ptr2++; + } + printw("] "); + if (line - 3 > edit_last[display_mode]) + edit_last[display_mode] = line - 3; + line++; + l+=16; + } + return (offset+len); +} - else - { - fprintf(stderr, "%s: unknown command (%s)\n", prog_name, cmd); - print_usage(); - } +/* ------------------------------------------------------------------------ */ +/* display_extended */ +/* ------------------------------------------------------------------------ */ +int display_extended(void) +{ + int e; + edit_last[display_mode] = 0; + move(line++, 0); + if (indirect_blocks) { + printw("This inode contains %d indirect blocks", indirect_blocks); + line++; + move(line++, 0); + printw("Indirect blocks for this inode:"); + for (e = 0; e < termlines && e < indirect_blocks; e++) { + if (line - 6 == edit_row[display_mode]) + attrset(COLOR_PAIR(5)); + move(line, 5); + printw("%d => %"PRIX64, e + 1, indirect_block[e]); + if (line - 6 == edit_row[display_mode]) { + sprintf(edit_string, "%"PRIX64, indirect_block[e]); + strcpy(edit_fmt, "%"PRIX64); + edit_size[display_mode] = strlen(edit_string); + attrset(COLOR_PAIR(2)); + } + line++; + } + if (line >= 7) /* 7 because it was bumped at the end */ + edit_last[display_mode] = line - 7; + } + else + printw("This block does not have indirect blocks."); + return 0; +} - return(0); +/* ------------------------------------------------------------------------ */ +/* display */ +/* ------------------------------------------------------------------------ */ +int display(void) +{ + display_title_lines(); + move(2,0); + if (block_in_mem != block) { /* If we changed blocks from the last read */ + dev_offset = block * bufsize; + ioctl(fd, BLKFLSBUF, 0); + do_lseek(fd, dev_offset); + do_read(fd, buf, bufsize); /* read in the desired block */ + block_in_mem = block; /* remember which block is in memory */ + } + line = 1; + gfs_struct_type = display_block_type(buf); + indirect_blocks = 0; + if (gfs_struct_type == GFS_METATYPE_SB || block == 0x10) + gfs_sb_in(&sb, buf); /* parse it out into the sb structure */ + else if (gfs_struct_type == GFS_METATYPE_DI) { + gfs_dinode_in(&di, buf); /* parse disk inode into structure */ + do_dinode_extended(&di, buf); /* get extended data, if any */ + } + edit_last[display_mode] = 0; + if (display_mode == HEX_MODE) /* if hex display mode */ + hexdump(dev_offset, buf, 256); /* show the block in hex */ + else if (display_mode == GFS_MODE) /* if structure display */ + display_gfs(); /* display the gfs structure */ + else /* otherwise */ + display_extended(); /* display extended blocks */ + refresh(); + return(0); } @@ -308,68 +523,311 @@ ** ******************************************************************************* ******************************************************************************/ - int main(int argc, char *argv[]) { - char line[STRLEN]; - char cmd[STRLEN]; - char arg1[STRLEN]; - char arg2[STRLEN]; - char arg3[STRLEN]; - - - prog_name = argv[0]; - - if (argc < 2) - die("no device specified\n"); - - if(!strcmp(argv[1], "-V")) { - printf("%s %s (built %s %s)\n", prog_name, GFS_RELEASE_NAME, - __DATE__, __TIME__); - printf("%s\n", REDHAT_COPYRIGHT); - exit(0); - } - - fd = open(argv[1], O_RDWR); - if (fd < 0) - die("can't open %s: %s\n", argv[1], strerror(errno)); - - - - start = 0; - display(); - - printf("\n\n> "); - - - while (fgets(line, STRLEN - 1, stdin) != NULL) - { - sscanf(line, "%s %s %s %s", cmd, arg1, arg2, arg3); - - if (!strncmp(cmd, "", 1)) - { - /* Do nothing */ - } - else - { - printf("\n"); - run_command(cmd, arg1, arg2, arg3); - } - - printf("\n\n> "); - - memset(line, 0, STRLEN); - memset(cmd, 0, STRLEN); - memset(arg1, 0, STRLEN); - memset(arg2, 0, STRLEN); - memset(arg3, 0, STRLEN); - } - - - printf("\n\n"); - - - exit(EXIT_SUCCESS); + char device[STRLEN]; + char string[256]; + int i,ch, left_off; + int64 temp_blk; + + prog_name = argv[0]; + + if (argc < 2) + die("no device specified\n"); + + 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)); + display_mode = HEX_MODE; + type_alloc(buf, char, bufsize); /* allocate/malloc a new 4K buffer */ + block = 0x10; + for (i = 1; i < argc; i++) { + if (!strcasecmp(argv[i], "-verbose")) + verbose = TRUE; + else if (!strcasecmp(argv[i], "-V")) { + printf("%s %s (built %s %s)\n", prog_name, GFS_RELEASE_NAME, + __DATE__, __TIME__); + printf("%s\n", REDHAT_COPYRIGHT); + exit(0); + } + else { + strcpy(device,argv[i]); + } + } + fd = open(device, O_RDWR); + if (fd < 0) + die("can't open %s: %s\n", argv[1], strerror(errno)); + max_block = lseek(fd, 0, SEEK_END) / bufsize; + + if (initscr() == NULL) { + fprintf(stderr, "Error: unable to initialize screen.\n"); + exit(-1); + } + + signal(SIGWINCH, UpdateSize); /* handle the terminal resize signal */ + UpdateSize(0); /* update screen size based on terminal settings */ + clear(); + start_color(); + noecho(); + keypad(stdscr, TRUE); + raw(); + curs_set(0); + init_pair(1, COLOR_BLACK, COLOR_CYAN); /* title lines */ + init_pair(2, COLOR_WHITE, COLOR_BLACK); /* normal text */ + init_pair(3, COLOR_BLACK, COLOR_WHITE); /* inverse text */ + init_pair(4, COLOR_RED, COLOR_BLACK); /* special text */ + init_pair(5, COLOR_GREEN, COLOR_BLACK); /* highlighted text */ + init_pair(6, COLOR_CYAN, COLOR_BLACK); /* offsets */ + + while (!Quit) { + display(); + while ((ch=getch()) == 0); // wait for input + switch (ch) + { + /* -------------------------------------------------------------- */ + /* escape or 'q' */ + /* -------------------------------------------------------------- */ + case 0x1b: + case 0x03: + case 'q': + Quit=TRUE; + break; + /* -------------------------------------------------------------- */ + /* home - return to the superblock */ + /* -------------------------------------------------------------- */ + case KEY_HOME: + previous_block = block; + block = 0x10; + offset = 0; + break; + /* -------------------------------------------------------------- */ + /* backspace - return to the previous block */ + /* -------------------------------------------------------------- */ + case KEY_BACKSPACE: + case 0x7f: + temp_blk = block; + block = previous_block; + previous_block = temp_blk; + offset = 0; + break; + /* -------------------------------------------------------------- */ + /* arrow up */ + /* -------------------------------------------------------------- */ + case KEY_UP: + if (edit_row[display_mode] >= 0) /* -1 means change block number */ + edit_row[display_mode]--; + break; + /* -------------------------------------------------------------- */ + /* arrow down */ + /* -------------------------------------------------------------- */ + case KEY_DOWN: + if (edit_row[display_mode] < edit_last[display_mode]) + edit_row[display_mode]++; + break; + /* -------------------------------------------------------------- */ + /* arrow left */ + /* -------------------------------------------------------------- */ + case KEY_LEFT: + if (display_mode == HEX_MODE) { + if (edit_col[display_mode] > 0) + edit_col[display_mode]--; + else + edit_col[display_mode] = 15; + } + break; + /* -------------------------------------------------------------- */ + /* arrow right */ + /* -------------------------------------------------------------- */ + case KEY_RIGHT: + if (display_mode == HEX_MODE) { + if (edit_col[display_mode] < 15) + edit_col[display_mode]++; + else + edit_col[display_mode] = 0; + } + break; + /* -------------------------------------------------------------- */ + /* m - change display mode key */ + /* -------------------------------------------------------------- */ + case 'm': + display_mode = ((display_mode + 1) % DISPLAY_MODES); + break; + /* -------------------------------------------------------------- */ + /* J - Jump to highlighted block number */ + /* -------------------------------------------------------------- */ + case 'j': + if (display_mode == HEX_MODE) { + unsigned int col2; + uint64 *b; + + col2 = edit_col[display_mode] & 0x08;/* thus 0-7->0, 8-15->8 */ + b = (uint64 *)&buf[edit_row[display_mode]*16 + offset + col2]; + temp_blk=gfs64_to_cpu(*b); + } + else + sscanf(edit_string, "%"SCNx64, &temp_blk);/* retrieve in hex */ + if (temp_blk < max_block) { /* if the block number is valid */ + offset = 0; + display_mode = HEX_MODE; + previous_block = block; + block = temp_blk; + } + break; + /* -------------------------------------------------------------- */ + /* g - goto block */ + /* -------------------------------------------------------------- */ + case 'g': + memset(string, 0, sizeof(string)); + sprintf(string,"%"PRIX64, block); + if (bobgets(string, 1, 7, 16)) + sscanf(string, "%"SCNx64, &temp_blk); /* retrieve in hex */ + if (temp_blk < max_block) { + offset = 0; + previous_block = block; + block = temp_blk; + } + break; + /* -------------------------------------------------------------- */ + /* h - help key */ + /* -------------------------------------------------------------- */ + case 'h': + print_usage(); + break; + /* -------------------------------------------------------------- */ + /* b - Back one 4K block */ + /* -------------------------------------------------------------- */ + case 'b': + edit_row[display_mode] = 0; + if (block > 0) { + previous_block = block; + block--; + } + offset = 0; + break; + /* -------------------------------------------------------------- */ + /* page up key */ + /* -------------------------------------------------------------- */ + case 0x19: // ctrl-y for vt100 + case KEY_PPAGE: // PgUp + case 0x15: // ctrl-u for vi compat. + case 0x02: // ctrl-b for less compat. + edit_row[display_mode] = 0; + if (display_mode == GFS_MODE || offset==0) { + previous_block = block; + block--; + if (display_mode == HEX_MODE) + offset = (bufsize % screen_chunk_size) > 0 ? + screen_chunk_size * (bufsize / screen_chunk_size) : + bufsize - screen_chunk_size; + else + offset = 0; + } + else + offset -= screen_chunk_size; + break; + /* -------------------------------------------------------------- */ + /* f - Forward one 4K block */ + /* -------------------------------------------------------------- */ + case 'f': + case ' ': /* space for less/more compat. */ + previous_block = block; + edit_row[display_mode] = 0; + block++; + offset = 0; + break; + /* -------------------------------------------------------------- */ + /* page down key */ + /* -------------------------------------------------------------- */ + case 0x16: // ctrl-v for vt100 + case KEY_NPAGE: // PgDown + case 0x04: // ctrl-d for vi compat. + edit_row[display_mode] = 0; + if (display_mode == GFS_MODE || + offset + screen_chunk_size >= bufsize) { + previous_block = block; + block++; + offset = 0; + } + else + offset += screen_chunk_size; + break; + /* -------------------------------------------------------------- */ + /* enter key - change a value */ + /* -------------------------------------------------------------- */ + case(KEY_ENTER): + case('\n'): + case('\r'): + if (edit_row[display_mode] == -1) { + memset(string, 0, sizeof(string)); + sprintf(string,"%"PRIX64, block); + if (bobgets(string, 1, 7, 16)) + sscanf(string, "%"SCNx64, &temp_blk); /* retrieve in hex */ + if (temp_blk < max_block) { + offset = 0; + previous_block = block; + block = temp_blk; + } + } + else { + if (display_mode == HEX_MODE) { + left_off = ((block * bufsize) < 0xffffffff) ? 9 : 17; + /* 8 and 16 char addresses on screen */ + + if (bobgets(edit_string, edit_row[display_mode] + 3, + (edit_col[display_mode] * 2) + + (edit_col[display_mode] / 4) + left_off, 2)) { + if (strstr(edit_fmt,"X") || strstr(edit_fmt,"x")) { + int hexoffset; + unsigned char ch; + + hexoffset = (edit_row[display_mode] * 16) + + edit_col[display_mode]; + ch = 0x00; + if (isdigit(edit_string[0])) + ch = (edit_string[0] - '0') * 0x10; + else if (edit_string[0] >= 'a' && + edit_string[0] <= 'f') + ch = (edit_string[0] - 'a' + 0x0a) * 0x10; + else if (edit_string[0] >= 'A' && + edit_string[0] <= 'F') + ch = (edit_string[0] - 'A' + 0x0a) * 0x10; + if (isdigit(edit_string[1])) + ch += (edit_string[1] - '0'); + else if (edit_string[1] >= 'a' && + edit_string[1] <= 'f') + ch += (edit_string[1] - 'a' + 0x0a); + else if (edit_string[1] >= 'A' && + edit_string[1] <= 'F') + ch += (edit_string[1] - 'A' + 0x0a); + buf[offset + hexoffset] = ch; + do_lseek(fd, dev_offset); + do_write(fd, buf, bufsize); + fsync(fd); + } + } + } + else if (display_mode == GFS_MODE) + bobgets(edit_string, edit_row[display_mode] + 3, 24, + edit_size[display_mode]); + else + bobgets(edit_string, edit_row[display_mode] + 6, 24, + edit_size[display_mode]); + } + break; + default: + move(termlines - 1, 0); + printw("Keystroke not understood: %02X",ch); + refresh(); + sleep(2); + break; + } /* switch */ + } /* while !Quit */ + clear(); + refresh(); + endwin(); + close(fd); + if (buf) + free(buf); + exit(EXIT_SUCCESS); } - - --- cluster/gfs/gfs_edit/hexedit.h 2004/06/24 08:53:22 1.1 +++ cluster/gfs/gfs_edit/hexedit.h 2006/07/10 23:30:56 1.2 @@ -15,6 +15,13 @@ #define __HEXVIEW_DOT_H__ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + /* Extern Macro */ #ifndef EXTERN @@ -26,23 +33,46 @@ #define INIT(X) =X #endif - +#define DISPLAY_MODES 3 +enum dsp_mode { HEX_MODE = 0, GFS_MODE = 1, EXTENDED_MODE = 2 }; EXTERN char *prog_name; EXTERN int fd; -EXTERN unsigned int bsize INIT(GFS_BASIC_BLOCK); EXTERN int64 block INIT(0); -EXTERN unsigned int start INIT(0); +EXTERN int64 previous_block INIT(0); +EXTERN int64 block_in_mem INIT(-1); EXTERN int edit_mode INIT(0); - - +EXTERN int line, termlines; +EXTERN char edit_fmt[80]; +EXTERN char edit_string[1024]; +EXTERN int verbose INIT(FALSE); +EXTERN uint64 dev_offset INIT(0); +EXTERN uint64 max_block INIT(0); +EXTERN char *buf INIT(NULL); +EXTERN uint64 bufsize INIT(4096); +EXTERN int Quit INIT(FALSE); +EXTERN int termlines INIT(30); +EXTERN int insert INIT(0); +EXTERN const char *termtype; +EXTERN int line INIT(1); +EXTERN int struct_len INIT(0); +EXTERN unsigned int offset; +EXTERN int edit_row[DISPLAY_MODES], edit_col[DISPLAY_MODES]; +EXTERN int edit_size[DISPLAY_MODES], edit_last[DISPLAY_MODES]; +EXTERN char edit_string[1024], edit_fmt[80]; +EXTERN struct gfs_sb sb; +EXTERN struct gfs_dinode di; +EXTERN int screen_chunk_size INIT(512); /* how much of the 4K can fit on screen */ +EXTERN int gfs_struct_type; +EXTERN uint64 indirect_block[512]; /* more than the most indirect ptrs possible + for any given 4K block */ +EXTERN int indirect_blocks INIT(0); /* count of indirect blocks */ +EXTERN enum dsp_mode display_mode INIT(HEX_MODE); #define STRLEN (256) #define SCREEN_HEIGHT (16) #define SCREEN_WIDTH (16) - - #define die(fmt, args...) \ { \ fprintf(stderr, "%s: ", prog_name); \ @@ -50,8 +80,6 @@ exit(EXIT_FAILURE); \ } - - /* I/O macros */ #define do_lseek(fd, off) \ @@ -97,6 +125,66 @@ __LINE__, __FILE__); \ } +#define pa(struct, member, count) print_array(#member, struct->member, count); +#define printk printw +#define pv(struct, member, fmt) do { \ + if (line < termlines) { \ + if (line == edit_row[display_mode] + 3) { \ + attrset(COLOR_PAIR(5)); \ + } \ + move(line,0); \ + printw(" "#member":"); \ + move(line,24); \ + printw(fmt, struct->member); \ + move(line, 50); \ + if (strstr(fmt,"X") || strstr(fmt,"x")) \ + printw("(hex)"); \ + else if (strstr(fmt,"s")) \ + printw("(string)"); \ + else \ + printw("(decimal)"); \ + refresh(); \ + if (line == edit_row[display_mode] + 3) { \ + sprintf(edit_string, fmt, struct->member); \ + strcpy(edit_fmt, fmt); \ + edit_size[display_mode] = strlen(edit_string); \ + attrset(COLOR_PAIR(2)); \ + } \ + if (line - 3 > edit_last[display_mode]) \ + edit_last[display_mode] = line - 3; \ + line++; \ + move(line,0); /* this seemingly redundant move needed */ \ + } \ + } while (FALSE); + +#define pv2(struct, member, fmt) do { \ + if (line < termlines) { \ + if (line == edit_row[display_mode] + 3) { \ + attrset(COLOR_PAIR(5)); \ + } \ + move(line,24); \ + printw(fmt, struct->member); \ + move(line, 50); \ + if (strstr(fmt,"X") || strstr(fmt,"x")) \ + printw("(hex)"); \ + else if (strstr(fmt,"s")) \ + printw("(string)"); \ + else \ + printw("(decimal)"); \ + refresh(); \ + if (line == edit_row[display_mode] + 3) { \ + sprintf(edit_string, fmt, struct->member); \ + strcpy(edit_fmt, fmt); \ + edit_size[display_mode] = strlen(edit_string); \ + attrset(COLOR_PAIR(2)); \ + } \ + if (line - 3 > edit_last[display_mode]) \ + edit_last[display_mode] = line - 3; \ + line++; \ + move(line,0); /* this seemingly redundant move needed */ \ + } \ + } while (FALSE); + /* Divide x by y. Round up if there is a remainder. */ #define DIV_RU(x, y) (((x) + (y) - 1) / (y)) --- cluster/gfs/gfs_edit/ondisk.c 2005/01/18 16:18:59 1.2 +++ cluster/gfs/gfs_edit/ondisk.c 2006/07/10 23:30:56 1.3 @@ -16,15 +16,8 @@ #include "global.h" #include "linux_endian.h" -#include - -#define printk printf -#define pv(struct, member, fmt) printf(" "#member" = "fmt"\n", struct->member); -#define ENTER(x) -#define EXIT(x) -#define RET(x) return -#define RETURN(x, y) return y +#include #define WANT_GFS_CONVERSION_FUNCTIONS #include