[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] cluster/gfs/gfs_edit Makefile gfshex.c gfshex. ...



CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	rpeterso 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 <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <curses.h>
 
 #include "global.h"
-#include <linux/gfs_ondisk.h>
+#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 <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <curses.h>
+#include <term.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
 
 #include "global.h"
-#include <linux/gfs_ondisk.h>
 #include "copyright.cf"
 
 #define EXTERN
 #include "hexedit.h"
 #include "gfshex.h"
+#include "gfs_ondisk.h"
+#include "linux_endian.h"
 
+#include <syslog.h>
 
+#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 <bytes>\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 <bn>\t\t- Search\n");
-  fprintf(stderr, "sx <bn>\t\t- Search to hex block\n");
-
-  fprintf(stderr, "\nEdit mode operations:\n");
-  fprintf(stderr, "set <row> <col> <byte>\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 <escape> key)");
+	move(line++,0);
+	printw("<space>        - Forward one 4K block (same as 'f')");
+	move(line++,0);
+	printw("<pg up>/<down> - move up or down one screen full");
+	move(line++,0);
+	printw("<up>/<down>    - move up or down one line");
+	move(line++,0);
+	printw("<left>/<right> - move left or right one byte");
+	move(line++,0);
+	printw("<home>         - return to the superblock.");
+	move(line++,0);
+	printw("<enter>        - edit a value (enter to save, esc to discard)");
+	move(line++,0);
+	printw("<backspace>    - return to previous block");
+	move(line++,0);
+	printw("<escape>       - 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 <enter>.");
+	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 <linux/gfs_ondisk.h>
-
-#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 <linux/gfs_ondisk.h>
 
 #define WANT_GFS_CONVERSION_FUNCTIONS
 #include <linux/gfs_ondisk.h>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]