Blame gfs2/edit/hexedit.c

Packit Service 360c39
#include "clusterautoconfig.h"
Packit Service 360c39
Packit Service 360c39
#include <stdio.h>
Packit Service 360c39
#include <stdlib.h>
Packit Service 360c39
#include <ctype.h>
Packit Service 360c39
#include <string.h>
Packit Service 360c39
#include <inttypes.h>
Packit Service 360c39
#include <sys/types.h>
Packit Service 360c39
#include <linux/types.h>
Packit Service 360c39
#include <sys/stat.h>
Packit Service 360c39
#include <fcntl.h>
Packit Service 360c39
#include <unistd.h>
Packit Service 360c39
#include <errno.h>
Packit Service 360c39
#include <curses.h>
Packit Service 360c39
#include <term.h>
Packit Service 360c39
#include <time.h>
Packit Service 360c39
#include <signal.h>
Packit Service 360c39
#include <sys/ioctl.h>
Packit Service 360c39
#include <sys/mount.h>
Packit Service 360c39
#include <dirent.h>
Packit Service 360c39
Packit Service 360c39
#include <linux/gfs2_ondisk.h>
Packit Service 360c39
#include "copyright.cf"
Packit Service 360c39
Packit Service 360c39
#include "hexedit.h"
Packit Service 360c39
#include "libgfs2.h"
Packit Service 360c39
#include "gfs2hex.h"
Packit Service 360c39
#include "extended.h"
Packit Service 360c39
#include "journal.h"
Packit Service 360c39
Packit Service 360c39
const char *mtypes[] = {"none", "sb", "rg", "rb", "di", "in", "lf", "jd",
Packit Service 360c39
			"lh", "ld", "ea", "ed", "lb", "13", "qc"};
Packit Service 360c39
const char *allocdesc[2][5] = {
Packit Service 360c39
	{"Free ", "Data ", "Unlnk", "Meta ", "Resrv"},
Packit Service 360c39
	{"Free ", "Data ", "FreeM", "Meta ", "Resrv"},};
Packit Service 360c39
Packit Service 360c39
struct gfs2_buffer_head *bh;
Packit Service 360c39
struct gfs2_rgrp *lrgrp;
Packit Service 360c39
struct gfs2_meta_header *lmh;
Packit Service 360c39
struct gfs2_dinode *ldi;
Packit Service 360c39
struct gfs2_leaf *lleaf;
Packit Service 360c39
struct gfs2_log_header *llh;
Packit Service 360c39
struct gfs2_log_descriptor *lld;
Packit Service 360c39
int pgnum;
Packit Service 360c39
int details = 0;
Packit Service 360c39
long int gziplevel = 9;
Packit Service 360c39
static int termcols;
Packit Service 360c39
char *device = NULL;
Packit Service 360c39
extern uint64_t block;
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------- */
Packit Service 360c39
/* erase - clear the screen */
Packit Service 360c39
/* ------------------------------------------------------------------------- */
Packit Service 360c39
static void Erase(void)
Packit Service 360c39
{
Packit Service 360c39
	bkgd(A_NORMAL|COLOR_PAIR(COLOR_NORMAL));
Packit Service 360c39
	/* clear();*/ /* doesn't set background correctly */
Packit Service 360c39
	erase();
Packit Service 360c39
	/*bkgd(bg);*/
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------- */
Packit Service 360c39
/* display_title_lines */
Packit Service 360c39
/* ------------------------------------------------------------------------- */
Packit Service 360c39
static void display_title_lines(void)
Packit Service 360c39
{
Packit Service 360c39
	Erase();
Packit Service 360c39
	COLORS_TITLE;
Packit Service 360c39
	move(0, 0);
Packit Service 360c39
	printw("%-80s",TITLE1);
Packit Service 360c39
	move(termlines, 0);
Packit Service 360c39
	printw("%-79s",TITLE2);
Packit Service 360c39
	COLORS_NORMAL;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------- */
Packit Service 360c39
/* bobgets - get a string                                                    */
Packit Service 360c39
/* returns: 1 if user exited by hitting enter                                */
Packit Service 360c39
/*          0 if user exited by hitting escape                               */
Packit Service 360c39
/* ------------------------------------------------------------------------- */
Packit Service 360c39
static int bobgets(char string[],int x,int y,int sz,int *ch)
Packit Service 360c39
{
Packit Service 360c39
	int done,runningy,rc;
Packit Service 360c39
Packit Service 360c39
	move(x,y);
Packit Service 360c39
	done=FALSE;
Packit Service 360c39
	COLORS_INVERSE;
Packit Service 360c39
	move(x,y);
Packit Service 360c39
	addstr(string);
Packit Service 360c39
	move(x,y);
Packit Service 360c39
	curs_set(2);
Packit Service 360c39
	refresh();
Packit Service 360c39
	runningy=y;
Packit Service 360c39
	rc=0;
Packit Service 360c39
	while (!done) {
Packit Service 360c39
		*ch = getch();
Packit Service 360c39
		
Packit Service 360c39
		if(*ch < 0x0100 && isprint(*ch)) {
Packit Service 360c39
			char *p=string+strlen(string); // end of the string
Packit Service 360c39
Packit Service 360c39
			*(p+1)='\0';
Packit Service 360c39
			while (insert && p > &string[runningy-y]) {
Packit Service 360c39
				*p=*(p-1);
Packit Service 360c39
				p--;
Packit Service 360c39
			}
Packit Service 360c39
			string[runningy-y]=*ch;
Packit Service 360c39
			runningy++;
Packit Service 360c39
			move(x,y);
Packit Service 360c39
			addstr(string);
Packit Service 360c39
			if (runningy-y >= sz) {
Packit Service 360c39
				rc=1;
Packit Service 360c39
				*ch = KEY_RIGHT;
Packit Service 360c39
				done = TRUE;
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
		else {
Packit Service 360c39
			// special character, is it one we recognize?
Packit Service 360c39
			switch(*ch)
Packit Service 360c39
			{
Packit Service 360c39
			case(KEY_ENTER):
Packit Service 360c39
			case('\n'):
Packit Service 360c39
			case('\r'):
Packit Service 360c39
				rc=1;
Packit Service 360c39
				done=TRUE;
Packit Service 360c39
				string[runningy-y] = '\0';
Packit Service 360c39
				break;
Packit Service 360c39
			case(KEY_CANCEL):
Packit Service 360c39
			case(0x01B):
Packit Service 360c39
				rc=0;
Packit Service 360c39
				done=TRUE;
Packit Service 360c39
				break;
Packit Service 360c39
			case(KEY_LEFT):
Packit Service 360c39
				if (dmode == HEX_MODE) {
Packit Service 360c39
					done = TRUE;
Packit Service 360c39
					rc = 1;
Packit Service 360c39
				}
Packit Service 360c39
				else
Packit Service 360c39
					runningy--;
Packit Service 360c39
				break;
Packit Service 360c39
			case(KEY_RIGHT):
Packit Service 360c39
				if (dmode == HEX_MODE) {
Packit Service 360c39
					done = TRUE;
Packit Service 360c39
					rc = 1;
Packit Service 360c39
				}
Packit Service 360c39
				else
Packit Service 360c39
					runningy++;
Packit Service 360c39
				break;
Packit Service 360c39
			case(KEY_DC):
Packit Service 360c39
			case(0x07F):
Packit Service 360c39
				if (runningy>=y) {
Packit Service 360c39
					char *p;
Packit Service 360c39
					p = &string[runningy - y];
Packit Service 360c39
					while (*p) {
Packit Service 360c39
						*p = *(p + 1);
Packit Service 360c39
						p++;
Packit Service 360c39
					}
Packit Service 360c39
					*p = '\0';
Packit Service 360c39
					runningy--;
Packit Service 360c39
					// remove the character from the string 
Packit Service 360c39
					move(x,y);
Packit Service 360c39
					addstr(string);
Packit Service 360c39
					COLORS_NORMAL;
Packit Service 360c39
					addstr(" ");
Packit Service 360c39
					COLORS_INVERSE;
Packit Service 360c39
					runningy++;
Packit Service 360c39
				}
Packit Service 360c39
				break;
Packit Service 360c39
			case(KEY_BACKSPACE):
Packit Service 360c39
				if (runningy>y) {
Packit Service 360c39
					char *p;
Packit Service 360c39
Packit Service 360c39
					p = &string[runningy - y - 1];
Packit Service 360c39
					while (*p) {
Packit Service 360c39
						*p = *(p + 1);
Packit Service 360c39
						p++;
Packit Service 360c39
					}
Packit Service 360c39
					*p='\0';
Packit Service 360c39
					runningy--;
Packit Service 360c39
					// remove the character from the string 
Packit Service 360c39
					move(x,y);
Packit Service 360c39
					addstr(string);
Packit Service 360c39
					COLORS_NORMAL;
Packit Service 360c39
					addstr(" ");
Packit Service 360c39
					COLORS_INVERSE;
Packit Service 360c39
				}
Packit Service 360c39
				break;
Packit Service 360c39
			case KEY_DOWN:	// Down
Packit Service 360c39
				rc=0x5000U;
Packit Service 360c39
				done=TRUE;
Packit Service 360c39
				break;
Packit Service 360c39
			case KEY_UP:	// Up
Packit Service 360c39
				rc=0x4800U;
Packit Service 360c39
				done=TRUE;
Packit Service 360c39
				break;
Packit Service 360c39
			case 0x014b:
Packit Service 360c39
				insert=!insert;
Packit Service 360c39
				move(0,68);
Packit Service 360c39
				if (insert)
Packit Service 360c39
					printw("insert ");
Packit Service 360c39
				else
Packit Service 360c39
					printw("replace");
Packit Service 360c39
				break;
Packit Service 360c39
			default:
Packit Service 360c39
				move(0,70);
Packit Service 360c39
				printw("%08x",*ch);
Packit Service 360c39
				// ignore all other characters
Packit Service 360c39
				break;
Packit Service 360c39
			} // end switch on non-printable character
Packit Service 360c39
		} // end non-printable character
Packit Service 360c39
		move(x,runningy);
Packit Service 360c39
		refresh();
Packit Service 360c39
	} // while !done
Packit Service 360c39
	if (sz>0)
Packit Service 360c39
		string[sz]='\0';
Packit Service 360c39
	COLORS_NORMAL;
Packit Service 360c39
	return rc;
Packit Service 360c39
}/* bobgets */
Packit Service 360c39
Packit Service 360c39
/******************************************************************************
Packit Service 360c39
** instr - instructions
Packit Service 360c39
******************************************************************************/
Packit Service 360c39
static void gfs2instr(const char *s1, const char *s2)
Packit Service 360c39
{
Packit Service 360c39
	COLORS_HIGHLIGHT;
Packit Service 360c39
	move(line,0);
Packit Service 360c39
	printw(s1);
Packit Service 360c39
	COLORS_NORMAL;
Packit Service 360c39
	move(line,17);
Packit Service 360c39
	printw(s2);
Packit Service 360c39
	line++;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/******************************************************************************
Packit Service 360c39
*******************************************************************************
Packit Service 360c39
**
Packit Service 360c39
** void print_usage()
Packit Service 360c39
**
Packit Service 360c39
** Description:
Packit Service 360c39
**   This routine prints out the appropriate commands for this application.
Packit Service 360c39
**
Packit Service 360c39
*******************************************************************************
Packit Service 360c39
******************************************************************************/
Packit Service 360c39
Packit Service 360c39
static void print_usage(void)
Packit Service 360c39
{
Packit Service 360c39
	int ch;
Packit Service 360c39
Packit Service 360c39
	line = 2;
Packit Service 360c39
	Erase();
Packit Service 360c39
	display_title_lines();
Packit Service 360c39
	move(line++,0);
Packit Service 360c39
	printw("Supported commands: (roughly conforming to the rules of 'less')");
Packit Service 360c39
	line++;
Packit Service 360c39
	move(line++,0);
Packit Service 360c39
	printw("Navigation:");
Packit Service 360c39
	gfs2instr("<pg up>/<down>","Move up or down one screen full");
Packit Service 360c39
	gfs2instr("<up>/<down>","Move up or down one line");
Packit Service 360c39
	gfs2instr("<left>/<right>","Move left or right one byte");
Packit Service 360c39
	gfs2instr("<home>","Return to the superblock.");
Packit Service 360c39
	gfs2instr("   f","Forward one 4K block");
Packit Service 360c39
	gfs2instr("   b","Backward one 4K block");
Packit Service 360c39
	gfs2instr("   g","Goto a given block (number, master, root, rindex, jindex, etc)");
Packit Service 360c39
	gfs2instr("   j","Jump to the highlighted 64-bit block number.");
Packit Service 360c39
	gfs2instr("    ","(You may also arrow up to the block number and hit enter)");
Packit Service 360c39
	gfs2instr("<backspace>","Return to a previous block (a block stack is kept)");
Packit Service 360c39
	gfs2instr("<space>","Jump forward to block before backspace (opposite of backspace)");
Packit Service 360c39
	line++;
Packit Service 360c39
	move(line++, 0);
Packit Service 360c39
	printw("Other commands:");
Packit Service 360c39
	gfs2instr("   h","This Help display");
Packit Service 360c39
	gfs2instr("   c","Toggle the color scheme");
Packit Service 360c39
	gfs2instr("   m","Switch display mode: hex -> GFS2 structure -> Extended");
Packit Service 360c39
	gfs2instr("   q","Quit (same as hitting <escape> key)");
Packit Service 360c39
	gfs2instr("<enter>","Edit a value (enter to save, esc to discard)");
Packit Service 360c39
	gfs2instr("       ","(Currently only works on the hex display)");
Packit Service 360c39
	gfs2instr("<escape>","Quit the program");
Packit Service 360c39
	line++;
Packit Service 360c39
	move(line++, 0);
Packit Service 360c39
	printw("Notes: Areas shown in red are outside the bounds of the struct/file.");
Packit Service 360c39
	move(line++, 0);
Packit Service 360c39
	printw("       Areas shown in blue are file contents.");
Packit Service 360c39
	move(line++, 0);
Packit Service 360c39
	printw("       Characters shown in green are selected for edit on <enter>.");
Packit Service 360c39
	move(line++, 0);
Packit Service 360c39
	move(line++, 0);
Packit Service 360c39
	printw("Press any key to return.");
Packit Service 360c39
	refresh();
Packit Service 360c39
	while ((ch=getch()) == 0); // wait for input
Packit Service 360c39
	Erase();
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* get_block_type                                                           */
Packit Service 360c39
/* returns: metatype if block is a GFS2 structure block type                */
Packit Service 360c39
/*          0 if block is not a GFS2 structure                              */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
uint32_t get_block_type(const struct gfs2_buffer_head *lbh, int *structlen)
Packit Service 360c39
{
Packit Service 360c39
	uint32_t ty = lgfs2_get_block_type(lbh);
Packit Service 360c39
Packit Service 360c39
	if (ty != 0 && structlen != NULL) {
Packit Service 360c39
		unsigned ver = sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2;
Packit Service 360c39
		const struct lgfs2_metadata *mtype = lgfs2_find_mtype(ty, ver);
Packit Service 360c39
		if (mtype != NULL)
Packit Service 360c39
			*structlen = mtype->size;
Packit Service 360c39
		else
Packit Service 360c39
			*structlen = sbd.bsize;
Packit Service 360c39
	}
Packit Service 360c39
	return ty;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* display_block_type                                                       */
Packit Service 360c39
/* returns: metatype if block is a GFS2 structure block type                */
Packit Service 360c39
/*          0 if block is not a GFS2 structure                              */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
int display_block_type(struct gfs2_buffer_head *dbh, int from_restore)
Packit Service 360c39
{
Packit Service 360c39
	const struct gfs2_meta_header *mh;
Packit Service 360c39
	int ret_type = 0; /* return type */
Packit Service 360c39
Packit Service 360c39
	/* first, print out the kind of GFS2 block this is */
Packit Service 360c39
	if (termlines) {
Packit Service 360c39
		line = 1;
Packit Service 360c39
		move(line, 0);
Packit Service 360c39
	}
Packit Service 360c39
	print_gfs2("Block #");
Packit Service 360c39
	if (termlines) {
Packit Service 360c39
		if (edit_row[dmode] == -1)
Packit Service 360c39
			COLORS_HIGHLIGHT;
Packit Service 360c39
	}
Packit Service 360c39
	if (block == RGLIST_DUMMY_BLOCK)
Packit Service 360c39
		print_gfs2("RG List       ");
Packit Service 360c39
	else if (block == JOURNALS_DUMMY_BLOCK)
Packit Service 360c39
		print_gfs2("Journal Status:      ");
Packit Service 360c39
	else
Packit Service 360c39
		print_gfs2("%"PRIu64"    (0x%"PRIx64")", dbh->b_blocknr, dbh->b_blocknr);
Packit Service 360c39
	if (termlines) {
Packit Service 360c39
		if (edit_row[dmode] == -1)
Packit Service 360c39
			COLORS_NORMAL;
Packit Service 360c39
	}
Packit Service 360c39
	print_gfs2(" ");
Packit Service 360c39
	if (!from_restore)
Packit Service 360c39
		print_gfs2("of %"PRIu64" (0x%"PRIx64") ", max_block, max_block);
Packit Service 360c39
	if (block == RGLIST_DUMMY_BLOCK) {
Packit Service 360c39
		ret_type = GFS2_METATYPE_RG;
Packit Service 360c39
		struct_len = sbd.gfs1 ? sizeof(struct gfs_rgrp) :
Packit Service 360c39
			sizeof(struct gfs2_rgrp);
Packit Service 360c39
	} else if (block == JOURNALS_DUMMY_BLOCK) {
Packit Service 360c39
		ret_type = GFS2_METATYPE_DI;
Packit Service 360c39
		struct_len = 0;
Packit Service 360c39
	} else {
Packit Service 360c39
		ret_type = get_block_type(dbh, &struct_len);
Packit Service 360c39
		switch (ret_type) {
Packit Service 360c39
		case GFS2_METATYPE_SB:   /* 1 */
Packit Service 360c39
			print_gfs2("(superblock)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_RG:   /* 2 */
Packit Service 360c39
			print_gfs2("(rsrc grp hdr)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_RB:   /* 3 */
Packit Service 360c39
			print_gfs2("(rsrc grp bitblk)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_DI:   /* 4 */
Packit Service 360c39
			print_gfs2("(disk inode)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_IN:   /* 5 */
Packit Service 360c39
			print_gfs2("(indir blklist)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_LF:   /* 6 */
Packit Service 360c39
			print_gfs2("(directory leaf)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_JD:
Packit Service 360c39
			print_gfs2("(journal data)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_LH:
Packit Service 360c39
			print_gfs2("(log header)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_LD:
Packit Service 360c39
		 	print_gfs2("(log descriptor)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_EA:
Packit Service 360c39
			print_gfs2("(extended attr hdr)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_ED:
Packit Service 360c39
			print_gfs2("(extended attr data)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_LB:
Packit Service 360c39
			print_gfs2("(log buffer)");
Packit Service 360c39
			break;
Packit Service 360c39
		case GFS2_METATYPE_QC:
Packit Service 360c39
			print_gfs2("(quota change)");
Packit Service 360c39
			break;
Packit Service 360c39
		case 0:
Packit Service 360c39
			struct_len = sbd.bsize;
Packit Service 360c39
			break;
Packit Service 360c39
		default:
Packit Service 360c39
			print_gfs2("(wtf?)");
Packit Service 360c39
			break;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	mh = dbh->iov.iov_base;
Packit Service 360c39
	eol(0);
Packit Service 360c39
	if (from_restore)
Packit Service 360c39
		return ret_type;
Packit Service 360c39
	if (termlines && dmode == HEX_MODE) {
Packit Service 360c39
		int type;
Packit Service 360c39
		struct rgrp_tree *rgd;
Packit Service 360c39
Packit Service 360c39
		rgd = gfs2_blk2rgrpd(&sbd, block);
Packit Service 360c39
		if (rgd) {
Packit Service 360c39
			gfs2_rgrp_read(&sbd, rgd);
Packit Service 360c39
			if ((be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG) ||
Packit Service 360c39
			    (be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RB))
Packit Service 360c39
				type = 4;
Packit Service 360c39
			else {
Packit Service 360c39
				type = lgfs2_get_bitmap(&sbd, block, rgd);
Packit Service 360c39
			}
Packit Service 360c39
		} else
Packit Service 360c39
			type = 4;
Packit Service 360c39
		screen_chunk_size = ((termlines - 4) * 16) >> 8 << 8;
Packit Service 360c39
		if (!screen_chunk_size)
Packit Service 360c39
			screen_chunk_size = 256;
Packit Service 360c39
		pgnum = (offset / screen_chunk_size);
Packit Service 360c39
		if (type >= 0) {
Packit Service 360c39
			print_gfs2("(p.%d of %d--%s)", pgnum + 1,
Packit Service 360c39
				   (sbd.bsize % screen_chunk_size) > 0 ?
Packit Service 360c39
				   sbd.bsize / screen_chunk_size + 1 : sbd.bsize /
Packit Service 360c39
				   screen_chunk_size, allocdesc[sbd.gfs1][type]);
Packit Service 360c39
		}
Packit Service 360c39
		/*eol(9);*/
Packit Service 360c39
		if ((be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG)) {
Packit Service 360c39
			int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
Packit Service 360c39
Packit Service 360c39
			if (rgd && (ptroffset >= struct_len || pgnum)) {
Packit Service 360c39
				int blknum, b, btype;
Packit Service 360c39
Packit Service 360c39
				blknum = pgnum * screen_chunk_size;
Packit Service 360c39
				blknum += (ptroffset - struct_len);
Packit Service 360c39
				blknum *= 4;
Packit Service 360c39
				blknum += rgd->ri.ri_data0;
Packit Service 360c39
Packit Service 360c39
				print_gfs2(" blk ");
Packit Service 360c39
				for (b = blknum; b < blknum + 4; b++) {
Packit Service 360c39
					btype = lgfs2_get_bitmap(&sbd, b, rgd);
Packit Service 360c39
					if (btype >= 0) {
Packit Service 360c39
						print_gfs2("0x%x-%s  ", b,
Packit Service 360c39
							   allocdesc[sbd.gfs1][btype]);
Packit Service 360c39
					}
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
		} else if ((be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RB)) {
Packit Service 360c39
			int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
Packit Service 360c39
Packit Service 360c39
			if (rgd && (ptroffset >= struct_len || pgnum)) {
Packit Service 360c39
				int blknum, b, btype, rb_number;
Packit Service 360c39
Packit Service 360c39
				rb_number = block - rgd->ri.ri_addr;
Packit Service 360c39
				blknum = 0;
Packit Service 360c39
				/* count the number of bytes representing
Packit Service 360c39
				   blocks prior to the displayed screen. */
Packit Service 360c39
				for (b = 0; b < rb_number; b++) {
Packit Service 360c39
					struct_len = (b ?
Packit Service 360c39
					      sizeof(struct gfs2_meta_header) :
Packit Service 360c39
					      sizeof(struct gfs2_rgrp));
Packit Service 360c39
					blknum += (sbd.bsize - struct_len);
Packit Service 360c39
				}
Packit Service 360c39
				struct_len = sizeof(struct gfs2_meta_header);
Packit Service 360c39
				/* add the number of bytes on this screen */
Packit Service 360c39
				blknum += (ptroffset - struct_len);
Packit Service 360c39
				/* factor in the page number */
Packit Service 360c39
				blknum += pgnum * screen_chunk_size;
Packit Service 360c39
				/* convert bytes to blocks */
Packit Service 360c39
				blknum *= GFS2_NBBY;
Packit Service 360c39
				/* add the starting offset for this rgrp */
Packit Service 360c39
				blknum += rgd->ri.ri_data0;
Packit Service 360c39
				print_gfs2(" blk ");
Packit Service 360c39
				for (b = blknum; b < blknum + 4; b++) {
Packit Service 360c39
					btype = lgfs2_get_bitmap(&sbd, b, rgd);
Packit Service 360c39
					if (btype >= 0) {
Packit Service 360c39
						print_gfs2("0x%x-%s  ", b,
Packit Service 360c39
							   allocdesc[sbd.gfs1][btype]);
Packit Service 360c39
					}
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
		if (rgd)
Packit Service 360c39
			gfs2_rgrp_relse(rgd);
Packit Service 360c39
 	}
Packit Service 360c39
	if (block == sbd.sd_sb.sb_root_dir.no_addr)
Packit Service 360c39
		print_gfs2("--------------- Root directory ------------------");
Packit Service 360c39
	else if (!sbd.gfs1 && block == sbd.sd_sb.sb_master_dir.no_addr)
Packit Service 360c39
		print_gfs2("-------------- Master directory -----------------");
Packit Service 360c39
	else if (!sbd.gfs1 && block == RGLIST_DUMMY_BLOCK)
Packit Service 360c39
		print_gfs2("------------------ RG List ----------------------");
Packit Service 360c39
	else if (!sbd.gfs1 && block == JOURNALS_DUMMY_BLOCK)
Packit Service 360c39
		print_gfs2("-------------------- Journal List --------------------");
Packit Service 360c39
	else {
Packit Service 360c39
		if (sbd.gfs1) {
Packit Service 360c39
			if (block == sbd1->sb_rindex_di.no_addr)
Packit Service 360c39
				print_gfs2("---------------- rindex file -------------------");
Packit Service 360c39
			else if (block == gfs1_quota_di.no_addr)
Packit Service 360c39
				print_gfs2("---------------- Quota file --------------------");
Packit Service 360c39
			else if (block == sbd1->sb_jindex_di.no_addr)
Packit Service 360c39
				print_gfs2("--------------- Journal Index ------------------");
Packit Service 360c39
			else if (block == gfs1_license_di.no_addr)
Packit Service 360c39
				print_gfs2("--------------- License file -------------------");
Packit Service 360c39
		}
Packit Service 360c39
		else {
Packit Service 360c39
			int d;
Packit Service 360c39
Packit Service 360c39
			for (d = 2; d < 8; d++) {
Packit Service 360c39
				if (block == masterdir.dirent[d].block) {
Packit Service 360c39
					if (!strncmp(masterdir.dirent[d].filename, "jindex", 6))
Packit Service 360c39
						print_gfs2("--------------- Journal Index ------------------");
Packit Service 360c39
					else if (!strncmp(masterdir.dirent[d].filename, "per_node", 8))
Packit Service 360c39
						print_gfs2("--------------- Per-node Dir -------------------");
Packit Service 360c39
					else if (!strncmp(masterdir.dirent[d].filename, "inum", 4))
Packit Service 360c39
						print_gfs2("---------------- Inum file ---------------------");
Packit Service 360c39
					else if (!strncmp(masterdir.dirent[d].filename, "statfs", 6))
Packit Service 360c39
						print_gfs2("---------------- statfs file -------------------");
Packit Service 360c39
					else if (!strncmp(masterdir.dirent[d].filename, "rindex", 6))
Packit Service 360c39
						print_gfs2("---------------- rindex file -------------------");
Packit Service 360c39
					else if (!strncmp(masterdir.dirent[d].filename, "quota", 5))
Packit Service 360c39
						print_gfs2("---------------- Quota file --------------------");
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	eol(0);
Packit Service 360c39
	return ret_type;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static const struct lgfs2_metadata *find_mtype(uint32_t mtype, const unsigned versions)
Packit Service 360c39
{
Packit Service 360c39
	const struct lgfs2_metadata *m = lgfs2_metadata;
Packit Service 360c39
	unsigned n = 0;
Packit Service 360c39
Packit Service 360c39
	do {
Packit Service 360c39
		if ((m[n].versions & versions) && m[n].mh_type == mtype)
Packit Service 360c39
			return &m[n];
Packit Service 360c39
		n++;
Packit Service 360c39
	} while (n < lgfs2_metadata_size);
Packit Service 360c39
Packit Service 360c39
	return NULL;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int get_pnum(int ptroffset)
Packit Service 360c39
{
Packit Service 360c39
	int pnum;
Packit Service 360c39
Packit Service 360c39
	pnum = pgnum * screen_chunk_size;
Packit Service 360c39
	pnum += (ptroffset - struct_len);
Packit Service 360c39
	pnum /= sizeof(uint64_t);
Packit Service 360c39
Packit Service 360c39
	return pnum;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* hexdump - hex dump the filesystem block to the screen                    */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static int hexdump(uint64_t startaddr, int len, int trunc_zeros,
Packit Service 360c39
		   uint64_t flagref, uint64_t ref_blk)
Packit Service 360c39
{
Packit Service 360c39
	const unsigned char *pointer, *ptr2;
Packit Service 360c39
	int i;
Packit Service 360c39
	uint64_t l;
Packit Service 360c39
	const char *lpBuffer = bh->b_data;
Packit Service 360c39
	const char *zeros_strt = lpBuffer + sbd.bsize;
Packit Service 360c39
	int print_field, cursor_line;
Packit Service 360c39
	const uint32_t block_type = get_block_type(bh, NULL);
Packit Service 360c39
	uint64_t *ref;
Packit Service 360c39
	int ptroffset = 0;
Packit Service 360c39
Packit Service 360c39
	strcpy(edit_fmt,"%02x");
Packit Service 360c39
	pointer = (unsigned char *)lpBuffer + offset;
Packit Service 360c39
	ptr2 = (unsigned char *)lpBuffer + offset;
Packit Service 360c39
	ref = (uint64_t *)lpBuffer + offset;
Packit Service 360c39
	if (trunc_zeros) {
Packit Service 360c39
		while (zeros_strt > lpBuffer && (*(zeros_strt - 1) == 0))
Packit Service 360c39
			zeros_strt--;
Packit Service 360c39
	}
Packit Service 360c39
	l = offset;
Packit Service 360c39
	print_entry_ndx = 0;
Packit Service 360c39
	while (((termlines && line < termlines &&
Packit Service 360c39
		 line <= ((screen_chunk_size / 16) + 2)) ||
Packit Service 360c39
		(!termlines && l < len)) && l < sbd.bsize) {
Packit Service 360c39
		int ptr_not_null = 0;
Packit Service 360c39
Packit Service 360c39
		if (termlines) {
Packit Service 360c39
			move(line, 0);
Packit Service 360c39
			COLORS_OFFSETS; /* cyan for offsets */
Packit Service 360c39
		}
Packit Service 360c39
		if (startaddr < 0xffffffff)
Packit Service 360c39
			print_gfs2("%.8"PRIx64, startaddr + l);
Packit Service 360c39
		else
Packit Service 360c39
			print_gfs2("%.16"PRIx64, startaddr + l);
Packit Service 360c39
		if (termlines) {
Packit Service 360c39
			if (l < struct_len)
Packit Service 360c39
				COLORS_NORMAL; /* normal part of structure */
Packit Service 360c39
			else if (gfs2_struct_type == GFS2_METATYPE_DI &&
Packit Service 360c39
					 l < struct_len + di.di_size)
Packit Service 360c39
				COLORS_CONTENTS; /* after struct but not eof */
Packit Service 360c39
			else
Packit Service 360c39
				COLORS_SPECIAL; /* beyond end of the struct */
Packit Service 360c39
		}
Packit Service 360c39
		print_field = -1;
Packit Service 360c39
		cursor_line = 0;
Packit Service 360c39
		for (i = 0; i < 16; i++) { /* first print it in hex */
Packit Service 360c39
			/* Figure out if we have a null pointer--for colors */
Packit Service 360c39
			if (((gfs2_struct_type == GFS2_METATYPE_IN) ||
Packit Service 360c39
			     (gfs2_struct_type == GFS2_METATYPE_DI &&
Packit Service 360c39
			      l < struct_len + di.di_size &&
Packit Service 360c39
			      (di.di_height > 0 || !S_ISREG(di.di_mode)))) &&
Packit Service 360c39
			    (i==0 || i==8)) {
Packit Service 360c39
				int j;
Packit Service 360c39
Packit Service 360c39
				ptr_not_null = 0;
Packit Service 360c39
				for (j = 0; j < 8; j++) {
Packit Service 360c39
					if (*(pointer + j)) {
Packit Service 360c39
						ptr_not_null = 1;
Packit Service 360c39
						break;
Packit Service 360c39
					}
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
			if (termlines) {
Packit Service 360c39
				if (l + i < struct_len)
Packit Service 360c39
					COLORS_NORMAL; /* in the structure */
Packit Service 360c39
				else if (gfs2_struct_type == GFS2_METATYPE_DI
Packit Service 360c39
					 && l + i < struct_len + di.di_size) {
Packit Service 360c39
					if ((!di.di_height &&
Packit Service 360c39
					     S_ISREG(di.di_mode)) ||
Packit Service 360c39
					    !ptr_not_null)
Packit Service 360c39
						COLORS_CONTENTS;/*stuff data */
Packit Service 360c39
					else
Packit Service 360c39
						COLORS_SPECIAL;/* non-null */
Packit Service 360c39
				}
Packit Service 360c39
				else if (gfs2_struct_type == GFS2_METATYPE_IN){
Packit Service 360c39
					if (ptr_not_null)
Packit Service 360c39
						COLORS_SPECIAL;/* non-null */
Packit Service 360c39
					else
Packit Service 360c39
						COLORS_CONTENTS;/* null */
Packit Service 360c39
				} else
Packit Service 360c39
					COLORS_SPECIAL; /* past the struct */
Packit Service 360c39
			}
Packit Service 360c39
			if (i%4 == 0)
Packit Service 360c39
				print_gfs2(" ");
Packit Service 360c39
			if (termlines && line == edit_row[dmode] + 3 &&
Packit Service 360c39
				i == edit_col[dmode]) {
Packit Service 360c39
				COLORS_HIGHLIGHT; /* in the structure */
Packit Service 360c39
				memset(estring,0,3);
Packit Service 360c39
				sprintf(estring,"%02x",*pointer);
Packit Service 360c39
				cursor_line = 1;
Packit Service 360c39
				print_field = (char *)pointer - bh->b_data;
Packit Service 360c39
			}
Packit Service 360c39
			print_gfs2("%02x",*pointer);
Packit Service 360c39
			if (termlines && line == edit_row[dmode] + 3 &&
Packit Service 360c39
				i == edit_col[dmode]) {
Packit Service 360c39
				if (l < struct_len + offset)
Packit Service 360c39
					COLORS_NORMAL; /* in the structure */
Packit Service 360c39
				else
Packit Service 360c39
					COLORS_SPECIAL; /* beyond structure */
Packit Service 360c39
			}
Packit Service 360c39
			pointer++;
Packit Service 360c39
		}
Packit Service 360c39
		print_gfs2(" [");
Packit Service 360c39
		for (i=0; i<16; i++) { /* now print it in character format */
Packit Service 360c39
			if ((*ptr2 >=' ') && (*ptr2 <= '~'))
Packit Service 360c39
				print_gfs2("%c",*ptr2);
Packit Service 360c39
			else
Packit Service 360c39
				print_gfs2(".");
Packit Service 360c39
			ptr2++;
Packit Service 360c39
		}
Packit Service 360c39
		print_gfs2("] ");
Packit Service 360c39
		if (print_field >= 0) {
Packit Service 360c39
			const struct lgfs2_metadata *m = find_mtype(block_type,
Packit Service 360c39
			               sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2);
Packit Service 360c39
			if (m) {
Packit Service 360c39
				const struct lgfs2_metafield *f;
Packit Service 360c39
				unsigned n;
Packit Service 360c39
				for (n = 0; n < m->nfields; n++) {
Packit Service 360c39
					f = &m->fields[n];
Packit Service 360c39
					if (print_field >= f->offset &&
Packit Service 360c39
					    print_field < (f->offset + f->length)) {
Packit Service 360c39
						print_gfs2("%s", m->fields[n].name);
Packit Service 360c39
						break;
Packit Service 360c39
					}
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
Packit Service 360c39
		}
Packit Service 360c39
		if (cursor_line) {
Packit Service 360c39
			if (block_type == GFS2_METATYPE_IN ||
Packit Service 360c39
			    block_type == GFS2_METATYPE_LD ||
Packit Service 360c39
			    ((block_type == GFS2_METATYPE_DI) &&
Packit Service 360c39
			     ((struct gfs2_dinode*)bh->b_data)->di_height) ||
Packit Service 360c39
			     S_ISDIR(di.di_mode)) {
Packit Service 360c39
				ptroffset = edit_row[dmode] * 16 +
Packit Service 360c39
					edit_col[dmode];
Packit Service 360c39
Packit Service 360c39
				if (ptroffset >= struct_len || pgnum) {
Packit Service 360c39
					int pnum = get_pnum(ptroffset);
Packit Service 360c39
					if (block_type == GFS2_METATYPE_LD)
Packit Service 360c39
						print_gfs2("*");
Packit Service 360c39
					print_gfs2("pointer 0x%x", pnum);
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
		if (line - 3 > last_entry_onscreen[dmode])
Packit Service 360c39
			last_entry_onscreen[dmode] = line - 3;
Packit Service 360c39
		if (flagref && be64_to_cpu(*ref) == flagref)
Packit Service 360c39
			print_gfs2("<------------------------- ref in 0x%"PRIx64" "
Packit Service 360c39
				   "to 0x%"PRIx64, ref_blk, flagref);
Packit Service 360c39
		ref++;
Packit Service 360c39
		if (flagref && be64_to_cpu(*ref) == flagref)
Packit Service 360c39
			print_gfs2("<------------------------- ref in 0x%"PRIx64" "
Packit Service 360c39
				   "to 0x%"PRIx64, ref_blk, flagref);
Packit Service 360c39
		ref++;
Packit Service 360c39
		eol(0);
Packit Service 360c39
		l += 16;
Packit Service 360c39
		print_entry_ndx++;
Packit Service 360c39
		/* This should only happen if trunc_zeros is specified: */
Packit Service 360c39
		if ((const char *)pointer >= zeros_strt)
Packit Service 360c39
			break;
Packit Service 360c39
	} /* while */
Packit Service 360c39
	if (block_type == GFS2_METATYPE_LD && ptroffset >= struct_len) {
Packit Service 360c39
		COLORS_NORMAL;
Packit Service 360c39
		eol(0);
Packit Service 360c39
		print_gfs2("         * 'j' will jump to the journaled block, "
Packit Service 360c39
			   "not the absolute block.");
Packit Service 360c39
		eol(0);
Packit Service 360c39
	}
Packit Service 360c39
	if (sbd.gfs1) {
Packit Service 360c39
		COLORS_NORMAL;
Packit Service 360c39
		print_gfs2("         *** This seems to be a GFS-1 file system ***");
Packit Service 360c39
		eol(0);
Packit Service 360c39
	}
Packit Service 360c39
	return (offset+len);
Packit Service 360c39
}/* hexdump */
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* masterblock - find a file (by name) in the master directory and return   */
Packit Service 360c39
/*               its block number.                                          */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
uint64_t masterblock(const char *fn)
Packit Service 360c39
{
Packit Service 360c39
	int d;
Packit Service 360c39
	
Packit Service 360c39
	for (d = 2; d < 8; d++)
Packit Service 360c39
		if (!strncmp(masterdir.dirent[d].filename, fn, strlen(fn)))
Packit Service 360c39
			return (masterdir.dirent[d].block);
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* rgcount - return how many rgrps there are.                               */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void rgcount(void)
Packit Service 360c39
{
Packit Service 360c39
	printf("%lld RGs in this file system.\n",
Packit Service 360c39
	       (unsigned long long)sbd.md.riinode->i_di.di_size /
Packit Service 360c39
	       sizeof(struct gfs2_rindex));
Packit Service 360c39
	inode_put(&sbd.md.riinode);
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
	exit(EXIT_SUCCESS);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* find_rgrp_block - locate the block for a given rgrp number               */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t find_rgrp_block(struct gfs2_inode *dif, int rg)
Packit Service 360c39
{
Packit Service 360c39
	int amt;
Packit Service 360c39
	struct gfs2_rindex fbuf, ri;
Packit Service 360c39
	uint64_t foffset, gfs1_adj = 0;
Packit Service 360c39
Packit Service 360c39
	foffset = rg * sizeof(struct gfs2_rindex);
Packit Service 360c39
	if (sbd.gfs1) {
Packit Service 360c39
		uint64_t sd_jbsize =
Packit Service 360c39
			(sbd.bsize - sizeof(struct gfs2_meta_header));
Packit Service 360c39
Packit Service 360c39
		gfs1_adj = (foffset / sd_jbsize) *
Packit Service 360c39
			sizeof(struct gfs2_meta_header);
Packit Service 360c39
		gfs1_adj += sizeof(struct gfs2_meta_header);
Packit Service 360c39
	}
Packit Service 360c39
	amt = gfs2_readi(dif, (void *)&fbuf, foffset + gfs1_adj,
Packit Service 360c39
			 sizeof(struct gfs2_rindex));
Packit Service 360c39
	if (!amt) /* end of file */
Packit Service 360c39
		return 0;
Packit Service 360c39
	gfs2_rindex_in(&ri, (void *)&fbuf);
Packit Service 360c39
	return ri.ri_addr;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* gfs_rgrp_print - print a gfs1 resource group                             */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
void gfs_rgrp_print(struct gfs_rgrp *rg)
Packit Service 360c39
{
Packit Service 360c39
	gfs2_meta_header_print(&rg->rg_header);
Packit Service 360c39
	pv(rg, rg_flags, "%u", "0x%x");
Packit Service 360c39
	pv(rg, rg_free, "%u", "0x%x");
Packit Service 360c39
	pv(rg, rg_useddi, "%u", "0x%x");
Packit Service 360c39
	pv(rg, rg_freedi, "%u", "0x%x");
Packit Service 360c39
	gfs2_inum_print(&rg->rg_freedi_list);
Packit Service 360c39
	pv(rg, rg_usedmeta, "%u", "0x%x");
Packit Service 360c39
	pv(rg, rg_freemeta, "%u", "0x%x");
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* get_rg_addr                                                              */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t get_rg_addr(int rgnum)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t rgblk = 0, gblock;
Packit Service 360c39
	struct gfs2_inode *riinode;
Packit Service 360c39
Packit Service 360c39
	if (sbd.gfs1)
Packit Service 360c39
		gblock = sbd1->sb_rindex_di.no_addr;
Packit Service 360c39
	else
Packit Service 360c39
		gblock = masterblock("rindex");
Packit Service 360c39
	riinode = lgfs2_inode_read(&sbd, gblock);
Packit Service 360c39
	if (riinode == NULL)
Packit Service 360c39
		return 0;
Packit Service 360c39
	if (rgnum < riinode->i_di.di_size / sizeof(struct gfs2_rindex))
Packit Service 360c39
		rgblk = find_rgrp_block(riinode, rgnum);
Packit Service 360c39
	else
Packit Service 360c39
		fprintf(stderr, "Error: File system only has %lld RGs.\n",
Packit Service 360c39
			(unsigned long long)riinode->i_di.di_size /
Packit Service 360c39
			sizeof(struct gfs2_rindex));
Packit Service 360c39
	inode_put(&riinode);
Packit Service 360c39
	return rgblk;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* set_rgrp_flags - Set an rgrp's flags to a given value                    */
Packit Service 360c39
/* rgnum: which rg to print or modify flags for (0 - X)                     */
Packit Service 360c39
/* new_flags: value to set new rg_flags to (if modify == TRUE)              */
Packit Service 360c39
/* modify: TRUE if the value is to be modified, FALSE if it's to be printed */
Packit Service 360c39
/* full: TRUE if the full RG should be printed.                             */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void set_rgrp_flags(int rgnum, uint32_t new_flags, int modify, int full)
Packit Service 360c39
{
Packit Service 360c39
	union {
Packit Service 360c39
		struct gfs2_rgrp rg2;
Packit Service 360c39
		struct gfs_rgrp rg1;
Packit Service 360c39
	} rg;
Packit Service 360c39
	struct gfs2_buffer_head *rbh;
Packit Service 360c39
	uint64_t rgblk;
Packit Service 360c39
Packit Service 360c39
	rgblk = get_rg_addr(rgnum);
Packit Service 360c39
	rbh = bread(&sbd, rgblk);
Packit Service 360c39
	if (sbd.gfs1)
Packit Service 360c39
		gfs_rgrp_in(&rg.rg1, rbh);
Packit Service 360c39
	else
Packit Service 360c39
		gfs2_rgrp_in(&rg.rg2, rbh->b_data);
Packit Service 360c39
	if (modify) {
Packit Service 360c39
		printf("RG #%d (block %llu / 0x%llx) rg_flags changed from 0x%08x to 0x%08x\n",
Packit Service 360c39
		       rgnum, (unsigned long long)rgblk,
Packit Service 360c39
		       (unsigned long long)rgblk, rg.rg2.rg_flags, new_flags);
Packit Service 360c39
		rg.rg2.rg_flags = new_flags;
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			gfs_rgrp_out(&rg.rg1, rbh);
Packit Service 360c39
		else
Packit Service 360c39
			gfs2_rgrp_out(&rg.rg2, rbh->b_data);
Packit Service 360c39
		bmodified(rbh);
Packit Service 360c39
		brelse(rbh);
Packit Service 360c39
	} else {
Packit Service 360c39
		if (full) {
Packit Service 360c39
			print_gfs2("RG #%d", rgnum);
Packit Service 360c39
			print_gfs2(" located at: %"PRIu64" (0x%"PRIx64")", rgblk, rgblk);
Packit Service 360c39
                        eol(0);
Packit Service 360c39
			if (sbd.gfs1)
Packit Service 360c39
				gfs_rgrp_print(&rg.rg1);
Packit Service 360c39
			else
Packit Service 360c39
				gfs2_rgrp_print(&rg.rg2);
Packit Service 360c39
		}
Packit Service 360c39
		else
Packit Service 360c39
			printf("RG #%d (block %llu / 0x%llx) rg_flags = 0x%08x\n",
Packit Service 360c39
			       rgnum, (unsigned long long)rgblk,
Packit Service 360c39
			       (unsigned long long)rgblk, rg.rg2.rg_flags);
Packit Service 360c39
		brelse(rbh);
Packit Service 360c39
	}
Packit Service 360c39
	if (modify)
Packit Service 360c39
		fsync(sbd.device_fd);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* has_indirect_blocks                                                      */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
int has_indirect_blocks(void)
Packit Service 360c39
{
Packit Service 360c39
	if (indirect_blocks || gfs2_struct_type == GFS2_METATYPE_SB ||
Packit Service 360c39
	    gfs2_struct_type == GFS2_METATYPE_LF ||
Packit Service 360c39
	    (gfs2_struct_type == GFS2_METATYPE_DI &&
Packit Service 360c39
	     (S_ISDIR(di.di_mode) || (sbd.gfs1 && di.__pad1 == GFS_FILE_DIR))))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int block_is_rindex(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	if ((sbd.gfs1 && blk == sbd1->sb_rindex_di.no_addr) ||
Packit Service 360c39
	    (blk == masterblock("rindex")))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int block_is_jindex(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	if ((sbd.gfs1 && blk == sbd1->sb_jindex_di.no_addr))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int block_is_inum_file(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	if (!sbd.gfs1 && blk == masterblock("inum"))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int block_is_statfs_file(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	if (sbd.gfs1 && blk == gfs1_license_di.no_addr)
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	if (!sbd.gfs1 && blk == masterblock("statfs"))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int block_is_quota_file(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	if (sbd.gfs1 && blk == gfs1_quota_di.no_addr)
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	if (!sbd.gfs1 && blk == masterblock("quota"))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int block_is_per_node(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	if (!sbd.gfs1 && blk == masterblock("per_node"))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* block_has_extended_info                                                  */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static int block_has_extended_info(void)
Packit Service 360c39
{
Packit Service 360c39
	if (has_indirect_blocks() ||
Packit Service 360c39
	    block_is_rindex(block) ||
Packit Service 360c39
	    block_is_rgtree(block) ||
Packit Service 360c39
	    block_is_journals(block) ||
Packit Service 360c39
	    block_is_jindex(block) ||
Packit Service 360c39
	    block_is_inum_file(block) ||
Packit Service 360c39
	    block_is_statfs_file(block) ||
Packit Service 360c39
	    block_is_quota_file(block))
Packit Service 360c39
		return TRUE;
Packit Service 360c39
	return FALSE;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void read_superblock(int fd)
Packit Service 360c39
{
Packit Service 360c39
	sbd1 = (struct gfs_sb *)&sbd.sd_sb;
Packit Service 360c39
	ioctl(fd, BLKFLSBUF, 0);
Packit Service 360c39
	memset(&sbd, 0, sizeof(struct gfs2_sbd));
Packit Service 360c39
	sbd.bsize = GFS2_DEFAULT_BSIZE;
Packit Service 360c39
	sbd.device_fd = fd;
Packit Service 360c39
	bh = bread(&sbd, 0x10);
Packit Service 360c39
	sbd.jsize = GFS2_DEFAULT_JSIZE;
Packit Service 360c39
	sbd.rgsize = GFS2_DEFAULT_RGSIZE;
Packit Service 360c39
	sbd.qcsize = GFS2_DEFAULT_QCSIZE;
Packit Service 360c39
	sbd.time = time(NULL);
Packit Service 360c39
	sbd.rgtree.osi_node = NULL;
Packit Service 360c39
	gfs2_sb_in(&sbd.sd_sb, bh->b_data);
Packit Service 360c39
	/* Check to see if this is really gfs1 */
Packit Service 360c39
	if (sbd1->sb_fs_format == GFS_FORMAT_FS &&
Packit Service 360c39
		sbd1->sb_header.mh_type == GFS_METATYPE_SB &&
Packit Service 360c39
		sbd1->sb_header.mh_format == GFS_FORMAT_SB &&
Packit Service 360c39
		sbd1->sb_multihost_format == GFS_FORMAT_MULTI) {
Packit Service 360c39
		struct gfs_sb *sbbuf = (struct gfs_sb *)bh->b_data;
Packit Service 360c39
Packit Service 360c39
		sbd.gfs1 = TRUE;
Packit Service 360c39
		sbd1->sb_flags = be32_to_cpu(sbbuf->sb_flags);
Packit Service 360c39
		sbd1->sb_seg_size = be32_to_cpu(sbbuf->sb_seg_size);
Packit Service 360c39
		gfs2_inum_in(&sbd1->sb_rindex_di, (void *)&sbbuf->sb_rindex_di);
Packit Service 360c39
		gfs2_inum_in(&gfs1_quota_di, (void *)&sbbuf->sb_quota_di);
Packit Service 360c39
		gfs2_inum_in(&gfs1_license_di, (void *)&sbbuf->sb_license_di);
Packit Service 360c39
	}
Packit Service 360c39
	else
Packit Service 360c39
		sbd.gfs1 = FALSE;
Packit Service 360c39
	sbd.bsize = sbd.sd_sb.sb_bsize;
Packit Service 360c39
	if (!sbd.bsize)
Packit Service 360c39
		sbd.bsize = GFS2_DEFAULT_BSIZE;
Packit Service 360c39
	if (lgfs2_get_dev_info(fd, &sbd.dinfo)) {
Packit Service 360c39
		perror(device);
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	if(compute_constants(&sbd)) {
Packit Service 360c39
		fprintf(stderr, "Failed to compute constants.\n");
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	if (sbd.gfs1 || (sbd.sd_sb.sb_header.mh_magic == GFS2_MAGIC &&
Packit Service 360c39
		     sbd.sd_sb.sb_header.mh_type == GFS2_METATYPE_SB))
Packit Service 360c39
		block = 0x10 * (GFS2_DEFAULT_BSIZE / sbd.bsize);
Packit Service 360c39
	else {
Packit Service 360c39
		block = starting_blk = 0;
Packit Service 360c39
	}
Packit Service 360c39
	fix_device_geometry(&sbd;;
Packit Service 360c39
	if(sbd.gfs1) {
Packit Service 360c39
		sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs_indirect)) /
Packit Service 360c39
			sizeof(uint64_t);
Packit Service 360c39
		sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs_dinode)) /
Packit Service 360c39
			sizeof(uint64_t);
Packit Service 360c39
		sbd.md.riinode = lgfs2_inode_read(&sbd, sbd1->sb_rindex_di.no_addr);
Packit Service 360c39
	} else {
Packit Service 360c39
		sbd.sd_inptrs = (sbd.bsize - sizeof(struct gfs2_meta_header)) /
Packit Service 360c39
			sizeof(uint64_t);
Packit Service 360c39
		sbd.sd_diptrs = (sbd.bsize - sizeof(struct gfs2_dinode)) /
Packit Service 360c39
			sizeof(uint64_t);
Packit Service 360c39
		sbd.master_dir = lgfs2_inode_read(&sbd,
Packit Service 360c39
					    sbd.sd_sb.sb_master_dir.no_addr);
Packit Service 360c39
		if (sbd.master_dir == NULL) {
Packit Service 360c39
			sbd.md.riinode = NULL;
Packit Service 360c39
		} else {
Packit Service 360c39
			gfs2_lookupi(sbd.master_dir, "rindex", 6, &sbd.md.riinode);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	brelse(bh);
Packit Service 360c39
	bh = NULL;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int read_rindex(void)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_rindex *ri;
Packit Service 360c39
	uint64_t count;
Packit Service 360c39
	int sane;
Packit Service 360c39
Packit Service 360c39
	sbd.fssize = sbd.device.length;
Packit Service 360c39
	if (sbd.md.riinode) /* If we found the rindex */
Packit Service 360c39
		rindex_read(&sbd, 0, &count, &sane);
Packit Service 360c39
Packit Service 360c39
	if (!OSI_EMPTY_ROOT(&sbd.rgtree)) {
Packit Service 360c39
		ri = &((struct rgrp_tree *)osi_last(&sbd.rgtree))->ri;
Packit Service 360c39
		sbd.fssize = ri->ri_data0 + ri->ri_data;
Packit Service 360c39
	}
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int read_master_dir(void)
Packit Service 360c39
{
Packit Service 360c39
	ioctl(sbd.device_fd, BLKFLSBUF, 0);
Packit Service 360c39
Packit Service 360c39
	bh = bread(&sbd, sbd.sd_sb.sb_master_dir.no_addr);
Packit Service 360c39
	if (bh == NULL)
Packit Service 360c39
		return 1;
Packit Service 360c39
	gfs2_dinode_in(&di, bh->b_data);
Packit Service 360c39
	do_dinode_extended(&di, bh); /* get extended data, if any */
Packit Service 360c39
	memcpy(&masterdir, &indirect[0], sizeof(struct indirect_info));
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int display(int identify_only, int trunc_zeros, uint64_t flagref,
Packit Service 360c39
	    uint64_t ref_blk)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t blk;
Packit Service 360c39
Packit Service 360c39
	if (block == RGLIST_DUMMY_BLOCK) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			blk = sbd1->sb_rindex_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			blk = masterblock("rindex");
Packit Service 360c39
	} else if (block == JOURNALS_DUMMY_BLOCK) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			blk = sbd1->sb_jindex_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			blk = masterblock("jindex");
Packit Service 360c39
	} else
Packit Service 360c39
		blk = block;
Packit Service 360c39
	if (termlines) {
Packit Service 360c39
		display_title_lines();
Packit Service 360c39
		move(2,0);
Packit Service 360c39
	}
Packit Service 360c39
	if (bh == NULL || bh->b_blocknr != blk) { /* If we changed blocks from the last read */
Packit Service 360c39
		if (bh != NULL)
Packit Service 360c39
			brelse(bh);
Packit Service 360c39
		dev_offset = blk * sbd.bsize;
Packit Service 360c39
		ioctl(sbd.device_fd, BLKFLSBUF, 0);
Packit Service 360c39
		if (!(bh = bread(&sbd, blk))) {
Packit Service 360c39
			fprintf(stderr, "read error: %s from %s:%d: "
Packit Service 360c39
				"offset %lld (0x%llx)\n",
Packit Service 360c39
				strerror(errno), __FUNCTION__, __LINE__,
Packit Service 360c39
				(unsigned long long)dev_offset,
Packit Service 360c39
				(unsigned long long)dev_offset);
Packit Service 360c39
			exit(-1);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	line = 1;
Packit Service 360c39
	gfs2_struct_type = display_block_type(bh, FALSE);
Packit Service 360c39
	if (identify_only)
Packit Service 360c39
		return 0;
Packit Service 360c39
	indirect_blocks = 0;
Packit Service 360c39
	lines_per_row[dmode] = 1;
Packit Service 360c39
	if (gfs2_struct_type == GFS2_METATYPE_SB || blk == 0x10 * (4096 / sbd.bsize)) {
Packit Service 360c39
		gfs2_sb_in(&sbd.sd_sb, bh->b_data);
Packit Service 360c39
		memset(indirect, 0, sizeof(struct iinfo));
Packit Service 360c39
		indirect->ii[0].block = sbd.sd_sb.sb_master_dir.no_addr;
Packit Service 360c39
		indirect->ii[0].is_dir = TRUE;
Packit Service 360c39
		indirect->ii[0].dirents = 2;
Packit Service 360c39
Packit Service 360c39
		memcpy(&indirect->ii[0].dirent[0].filename, "root", 4);
Packit Service 360c39
		indirect->ii[0].dirent[0].dirent.de_inum.no_formal_ino =
Packit Service 360c39
			sbd.sd_sb.sb_root_dir.no_formal_ino;
Packit Service 360c39
		indirect->ii[0].dirent[0].dirent.de_inum.no_addr =
Packit Service 360c39
			sbd.sd_sb.sb_root_dir.no_addr;
Packit Service 360c39
		indirect->ii[0].dirent[0].block = sbd.sd_sb.sb_root_dir.no_addr;
Packit Service 360c39
		indirect->ii[0].dirent[0].dirent.de_type = DT_DIR;
Packit Service 360c39
Packit Service 360c39
		memcpy(&indirect->ii[0].dirent[1].filename, "master", 7);
Packit Service 360c39
		indirect->ii[0].dirent[1].dirent.de_inum.no_formal_ino = 
Packit Service 360c39
			sbd.sd_sb.sb_master_dir.no_formal_ino;
Packit Service 360c39
		indirect->ii[0].dirent[1].dirent.de_inum.no_addr =
Packit Service 360c39
			sbd.sd_sb.sb_master_dir.no_addr;
Packit Service 360c39
		indirect->ii[0].dirent[1].block = sbd.sd_sb.sb_master_dir.no_addr;
Packit Service 360c39
		indirect->ii[0].dirent[1].dirent.de_type = DT_DIR;
Packit Service 360c39
	}
Packit Service 360c39
	else if (gfs2_struct_type == GFS2_METATYPE_DI) {
Packit Service 360c39
		gfs2_dinode_in(&di, bh->b_data);
Packit Service 360c39
		do_dinode_extended(&di, bh); /* get extended data, if any */
Packit Service 360c39
	}
Packit Service 360c39
	else if (gfs2_struct_type == GFS2_METATYPE_IN) { /* indirect block list */
Packit Service 360c39
		if (blockhist) {
Packit Service 360c39
			int i;
Packit Service 360c39
Packit Service 360c39
			for (i = 0; i < 512; i++)
Packit Service 360c39
				memcpy(&indirect->ii[i].mp,
Packit Service 360c39
				       &blockstack[blockhist - 1].mp,
Packit Service 360c39
				       sizeof(struct metapath));
Packit Service 360c39
		}
Packit Service 360c39
		indirect_blocks = do_indirect_extended(bh->b_data, indirect);
Packit Service 360c39
	}
Packit Service 360c39
	else if (gfs2_struct_type == GFS2_METATYPE_LF) { /* directory leaf */
Packit Service 360c39
		do_leaf_extended(bh->b_data, indirect);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	last_entry_onscreen[dmode] = 0;
Packit Service 360c39
	if (dmode == EXTENDED_MODE && !block_has_extended_info())
Packit Service 360c39
		dmode = HEX_MODE;
Packit Service 360c39
	if (termlines) {
Packit Service 360c39
		move(termlines, 63);
Packit Service 360c39
		if (dmode==HEX_MODE)
Packit Service 360c39
			printw("Mode: Hex %s", (editing?"edit ":"view "));
Packit Service 360c39
		else
Packit Service 360c39
			printw("Mode: %s", (dmode==GFS2_MODE?"Structure":
Packit Service 360c39
					    "Pointers "));
Packit Service 360c39
		move(line, 0);
Packit Service 360c39
	}
Packit Service 360c39
	if (dmode == HEX_MODE)          /* if hex display mode           */
Packit Service 360c39
		hexdump(dev_offset, (gfs2_struct_type == GFS2_METATYPE_DI)?
Packit Service 360c39
		        struct_len + di.di_size:sbd.bsize, trunc_zeros,
Packit Service 360c39
		        flagref, ref_blk);
Packit Service 360c39
	else if (dmode == GFS2_MODE) { /* if structure display */
Packit Service 360c39
		if (block != JOURNALS_DUMMY_BLOCK)
Packit Service 360c39
			display_gfs2(bh);  /* display the gfs2 structure */
Packit Service 360c39
	} else
Packit Service 360c39
		display_extended();        /* display extended blocks       */
Packit Service 360c39
	/* No else here because display_extended can switch back to hex mode */
Packit Service 360c39
	if (termlines)
Packit Service 360c39
		refresh();
Packit Service 360c39
	return(0);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* push_block - push a block onto the block stack                           */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void push_block(uint64_t blk)
Packit Service 360c39
{
Packit Service 360c39
	int i, bhst;
Packit Service 360c39
Packit Service 360c39
	bhst = blockhist % BLOCK_STACK_SIZE;
Packit Service 360c39
	if (blk) {
Packit Service 360c39
		blockstack[bhst].dmode = dmode;
Packit Service 360c39
		for (i = 0; i < DMODES; i++) {
Packit Service 360c39
			blockstack[bhst].start_row[i] = start_row[i];
Packit Service 360c39
			blockstack[bhst].end_row[i] = end_row[i];
Packit Service 360c39
			blockstack[bhst].edit_row[i] = edit_row[i];
Packit Service 360c39
			blockstack[bhst].edit_col[i] = edit_col[i];
Packit Service 360c39
			blockstack[bhst].lines_per_row[i] = lines_per_row[i];
Packit Service 360c39
		}
Packit Service 360c39
		blockstack[bhst].gfs2_struct_type = gfs2_struct_type;
Packit Service 360c39
		if (edit_row[dmode] >= 0 && !block_is_rindex(block))
Packit Service 360c39
			memcpy(&blockstack[bhst].mp,
Packit Service 360c39
			       &indirect->ii[edit_row[dmode]].mp,
Packit Service 360c39
			       sizeof(struct metapath));
Packit Service 360c39
		blockhist++;
Packit Service 360c39
		blockstack[blockhist % BLOCK_STACK_SIZE].block = blk;
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* pop_block - pop a block off the block stack                              */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t pop_block(void)
Packit Service 360c39
{
Packit Service 360c39
	int i, bhst;
Packit Service 360c39
Packit Service 360c39
	if (!blockhist)
Packit Service 360c39
		return block;
Packit Service 360c39
	blockhist--;
Packit Service 360c39
	bhst = blockhist % BLOCK_STACK_SIZE;
Packit Service 360c39
	dmode = blockstack[bhst].dmode;
Packit Service 360c39
	for (i = 0; i < DMODES; i++) {
Packit Service 360c39
		start_row[i] = blockstack[bhst].start_row[i];
Packit Service 360c39
		end_row[i] = blockstack[bhst].end_row[i];
Packit Service 360c39
		edit_row[i] = blockstack[bhst].edit_row[i];
Packit Service 360c39
		edit_col[i] = blockstack[bhst].edit_col[i];
Packit Service 360c39
		lines_per_row[i] = blockstack[bhst].lines_per_row[i];
Packit Service 360c39
	}
Packit Service 360c39
	gfs2_struct_type = blockstack[bhst].gfs2_struct_type;
Packit Service 360c39
	return blockstack[bhst].block;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* Find next metadata block of a given type AFTER a given point in the fs   */
Packit Service 360c39
/*                                                                          */
Packit Service 360c39
/* This is used to find blocks that aren't represented in the bitmaps, such */
Packit Service 360c39
/* as the RGs and bitmaps or the superblock.                                */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t find_metablockoftype_slow(uint64_t startblk, int metatype, int print)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t blk, last_fs_block;
Packit Service 360c39
	int found = 0;
Packit Service 360c39
	struct gfs2_buffer_head *lbh;
Packit Service 360c39
Packit Service 360c39
	last_fs_block = lseek(sbd.device_fd, 0, SEEK_END) / sbd.bsize;
Packit Service 360c39
	for (blk = startblk + 1; blk < last_fs_block; blk++) {
Packit Service 360c39
		lbh = bread(&sbd, blk);
Packit Service 360c39
		/* Can't use get_block_type here (returns false "none") */
Packit Service 360c39
		if (lbh->b_data[0] == 0x01 && lbh->b_data[1] == 0x16 &&
Packit Service 360c39
		    lbh->b_data[2] == 0x19 && lbh->b_data[3] == 0x70 &&
Packit Service 360c39
		    lbh->b_data[4] == 0x00 && lbh->b_data[5] == 0x00 &&
Packit Service 360c39
		    lbh->b_data[6] == 0x00 && lbh->b_data[7] == metatype) {
Packit Service 360c39
			found = 1;
Packit Service 360c39
			brelse(lbh);
Packit Service 360c39
			break;
Packit Service 360c39
		}
Packit Service 360c39
		brelse(lbh);
Packit Service 360c39
	}
Packit Service 360c39
	if (!found)
Packit Service 360c39
		blk = 0;
Packit Service 360c39
	if (print) {
Packit Service 360c39
		if (dmode == HEX_MODE)
Packit Service 360c39
			printf("0x%llx\n", (unsigned long long)blk);
Packit Service 360c39
		else
Packit Service 360c39
			printf("%llu\n", (unsigned long long)blk);
Packit Service 360c39
	}
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
	if (print)
Packit Service 360c39
		exit(0);
Packit Service 360c39
	return blk;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int find_rg_metatype(struct rgrp_tree *rgd, uint64_t *blk, uint64_t startblk, int mtype)
Packit Service 360c39
{
Packit Service 360c39
	int found;
Packit Service 360c39
	unsigned i, j, m;
Packit Service 360c39
	struct gfs2_buffer_head *bhp = NULL;
Packit Service 360c39
	uint64_t *ibuf = malloc(sbd.bsize * GFS2_NBBY * sizeof(uint64_t));
Packit Service 360c39
Packit Service 360c39
	for (i = 0; i < rgd->ri.ri_length; i++) {
Packit Service 360c39
		m = lgfs2_bm_scan(rgd, i, ibuf, GFS2_BLKST_DINODE);
Packit Service 360c39
Packit Service 360c39
		for (j = 0; j < m; j++) {
Packit Service 360c39
			*blk = ibuf[j];
Packit Service 360c39
			bhp = bread(&sbd, *blk);
Packit Service 360c39
			found = (*blk > startblk) && !gfs2_check_meta(bhp, mtype);
Packit Service 360c39
			brelse(bhp);
Packit Service 360c39
			if (found) {
Packit Service 360c39
				free(ibuf);
Packit Service 360c39
				return 0;
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	free(ibuf);
Packit Service 360c39
	return -1;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* Find next "metadata in use" block AFTER a given point in the fs          */
Packit Service 360c39
/*                                                                          */
Packit Service 360c39
/* This version does its magic by searching the bitmaps of the RG.  After   */
Packit Service 360c39
/* all, if we're searching for a dinode, we want a real allocated inode,    */
Packit Service 360c39
/* not just some block that used to be an inode in a previous incarnation.  */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t find_metablockoftype_rg(uint64_t startblk, int metatype, int print)
Packit Service 360c39
{
Packit Service 360c39
	struct osi_node *next = NULL;
Packit Service 360c39
	uint64_t blk, errblk;
Packit Service 360c39
	int first = 1, found = 0;
Packit Service 360c39
	struct rgrp_tree *rgd = NULL;
Packit Service 360c39
	struct gfs2_rindex *ri;
Packit Service 360c39
Packit Service 360c39
	blk = 0;
Packit Service 360c39
	/* Skip the rgs prior to the block we've been given */
Packit Service 360c39
	for (next = osi_first(&sbd.rgtree); next; next = osi_next(next)) {
Packit Service 360c39
		rgd = (struct rgrp_tree *)next;
Packit Service 360c39
		ri = &rgd->ri;
Packit Service 360c39
		if (first && startblk <= ri->ri_data0) {
Packit Service 360c39
			startblk = ri->ri_data0;
Packit Service 360c39
			break;
Packit Service 360c39
		} else if (ri->ri_addr <= startblk &&
Packit Service 360c39
			 startblk < ri->ri_data0 + ri->ri_data)
Packit Service 360c39
			break;
Packit Service 360c39
		else
Packit Service 360c39
			rgd = NULL;
Packit Service 360c39
		first = 0;
Packit Service 360c39
	}
Packit Service 360c39
	if (!rgd) {
Packit Service 360c39
		if (print)
Packit Service 360c39
			printf("0\n");
Packit Service 360c39
		gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
		if (print)
Packit Service 360c39
			exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	for (; !found && next; next = osi_next(next)){
Packit Service 360c39
		rgd = (struct rgrp_tree *)next;
Packit Service 360c39
		errblk = gfs2_rgrp_read(&sbd, rgd);
Packit Service 360c39
		if (errblk)
Packit Service 360c39
			continue;
Packit Service 360c39
Packit Service 360c39
		found = !find_rg_metatype(rgd, &blk, startblk, metatype);
Packit Service 360c39
		if (found)
Packit Service 360c39
			break;
Packit Service 360c39
Packit Service 360c39
		gfs2_rgrp_relse(rgd);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	if (!found)
Packit Service 360c39
		blk = 0;
Packit Service 360c39
	if (print) {
Packit Service 360c39
		if (dmode == HEX_MODE)
Packit Service 360c39
			printf("0x%llx\n", (unsigned long long)blk);
Packit Service 360c39
		else
Packit Service 360c39
			printf("%llu\n", (unsigned long long)blk);
Packit Service 360c39
	}
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
	if (print)
Packit Service 360c39
		exit(0);
Packit Service 360c39
	return blk;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* Find next metadata block AFTER a given point in the fs                   */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t find_metablockoftype(const char *strtype, int print)
Packit Service 360c39
{
Packit Service 360c39
	int mtype = 0;
Packit Service 360c39
	uint64_t startblk, blk = 0;
Packit Service 360c39
Packit Service 360c39
	if (print)
Packit Service 360c39
		startblk = blockstack[blockhist % BLOCK_STACK_SIZE].block;
Packit Service 360c39
	else
Packit Service 360c39
		startblk = block;
Packit Service 360c39
Packit Service 360c39
	for (mtype = GFS2_METATYPE_NONE;
Packit Service 360c39
	     mtype <= GFS2_METATYPE_QC; mtype++)
Packit Service 360c39
		if (!strcasecmp(strtype, mtypes[mtype]))
Packit Service 360c39
			break;
Packit Service 360c39
	if (!strcmp(strtype, "dinode"))
Packit Service 360c39
		mtype = GFS2_METATYPE_DI;
Packit Service 360c39
	if (mtype >= GFS2_METATYPE_NONE && mtype <= GFS2_METATYPE_RB)
Packit Service 360c39
		blk = find_metablockoftype_slow(startblk, mtype, print);
Packit Service 360c39
	else if (mtype >= GFS2_METATYPE_DI && mtype <= GFS2_METATYPE_QC)
Packit Service 360c39
		blk = find_metablockoftype_rg(startblk, mtype, print);
Packit Service 360c39
	else if (print) {
Packit Service 360c39
		fprintf(stderr, "Error: metadata type not "
Packit Service 360c39
			"specified: must be one of:\n");
Packit Service 360c39
		fprintf(stderr, "sb rg rb di in lf jd lh ld"
Packit Service 360c39
			" ea ed lb 13 qc\n");
Packit Service 360c39
		gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	return blk;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* Check if the word is a keyword such as "sb" or "rindex"                  */
Packit Service 360c39
/* Returns: block number if it is, else 0                                   */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
uint64_t check_keywords(const char *kword)
Packit Service 360c39
{
Packit Service 360c39
	unsigned long long blk = 0;
Packit Service 360c39
Packit Service 360c39
	if (!strcmp(kword, "sb") ||!strcmp(kword, "superblock"))
Packit Service 360c39
		blk = 0x10 * (4096 / sbd.bsize); /* superblock */
Packit Service 360c39
	else if (!strcmp(kword, "root") || !strcmp(kword, "rootdir"))
Packit Service 360c39
		blk = sbd.sd_sb.sb_root_dir.no_addr;
Packit Service 360c39
	else if (!strcmp(kword, "master")) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			fprintf(stderr, "This is GFS1; there's no master directory.\n");
Packit Service 360c39
		else if (!sbd.sd_sb.sb_master_dir.no_addr) {
Packit Service 360c39
			fprintf(stderr, "GFS2 master directory not found on %s\n", device);
Packit Service 360c39
			exit(-1);
Packit Service 360c39
		} else
Packit Service 360c39
			blk = sbd.sd_sb.sb_master_dir.no_addr;
Packit Service 360c39
	}
Packit Service 360c39
	else if (!strcmp(kword, "jindex")) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			blk = sbd1->sb_jindex_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			blk = masterblock("jindex"); /* journal index */
Packit Service 360c39
	}
Packit Service 360c39
	else if (!sbd.gfs1 && !strcmp(kword, "per_node"))
Packit Service 360c39
		blk = masterblock("per_node");
Packit Service 360c39
	else if (!sbd.gfs1 && !strcmp(kword, "inum"))
Packit Service 360c39
		blk = masterblock("inum");
Packit Service 360c39
	else if (!strcmp(kword, "statfs")) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			blk = gfs1_license_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			blk = masterblock("statfs");
Packit Service 360c39
	}
Packit Service 360c39
	else if (!strcmp(kword, "rindex") || !strcmp(kword, "rgindex")) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			blk = sbd1->sb_rindex_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			blk = masterblock("rindex");
Packit Service 360c39
	} else if (!strcmp(kword, "rgs")) {
Packit Service 360c39
		blk = RGLIST_DUMMY_BLOCK;
Packit Service 360c39
	} else if (!strcmp(kword, "quota")) {
Packit Service 360c39
		if (sbd.gfs1)
Packit Service 360c39
			blk = gfs1_quota_di.no_addr;
Packit Service 360c39
		else
Packit Service 360c39
			blk = masterblock("quota");
Packit Service 360c39
	} else if (!strncmp(kword, "rg ", 3)) {
Packit Service 360c39
		int rgnum = 0;
Packit Service 360c39
Packit Service 360c39
		rgnum = atoi(kword + 3);
Packit Service 360c39
		blk = get_rg_addr(rgnum);
Packit Service 360c39
	} else if (!strncmp(kword, "journals", 8)) {
Packit Service 360c39
		blk = JOURNALS_DUMMY_BLOCK;
Packit Service 360c39
	} else if (strlen(kword) > 7 && !strncmp(kword, "journal", 7) && isdigit(kword[7])) {
Packit Service 360c39
		uint64_t j_size;
Packit Service 360c39
Packit Service 360c39
		blk = find_journal_block(kword, &j_size);
Packit Service 360c39
	} else if (kword[0]=='/') /* search */
Packit Service 360c39
		blk = find_metablockoftype(&kword[1], 0);
Packit Service 360c39
	else if (kword[0]=='0' && kword[1]=='x') /* hex addr */
Packit Service 360c39
		sscanf(kword, "%llx", &blk);/* retrieve in hex */
Packit Service 360c39
	else
Packit Service 360c39
		sscanf(kword, "%llu", &blk); /* retrieve decimal */
Packit Service 360c39
Packit Service 360c39
	return blk;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* goto_block - go to a desired block entered by the user                   */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static uint64_t goto_block(void)
Packit Service 360c39
{
Packit Service 360c39
	char string[256];
Packit Service 360c39
	int ch, delta;
Packit Service 360c39
Packit Service 360c39
	memset(string, 0, sizeof(string));
Packit Service 360c39
	sprintf(string,"%lld", (long long)block);
Packit Service 360c39
	if (bobgets(string, 1, 7, 16, &ch)) {
Packit Service 360c39
		if (isalnum(string[0]) || string[0] == '/')
Packit Service 360c39
			temp_blk = check_keywords(string);
Packit Service 360c39
		else if (string[0] == '+' || string[0] == '-') {
Packit Service 360c39
			if (string[1] == '0' && string[2] == 'x')
Packit Service 360c39
				sscanf(string, "%x", &delta);
Packit Service 360c39
			else
Packit Service 360c39
				sscanf(string, "%d", &delta);
Packit Service 360c39
			temp_blk = block + delta;
Packit Service 360c39
		}
Packit Service 360c39
Packit Service 360c39
		if (temp_blk == RGLIST_DUMMY_BLOCK ||
Packit Service 360c39
		    temp_blk == JOURNALS_DUMMY_BLOCK || temp_blk < max_block) {
Packit Service 360c39
			offset = 0;
Packit Service 360c39
			block = temp_blk;
Packit Service 360c39
			push_block(block);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	return block;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* init_colors                                                              */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void init_colors(void)
Packit Service 360c39
{
Packit Service 360c39
Packit Service 360c39
	if (color_scheme) {
Packit Service 360c39
		init_pair(COLOR_TITLE, COLOR_BLACK,  COLOR_CYAN);
Packit Service 360c39
		init_pair(COLOR_NORMAL, COLOR_WHITE,  COLOR_BLACK);
Packit Service 360c39
		init_pair(COLOR_INVERSE, COLOR_BLACK,  COLOR_WHITE);
Packit Service 360c39
		init_pair(COLOR_SPECIAL, COLOR_RED,    COLOR_BLACK);
Packit Service 360c39
		init_pair(COLOR_HIGHLIGHT, COLOR_GREEN, COLOR_BLACK);
Packit Service 360c39
		init_pair(COLOR_OFFSETS, COLOR_CYAN,   COLOR_BLACK);
Packit Service 360c39
		init_pair(COLOR_CONTENTS, COLOR_YELLOW, COLOR_BLACK);
Packit Service 360c39
	}
Packit Service 360c39
	else {
Packit Service 360c39
		init_pair(COLOR_TITLE, COLOR_BLACK,  COLOR_CYAN);
Packit Service 360c39
		init_pair(COLOR_NORMAL, COLOR_BLACK,  COLOR_WHITE);
Packit Service 360c39
		init_pair(COLOR_INVERSE, COLOR_WHITE,  COLOR_BLACK);
Packit Service 360c39
		init_pair(COLOR_SPECIAL, COLOR_MAGENTA, COLOR_WHITE);
Packit Service 360c39
		init_pair(COLOR_HIGHLIGHT, COLOR_RED, COLOR_WHITE); /*cursor*/
Packit Service 360c39
		init_pair(COLOR_OFFSETS, COLOR_CYAN,   COLOR_WHITE);
Packit Service 360c39
		init_pair(COLOR_CONTENTS, COLOR_BLUE, COLOR_WHITE);
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* hex_edit - Allow the user to edit the page by entering hex digits        */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void hex_edit(int *exitch)
Packit Service 360c39
{
Packit Service 360c39
	int left_off;
Packit Service 360c39
	int ch;
Packit Service 360c39
Packit Service 360c39
	left_off = ((block * sbd.bsize) < 0xffffffff) ? 9 : 17;
Packit Service 360c39
	/* 8 and 16 char addresses on screen */
Packit Service 360c39
	
Packit Service 360c39
	if (bobgets(estring, edit_row[HEX_MODE] + 3,
Packit Service 360c39
		    (edit_col[HEX_MODE] * 2) + (edit_col[HEX_MODE] / 4) +
Packit Service 360c39
		    left_off, 2, exitch)) {
Packit Service 360c39
		if (strstr(edit_fmt,"X") || strstr(edit_fmt,"x")) {
Packit Service 360c39
			int hexoffset;
Packit Service 360c39
			int i, sl = strlen(estring);
Packit Service 360c39
			
Packit Service 360c39
			for (i = 0; i < sl; i+=2) {
Packit Service 360c39
				hexoffset = (edit_row[HEX_MODE] * 16) +
Packit Service 360c39
					edit_col[HEX_MODE] + (i / 2);
Packit Service 360c39
				ch = 0x00;
Packit Service 360c39
				if (isdigit(estring[i]))
Packit Service 360c39
					ch = (estring[i] - '0') * 0x10;
Packit Service 360c39
				else if (estring[i] >= 'a' &&
Packit Service 360c39
					 estring[i] <= 'f')
Packit Service 360c39
					ch = (estring[i]-'a' + 0x0a)*0x10;
Packit Service 360c39
				else if (estring[i] >= 'A' &&
Packit Service 360c39
					 estring[i] <= 'F')
Packit Service 360c39
					ch = (estring[i] - 'A' + 0x0a) * 0x10;
Packit Service 360c39
				if (isdigit(estring[i+1]))
Packit Service 360c39
					ch += (estring[i+1] - '0');
Packit Service 360c39
				else if (estring[i+1] >= 'a' &&
Packit Service 360c39
					 estring[i+1] <= 'f')
Packit Service 360c39
					ch += (estring[i+1] - 'a' + 0x0a);
Packit Service 360c39
				else if (estring[i+1] >= 'A' &&
Packit Service 360c39
					 estring[i+1] <= 'F')
Packit Service 360c39
					ch += (estring[i+1] - 'A' + 0x0a);
Packit Service 360c39
				bh->b_data[offset + hexoffset] = ch;
Packit Service 360c39
			}
Packit Service 360c39
			if (pwrite(sbd.device_fd, bh->b_data, sbd.bsize, dev_offset) !=
Packit Service 360c39
			    sbd.bsize) {
Packit Service 360c39
				fprintf(stderr, "write error: %s from %s:%d: "
Packit Service 360c39
					"offset %lld (0x%llx)\n",
Packit Service 360c39
					strerror(errno),
Packit Service 360c39
					__FUNCTION__, __LINE__,
Packit Service 360c39
					(unsigned long long)dev_offset,
Packit Service 360c39
					(unsigned long long)dev_offset);
Packit Service 360c39
				exit(-1);
Packit Service 360c39
			}
Packit Service 360c39
			fsync(sbd.device_fd);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* page up                                                                  */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void pageup(void)
Packit Service 360c39
{
Packit Service 360c39
	if (dmode == EXTENDED_MODE) {
Packit Service 360c39
		if (edit_row[dmode] - (dsplines / lines_per_row[dmode]) > 0)
Packit Service 360c39
			edit_row[dmode] -= (dsplines / lines_per_row[dmode]);
Packit Service 360c39
		else
Packit Service 360c39
			edit_row[dmode] = 0;
Packit Service 360c39
		if (start_row[dmode] - (dsplines / lines_per_row[dmode]) > 0)
Packit Service 360c39
			start_row[dmode] -= (dsplines / lines_per_row[dmode]);
Packit Service 360c39
		else
Packit Service 360c39
			start_row[dmode] = 0;
Packit Service 360c39
	}
Packit Service 360c39
	else {
Packit Service 360c39
		start_row[dmode] = edit_row[dmode] = 0;
Packit Service 360c39
		if (dmode == GFS2_MODE || offset==0) {
Packit Service 360c39
			block--;
Packit Service 360c39
			if (dmode == HEX_MODE)
Packit Service 360c39
				offset = (sbd.bsize % screen_chunk_size) > 0 ?
Packit Service 360c39
					screen_chunk_size *
Packit Service 360c39
					(sbd.bsize / screen_chunk_size) :
Packit Service 360c39
					sbd.bsize - screen_chunk_size;
Packit Service 360c39
			else
Packit Service 360c39
				offset = 0;
Packit Service 360c39
		} else
Packit Service 360c39
			offset -= screen_chunk_size;
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* page down                                                                */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void pagedn(void)
Packit Service 360c39
{
Packit Service 360c39
	if (dmode == EXTENDED_MODE) {
Packit Service 360c39
		if ((edit_row[dmode] + dsplines) / lines_per_row[dmode] + 1 <=
Packit Service 360c39
		    end_row[dmode]) {
Packit Service 360c39
			start_row[dmode] += dsplines / lines_per_row[dmode];
Packit Service 360c39
			edit_row[dmode] += dsplines / lines_per_row[dmode];
Packit Service 360c39
		} else {
Packit Service 360c39
			edit_row[dmode] = end_row[dmode] - 1;
Packit Service 360c39
			while (edit_row[dmode] - start_row[dmode]
Packit Service 360c39
			       + 1 > last_entry_onscreen[dmode])
Packit Service 360c39
				start_row[dmode]++;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	else {
Packit Service 360c39
		start_row[dmode] = edit_row[dmode] = 0;
Packit Service 360c39
		if (dmode == GFS2_MODE ||
Packit Service 360c39
		    offset + screen_chunk_size >= sbd.bsize) {
Packit Service 360c39
			block++;
Packit Service 360c39
			offset = 0;
Packit Service 360c39
		} else
Packit Service 360c39
			offset += screen_chunk_size;
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* jump - jump to the address the cursor is on                              */
Packit Service 360c39
/*                                                                          */
Packit Service 360c39
/* If the cursor is in a log descriptor, jump to the log-descriptor version */
Packit Service 360c39
/* of the block instead of the "real" block.                                */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void jump(void)
Packit Service 360c39
{
Packit Service 360c39
	if (dmode == HEX_MODE) {
Packit Service 360c39
		unsigned int col2;
Packit Service 360c39
		uint64_t *b;
Packit Service 360c39
		const uint32_t block_type = get_block_type(bh, NULL);
Packit Service 360c39
		
Packit Service 360c39
		/* special exception for log descriptors: jump the journaled
Packit Service 360c39
		   version of the block, not the "real" block */
Packit Service 360c39
		if (block_type == GFS2_METATYPE_LD) {
Packit Service 360c39
			int ptroffset = edit_row[dmode] * 16 + edit_col[dmode];
Packit Service 360c39
			int pnum = get_pnum(ptroffset);
Packit Service 360c39
			temp_blk = bh->b_blocknr + pnum + 1;
Packit Service 360c39
		} else if (edit_row[dmode] >= 0) {
Packit Service 360c39
			col2 = edit_col[dmode] & 0x08;/* thus 0-7->0, 8-15->8 */
Packit Service 360c39
			b = (uint64_t *)&bh->b_data[edit_row[dmode]*16 +
Packit Service 360c39
						    offset + col2];
Packit Service 360c39
			temp_blk = be64_to_cpu(*b);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	else
Packit Service 360c39
		sscanf(estring, "%"SCNx64, &temp_blk);/* retrieve in hex */
Packit Service 360c39
	if (temp_blk < max_block) { /* if the block number is valid */
Packit Service 360c39
		int i;
Packit Service 360c39
		
Packit Service 360c39
		offset = 0;
Packit Service 360c39
		push_block(temp_blk);
Packit Service 360c39
		block = temp_blk;
Packit Service 360c39
		for (i = 0; i < DMODES; i++) {
Packit Service 360c39
			start_row[i] = end_row[i] = edit_row[i] = 0;
Packit Service 360c39
			edit_col[i] = 0;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* print block type                                                         */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void print_block_type(uint64_t tblock, int type, const char *additional)
Packit Service 360c39
{
Packit Service 360c39
	if (type <= GFS2_METATYPE_QC)
Packit Service 360c39
		printf("%d (Block %lld is type %d: %s%s)\n", type,
Packit Service 360c39
		       (unsigned long long)tblock, type, block_type_str[type],
Packit Service 360c39
		       additional);
Packit Service 360c39
	else
Packit Service 360c39
		printf("%d (Block %lld is type %d: unknown%s)\n", type,
Packit Service 360c39
		       (unsigned long long)tblock, type, additional);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* find_print block type                                                    */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void find_print_block_type(void)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t tblock;
Packit Service 360c39
	struct gfs2_buffer_head *lbh;
Packit Service 360c39
	int type;
Packit Service 360c39
Packit Service 360c39
	tblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
Packit Service 360c39
	lbh = bread(&sbd, tblock);
Packit Service 360c39
	type = get_block_type(lbh, NULL);
Packit Service 360c39
	print_block_type(tblock, type, "");
Packit Service 360c39
	brelse(lbh);
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
	exit(0);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* Find and print the resource group associated with a given block          */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void find_print_block_rg(int bitmap)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t rblock, rgblock;
Packit Service 360c39
	int i;
Packit Service 360c39
	struct rgrp_tree *rgd;
Packit Service 360c39
Packit Service 360c39
	rblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
Packit Service 360c39
	if (rblock == LGFS2_SB_ADDR(&sbd))
Packit Service 360c39
		printf("0 (the superblock is not in the bitmap)\n");
Packit Service 360c39
	else {
Packit Service 360c39
		rgd = gfs2_blk2rgrpd(&sbd, rblock);
Packit Service 360c39
		if (rgd) {
Packit Service 360c39
			rgblock = rgd->ri.ri_addr;
Packit Service 360c39
			if (bitmap) {
Packit Service 360c39
				struct gfs2_bitmap *bits = NULL;
Packit Service 360c39
Packit Service 360c39
				for (i = 0; i < rgd->ri.ri_length; i++) {
Packit Service 360c39
					bits = &(rgd->bits[i]);
Packit Service 360c39
					if (rblock - rgd->ri.ri_data0 <
Packit Service 360c39
					    ((bits->bi_start + bits->bi_len) *
Packit Service 360c39
					     GFS2_NBBY)) {
Packit Service 360c39
						break;
Packit Service 360c39
					}
Packit Service 360c39
				}
Packit Service 360c39
				if (i < rgd->ri.ri_length)
Packit Service 360c39
					rgblock += i;
Packit Service 360c39
Packit Service 360c39
			}
Packit Service 360c39
			if (dmode == HEX_MODE)
Packit Service 360c39
				printf("0x%llx\n",(unsigned long long)rgblock);
Packit Service 360c39
			else
Packit Service 360c39
				printf("%llu\n", (unsigned long long)rgblock);
Packit Service 360c39
		} else {
Packit Service 360c39
			printf("-1 (block invalid or part of an rgrp).\n");
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
	exit(0);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* find/change/print block allocation (what the bitmap says about block)    */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void find_change_block_alloc(int *newval)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t ablock;
Packit Service 360c39
	int type;
Packit Service 360c39
	struct rgrp_tree *rgd;
Packit Service 360c39
Packit Service 360c39
	if (newval &&
Packit Service 360c39
	    (*newval < GFS2_BLKST_FREE || *newval > GFS2_BLKST_DINODE)) {
Packit Service 360c39
		int i;
Packit Service 360c39
Packit Service 360c39
		printf("Error: value %d is not valid.\nValid values are:\n",
Packit Service 360c39
		       *newval);
Packit Service 360c39
		for (i = GFS2_BLKST_FREE; i <= GFS2_BLKST_DINODE; i++)
Packit Service 360c39
			printf("%d - %s\n", i, allocdesc[sbd.gfs1][i]);
Packit Service 360c39
		gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	ablock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
Packit Service 360c39
	if (ablock == LGFS2_SB_ADDR(&sbd))
Packit Service 360c39
		printf("3 (the superblock is not in the bitmap)\n");
Packit Service 360c39
	else {
Packit Service 360c39
		rgd = gfs2_blk2rgrpd(&sbd, ablock);
Packit Service 360c39
		if (rgd) {
Packit Service 360c39
			gfs2_rgrp_read(&sbd, rgd);
Packit Service 360c39
			if (newval) {
Packit Service 360c39
				if (gfs2_set_bitmap(rgd, ablock, *newval))
Packit Service 360c39
					printf("-1 (block invalid or part of an rgrp).\n");
Packit Service 360c39
				else
Packit Service 360c39
					printf("%d\n", *newval);
Packit Service 360c39
			} else {
Packit Service 360c39
				type = lgfs2_get_bitmap(&sbd, ablock, rgd);
Packit Service 360c39
				if (type < 0) {
Packit Service 360c39
					printf("-1 (block invalid or part of "
Packit Service 360c39
					       "an rgrp).\n");
Packit Service 360c39
					exit(-1);
Packit Service 360c39
				}
Packit Service 360c39
				printf("%d (%s)\n", type, allocdesc[sbd.gfs1][type]);
Packit Service 360c39
			}
Packit Service 360c39
			gfs2_rgrp_relse(rgd);
Packit Service 360c39
		} else {
Packit Service 360c39
			gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
			printf("-1 (block invalid or part of an rgrp).\n");
Packit Service 360c39
			exit(-1);
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
	if (newval)
Packit Service 360c39
		fsync(sbd.device_fd);
Packit Service 360c39
	exit(0);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/**
Packit Service 360c39
 * process request to print a certain field from a previously pushed block
Packit Service 360c39
 */
Packit Service 360c39
static void process_field(const char *field, const char *nstr)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t fblock;
Packit Service 360c39
	struct gfs2_buffer_head *rbh;
Packit Service 360c39
	int type;
Packit Service 360c39
	const struct lgfs2_metadata *mtype;
Packit Service 360c39
	const struct lgfs2_metafield *mfield;
Packit Service 360c39
Packit Service 360c39
	fblock = blockstack[blockhist % BLOCK_STACK_SIZE].block;
Packit Service 360c39
	rbh = bread(&sbd, fblock);
Packit Service 360c39
	type = get_block_type(rbh, NULL);
Packit Service 360c39
Packit Service 360c39
	mtype = lgfs2_find_mtype(type, sbd.gfs1 ? LGFS2_MD_GFS1 : LGFS2_MD_GFS2);
Packit Service 360c39
	if (mtype == NULL) {
Packit Service 360c39
		fprintf(stderr, "Metadata type '%d' invalid\n", type);
Packit Service 360c39
		exit(1);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	mfield = lgfs2_find_mfield_name(field, mtype);
Packit Service 360c39
	if (mfield == NULL) {
Packit Service 360c39
		fprintf(stderr, "No field '%s' in block type '%s'\n", field, mtype->name);
Packit Service 360c39
		exit(1);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	if (nstr != device) {
Packit Service 360c39
		int err = 0;
Packit Service 360c39
		if (mfield->flags & (LGFS2_MFF_UUID|LGFS2_MFF_STRING)) {
Packit Service 360c39
			err = lgfs2_field_assign(rbh->b_data, mfield, nstr);
Packit Service 360c39
		} else {
Packit Service 360c39
			uint64_t val = 0;
Packit Service 360c39
			err = sscanf(nstr, "%"SCNi64, &val;;
Packit Service 360c39
			if (err == 1)
Packit Service 360c39
				err = lgfs2_field_assign(rbh->b_data, mfield, &val;;
Packit Service 360c39
			else
Packit Service 360c39
				err = -1;
Packit Service 360c39
		}
Packit Service 360c39
		if (err != 0) {
Packit Service 360c39
			fprintf(stderr, "Could not set '%s' to '%s': %s\n", field, nstr,
Packit Service 360c39
			        strerror(errno));
Packit Service 360c39
			exit(1);
Packit Service 360c39
		}
Packit Service 360c39
		bmodified(rbh);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	if (!termlines) {
Packit Service 360c39
		char str[GFS2_LOCKNAME_LEN] = "";
Packit Service 360c39
		lgfs2_field_str(str, GFS2_LOCKNAME_LEN, rbh->b_data, mfield, (dmode == HEX_MODE));
Packit Service 360c39
		printf("%s\n", str);
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	brelse(rbh);
Packit Service 360c39
	fsync(sbd.device_fd);
Packit Service 360c39
	exit(0);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* interactive_mode - accept keystrokes from user and display structures    */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void interactive_mode(void)
Packit Service 360c39
{
Packit Service 360c39
	int ch = 0, Quit;
Packit Service 360c39
Packit Service 360c39
	if ((wind = initscr()) == NULL) {
Packit Service 360c39
		fprintf(stderr, "Error: unable to initialize screen.");
Packit Service 360c39
		eol(0);
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	getmaxyx(stdscr, termlines, termcols);
Packit Service 360c39
	termlines--;
Packit Service 360c39
	/* Do our initial screen stuff: */
Packit Service 360c39
	clear(); /* don't use Erase */
Packit Service 360c39
	start_color();
Packit Service 360c39
	noecho();
Packit Service 360c39
	keypad(stdscr, TRUE);
Packit Service 360c39
	raw();
Packit Service 360c39
	curs_set(0);
Packit Service 360c39
	init_colors();
Packit Service 360c39
	/* Accept keystrokes and act on them accordingly */
Packit Service 360c39
	Quit = FALSE;
Packit Service 360c39
	editing = FALSE;
Packit Service 360c39
	while (!Quit) {
Packit Service 360c39
		display(FALSE, 0, 0, 0);
Packit Service 360c39
		if (editing) {
Packit Service 360c39
			if (edit_row[dmode] == -1)
Packit Service 360c39
				block = goto_block();
Packit Service 360c39
			else {
Packit Service 360c39
				if (dmode == HEX_MODE)
Packit Service 360c39
					hex_edit(&ch);
Packit Service 360c39
				else if (dmode == GFS2_MODE) {
Packit Service 360c39
					bobgets(estring, edit_row[dmode]+4, 24,
Packit Service 360c39
						10, &ch);
Packit Service 360c39
					process_field(efield, estring);
Packit Service 360c39
				} else
Packit Service 360c39
					bobgets(estring, edit_row[dmode]+6, 14,
Packit Service 360c39
						edit_size[dmode], &ch);
Packit Service 360c39
			}
Packit Service 360c39
		}
Packit Service 360c39
		else
Packit Service 360c39
			while ((ch=getch()) == 0); // wait for input
Packit Service 360c39
Packit Service 360c39
		switch (ch)
Packit Service 360c39
		{
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* escape or 'q' */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 0x1b:
Packit Service 360c39
		case 0x03:
Packit Service 360c39
		case 'q':
Packit Service 360c39
			if (editing)
Packit Service 360c39
				editing = FALSE;
Packit Service 360c39
			else
Packit Service 360c39
				Quit=TRUE;
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* home - return to the superblock                           */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_HOME:
Packit Service 360c39
			if (dmode == EXTENDED_MODE) {
Packit Service 360c39
				start_row[dmode] = end_row[dmode] = 0;
Packit Service 360c39
				edit_row[dmode] = 0;
Packit Service 360c39
			}
Packit Service 360c39
			else {
Packit Service 360c39
				block = 0x10 * (4096 / sbd.bsize);
Packit Service 360c39
				push_block(block);
Packit Service 360c39
				offset = 0;
Packit Service 360c39
			}
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* backspace - return to the previous block on the stack     */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_BACKSPACE:
Packit Service 360c39
		case 0x7f:
Packit Service 360c39
			block = pop_block();
Packit Service 360c39
			offset = 0;
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* space - go down the block stack (opposite of backspace)   */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case ' ':
Packit Service 360c39
			blockhist++;
Packit Service 360c39
			block = blockstack[blockhist % BLOCK_STACK_SIZE].block;
Packit Service 360c39
			offset = 0;
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* arrow up */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_UP:
Packit Service 360c39
		case '-':
Packit Service 360c39
			if (dmode == EXTENDED_MODE) {
Packit Service 360c39
				if (edit_row[dmode] > 0)
Packit Service 360c39
					edit_row[dmode]--;
Packit Service 360c39
				if (edit_row[dmode] < start_row[dmode])
Packit Service 360c39
					start_row[dmode] = edit_row[dmode];
Packit Service 360c39
			}
Packit Service 360c39
			else {
Packit Service 360c39
				if (edit_row[dmode] >= 0)
Packit Service 360c39
					edit_row[dmode]--;
Packit Service 360c39
			}
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* arrow down */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_DOWN:
Packit Service 360c39
		case '+':
Packit Service 360c39
			if (dmode == EXTENDED_MODE) {
Packit Service 360c39
				if (edit_row[dmode] + 1 < end_row[dmode]) {
Packit Service 360c39
					if (edit_row[dmode] - start_row[dmode]
Packit Service 360c39
					    + 1 > last_entry_onscreen[dmode])
Packit Service 360c39
						start_row[dmode]++;
Packit Service 360c39
					edit_row[dmode]++;
Packit Service 360c39
				}
Packit Service 360c39
			}
Packit Service 360c39
			else {
Packit Service 360c39
				if (edit_row[dmode] < last_entry_onscreen[dmode])
Packit Service 360c39
					edit_row[dmode]++;
Packit Service 360c39
			}
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* arrow left */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_LEFT:
Packit Service 360c39
			if (dmode == HEX_MODE) {
Packit Service 360c39
				if (edit_col[dmode] > 0)
Packit Service 360c39
					edit_col[dmode]--;
Packit Service 360c39
				else
Packit Service 360c39
					edit_col[dmode] = 15;
Packit Service 360c39
			}
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* arrow right */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_RIGHT:
Packit Service 360c39
			if (dmode == HEX_MODE) {
Packit Service 360c39
				if (edit_col[dmode] < 15)
Packit Service 360c39
					edit_col[dmode]++;
Packit Service 360c39
				else
Packit Service 360c39
					edit_col[dmode] = 0;
Packit Service 360c39
			}
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* m - change display mode key */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'm':
Packit Service 360c39
			dmode = ((dmode + 1) % DMODES);
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* J - Jump to highlighted block number */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'j':
Packit Service 360c39
			jump();
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* g - goto block */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'g':
Packit Service 360c39
			block = goto_block();
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* h - help key */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'h':
Packit Service 360c39
			print_usage();
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* e - change to extended mode */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'e':
Packit Service 360c39
			dmode = EXTENDED_MODE;
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* b - Back one 4K block */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'b':
Packit Service 360c39
			start_row[dmode] = end_row[dmode] = edit_row[dmode] = 0;
Packit Service 360c39
			if (block > 0)
Packit Service 360c39
				block--;
Packit Service 360c39
			offset = 0;
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* c - Change color scheme */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'c':
Packit Service 360c39
			color_scheme = !color_scheme;
Packit Service 360c39
			init_colors();
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* page up key */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 0x19:                    // ctrl-y for vt100
Packit Service 360c39
		case KEY_PPAGE:		      // PgUp
Packit Service 360c39
		case 0x15:                    // ctrl-u for vi compat.
Packit Service 360c39
		case 0x02:                   // ctrl-b for less compat.
Packit Service 360c39
			pageup();
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* end - Jump to the end of the list */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 0x168:
Packit Service 360c39
			if (dmode == EXTENDED_MODE) {
Packit Service 360c39
				int ents_per_screen = dsplines /
Packit Service 360c39
					lines_per_row[dmode];
Packit Service 360c39
Packit Service 360c39
				edit_row[dmode] = end_row[dmode] - 1;
Packit Service 360c39
				if ((edit_row[dmode] - ents_per_screen)+1 > 0)
Packit Service 360c39
					start_row[dmode] = edit_row[dmode] - 
Packit Service 360c39
						ents_per_screen + 1;
Packit Service 360c39
				else
Packit Service 360c39
					start_row[dmode] = 0;
Packit Service 360c39
			}
Packit Service 360c39
			/* TODO: Make end key work for other display modes. */
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* f - Forward one 4K block */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 'f':
Packit Service 360c39
			start_row[dmode]=end_row[dmode]=edit_row[dmode] = 0;
Packit Service 360c39
			lines_per_row[dmode] = 1;
Packit Service 360c39
			block++;
Packit Service 360c39
			offset = 0;
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* page down key */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case 0x16:                    // ctrl-v for vt100
Packit Service 360c39
		case KEY_NPAGE:		      // PgDown
Packit Service 360c39
		case 0x04:                    // ctrl-d for vi compat.
Packit Service 360c39
			pagedn();
Packit Service 360c39
			break;
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		/* enter key - change a value */
Packit Service 360c39
		/* --------------------------------------------------------- */
Packit Service 360c39
		case KEY_ENTER:
Packit Service 360c39
		case('\n'):
Packit Service 360c39
		case('\r'):
Packit Service 360c39
			editing = !editing;
Packit Service 360c39
			break;
Packit Service 360c39
		case KEY_RESIZE:
Packit Service 360c39
			getmaxyx(stdscr, termlines, termcols);
Packit Service 360c39
			termlines--;
Packit Service 360c39
			break;
Packit Service 360c39
		default:
Packit Service 360c39
			move(termlines - 1, 0);
Packit Service 360c39
			printw("Keystroke not understood: 0x%03x",ch);
Packit Service 360c39
			refresh();
Packit Service 360c39
			usleep(50000);
Packit Service 360c39
			break;
Packit Service 360c39
		} /* switch */
Packit Service 360c39
	} /* while !Quit */
Packit Service 360c39
Packit Service 360c39
    Erase();
Packit Service 360c39
    refresh();
Packit Service 360c39
    endwin();
Packit Service 360c39
}/* interactive_mode */
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* gfs_log_header_in - read in a gfs1-style log header                      */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
void gfs_log_header_in(struct gfs_log_header *head,
Packit Service 360c39
		       struct gfs2_buffer_head *lbh)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs_log_header *str = lbh->iov.iov_base;
Packit Service 360c39
Packit Service 360c39
	gfs2_meta_header_in(&head->lh_header, lbh->b_data);
Packit Service 360c39
Packit Service 360c39
	head->lh_flags = be32_to_cpu(str->lh_flags);
Packit Service 360c39
	head->lh_pad = be32_to_cpu(str->lh_pad);
Packit Service 360c39
Packit Service 360c39
	head->lh_first = be64_to_cpu(str->lh_first);
Packit Service 360c39
	head->lh_sequence = be64_to_cpu(str->lh_sequence);
Packit Service 360c39
Packit Service 360c39
	head->lh_tail = be64_to_cpu(str->lh_tail);
Packit Service 360c39
	head->lh_last_dump = be64_to_cpu(str->lh_last_dump);
Packit Service 360c39
Packit Service 360c39
	memcpy(head->lh_reserved, str->lh_reserved, 64);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* gfs_log_header_print - print a gfs1-style log header                     */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
void gfs_log_header_print(struct gfs_log_header *lh)
Packit Service 360c39
{
Packit Service 360c39
	gfs2_meta_header_print(&lh->lh_header);
Packit Service 360c39
	pv(lh, lh_flags, "%u", "0x%.8x");
Packit Service 360c39
	pv(lh, lh_pad, "%u", "%x");
Packit Service 360c39
	pv((unsigned long long)lh, lh_first, "%llu", "%llx");
Packit Service 360c39
	pv((unsigned long long)lh, lh_sequence, "%llu", "%llx");
Packit Service 360c39
	pv((unsigned long long)lh, lh_tail, "%llu", "%llx");
Packit Service 360c39
	pv((unsigned long long)lh, lh_last_dump, "%llu", "%llx");
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* usage - print command line usage                                         */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void usage(void)
Packit Service 360c39
{
Packit Service 360c39
	fprintf(stderr,"\nFormat is: gfs2_edit [-c 1] [-V] [-x] [-h] [identify] [-z <0-9>] [-p structures|blocks][blocktype][blockalloc [val]][blockbits][blockrg][rgcount][rgflags][rgbitmaps][find sb|rg|rb|di|in|lf|jd|lh|ld|ea|ed|lb|13|qc][field <f>[val]] /dev/device\n\n");
Packit Service 360c39
	fprintf(stderr,"If only the device is specified, it enters into hexedit mode.\n");
Packit Service 360c39
	fprintf(stderr,"identify - prints out only the block type, not the details.\n");
Packit Service 360c39
	fprintf(stderr,"printsavedmeta - prints out the saved metadata blocks from a savemeta file.\n");
Packit Service 360c39
	fprintf(stderr,"savemeta <file_system> <file.gz> - save off your metadata for analysis and debugging.\n");
Packit Service 360c39
	fprintf(stderr,"   (The intelligent way: assume bitmap is correct).\n");
Packit Service 360c39
	fprintf(stderr,"savemetaslow - save off your metadata for analysis and debugging.  The SLOW way (block by block).\n");
Packit Service 360c39
	fprintf(stderr,"savergs - save off only the resource group information (rindex and rgs).\n");
Packit Service 360c39
	fprintf(stderr,"restoremeta - restore metadata for debugging (DANGEROUS).\n");
Packit Service 360c39
	fprintf(stderr,"rgcount - print how many RGs in the file system.\n");
Packit Service 360c39
	fprintf(stderr,"rgflags rgnum [new flags] - print or modify flags for rg #rgnum (0 - X)\n");
Packit Service 360c39
	fprintf(stderr,"rgbitmaps <rgnum> - print out the bitmaps for rgrp "
Packit Service 360c39
		"rgnum.\n");
Packit Service 360c39
	fprintf(stderr,"rgrepair - find and repair damaged rgrp.\n");
Packit Service 360c39
	fprintf(stderr,"-V   prints version number.\n");
Packit Service 360c39
	fprintf(stderr,"-c 1 selects alternate color scheme 1\n");
Packit Service 360c39
	fprintf(stderr,"-d   prints details (for printing journals)\n");
Packit Service 360c39
	fprintf(stderr,"-p   prints GFS2 structures or blocks to stdout.\n");
Packit Service 360c39
	fprintf(stderr,"     sb - prints the superblock.\n");
Packit Service 360c39
	fprintf(stderr,"     size - prints the filesystem size.\n");
Packit Service 360c39
	fprintf(stderr,"     master - prints the master directory.\n");
Packit Service 360c39
	fprintf(stderr,"     root - prints the root directory.\n");
Packit Service 360c39
	fprintf(stderr,"     jindex - prints the journal index directory.\n");
Packit Service 360c39
	fprintf(stderr,"     journals - prints the journal status.\n");
Packit Service 360c39
	fprintf(stderr,"     per_node - prints the per_node directory.\n");
Packit Service 360c39
	fprintf(stderr,"     inum - prints the inum file.\n");
Packit Service 360c39
	fprintf(stderr,"     statfs - prints the statfs file.\n");
Packit Service 360c39
	fprintf(stderr,"     rindex - prints the rindex file.\n");
Packit Service 360c39
	fprintf(stderr,"     rg X - print resource group X.\n");
Packit Service 360c39
	fprintf(stderr,"     rgs - prints all the resource groups (rgs).\n");
Packit Service 360c39
	fprintf(stderr,"     quota - prints the quota file.\n");
Packit Service 360c39
	fprintf(stderr,"     0x1234 - prints the specified block\n");
Packit Service 360c39
	fprintf(stderr,"-p   <block> blocktype - prints the type "
Packit Service 360c39
		"of the specified block\n");
Packit Service 360c39
	fprintf(stderr,"-p   <block> blockrg - prints the resource group "
Packit Service 360c39
		"block corresponding to the specified block\n");
Packit Service 360c39
	fprintf(stderr,"-p   <block> blockbits - prints the block with "
Packit Service 360c39
		"the bitmap corresponding to the specified block\n");
Packit Service 360c39
	fprintf(stderr,"-p   <block> blockalloc [0|1|2|3] - print or change "
Packit Service 360c39
		"the allocation type of the specified block\n");
Packit Service 360c39
	fprintf(stderr,"-p   <block> field [new_value] - prints or change the "
Packit Service 360c39
		"structure field\n");
Packit Service 360c39
	fprintf(stderr,"-p    find sb|rg|rb|di|in|lf|jd|lh|ld|ea|ed|lb|"
Packit Service 360c39
		"13|qc - find block of given type after block \n");
Packit Service 360c39
	fprintf(stderr,"      specifies the starting block for search\n");
Packit Service 360c39
	fprintf(stderr,"-z 1 use gzip compression level 1 for savemeta (default 9)\n");
Packit Service 360c39
	fprintf(stderr,"-z 0 do not use compression\n");
Packit Service 360c39
	fprintf(stderr,"-s   specifies a starting block such as root, rindex, quota, inum.\n");
Packit Service 360c39
	fprintf(stderr,"-x   print in hexmode.\n");
Packit Service 360c39
	fprintf(stderr,"-h   prints this help.\n\n");
Packit Service 360c39
	fprintf(stderr,"Examples:\n");
Packit Service 360c39
	fprintf(stderr,"   To run in interactive mode:\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit /dev/bobs_vg/lvol0\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the superblock and master directory:\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p sb master /dev/bobs_vg/lvol0\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the master directory in hex:\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -x -p master /dev/bobs_vg/lvol0\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the block-type for block 0x27381:\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit identify -p 0x27381 /dev/bobs_vg/lvol0\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the fourth Resource Group. (the first R is #0)\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p rg 3 /dev/sdb1\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the metadata type of block 1234\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p 1234 blocktype /dev/roth_vg/roth_lb\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the allocation type of block 2345\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p 2345 blockalloc /dev/vg/lv\n");
Packit Service 360c39
	fprintf(stderr,"   To change the allocation type of block 2345 to a 'free block'\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p 2345 blockalloc 0 /dev/vg/lv\n");
Packit Service 360c39
	fprintf(stderr,"   To print out the file size of the dinode at block 0x118\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p 0x118 field di_size /dev/roth_vg/roth_lb\n");
Packit Service 360c39
	fprintf(stderr,"   To find any dinode higher than the quota file dinode:\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit -p quota find di /dev/x/y\n");
Packit Service 360c39
	fprintf(stderr,"   To set the Resource Group flags for rg #7 to 3.\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit rgflags 7 3 /dev/sdc2\n");
Packit Service 360c39
	fprintf(stderr,"   To save off all metadata for /dev/vg/lv:\n");
Packit Service 360c39
	fprintf(stderr,"     gfs2_edit savemeta /dev/vg/lv /tmp/metasave.gz\n");
Packit Service 360c39
}/* usage */
Packit Service 360c39
Packit Service 360c39
/**
Packit Service 360c39
 * getgziplevel - Process the -z parameter to savemeta operations
Packit Service 360c39
 * argv - argv
Packit Service 360c39
 * i    - a pointer to the argv index at which to begin processing
Packit Service 360c39
 * The index pointed to by i will be incremented past the -z option if found
Packit Service 360c39
 */
Packit Service 360c39
static void getgziplevel(char *argv[], int *i)
Packit Service 360c39
{
Packit Service 360c39
	char *opt, *arg;
Packit Service 360c39
	char *endptr;
Packit Service 360c39
Packit Service 360c39
	arg = argv[1 + *i];
Packit Service 360c39
	if (strncmp(arg, "-z", 2)) {
Packit Service 360c39
		return;
Packit Service 360c39
	} else if (arg[2] != '\0') {
Packit Service 360c39
		opt = &arg[2];
Packit Service 360c39
	} else {
Packit Service 360c39
		(*i)++;
Packit Service 360c39
		opt = argv[1 + *i];
Packit Service 360c39
	}
Packit Service 360c39
	errno = 0;
Packit Service 360c39
	gziplevel = strtol(opt, &endptr, 10);
Packit Service 360c39
	if (errno || endptr == opt || gziplevel < 0 || gziplevel > 9) {
Packit Service 360c39
		fprintf(stderr, "Compression level out of range: %s\n", opt);
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	}
Packit Service 360c39
	(*i)++;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int count_dinode_blks(struct rgrp_tree *rgd, int bitmap,
Packit Service 360c39
			     struct gfs2_buffer_head *rbh)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_buffer_head *tbh;
Packit Service 360c39
	uint64_t b;
Packit Service 360c39
	int dinodes = 0;
Packit Service 360c39
	char *byte, cur_state, new_state;
Packit Service 360c39
	int bit, off;
Packit Service 360c39
Packit Service 360c39
	if (bitmap)
Packit Service 360c39
		off = sizeof(struct gfs2_meta_header);
Packit Service 360c39
	else
Packit Service 360c39
		off = sizeof(struct gfs2_rgrp);
Packit Service 360c39
Packit Service 360c39
	for (b = 0; b < rgd->bits[bitmap].bi_len << GFS2_BIT_SIZE; b++) {
Packit Service 360c39
		tbh = bread(&sbd, rgd->ri.ri_data0 +
Packit Service 360c39
			    rgd->bits[bitmap].bi_start + b);
Packit Service 360c39
		byte = rbh->b_data + off + (b / GFS2_NBBY);
Packit Service 360c39
		bit = (b % GFS2_NBBY) * GFS2_BIT_SIZE;
Packit Service 360c39
		if (gfs2_check_meta(tbh, GFS2_METATYPE_DI) == 0) {
Packit Service 360c39
			dinodes++;
Packit Service 360c39
			new_state = GFS2_BLKST_DINODE;
Packit Service 360c39
		} else {
Packit Service 360c39
			new_state = GFS2_BLKST_USED;
Packit Service 360c39
		}
Packit Service 360c39
		cur_state = (*byte >> bit) & GFS2_BIT_MASK;
Packit Service 360c39
		*byte ^= cur_state << bit;
Packit Service 360c39
		*byte |= new_state << bit;
Packit Service 360c39
		brelse(tbh);
Packit Service 360c39
	}
Packit Service 360c39
	bmodified(rbh);
Packit Service 360c39
	return dinodes;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static int count_dinode_bits(struct gfs2_buffer_head *rbh)
Packit Service 360c39
{
Packit Service 360c39
	uint64_t blk;
Packit Service 360c39
	struct gfs2_meta_header *mh = (struct gfs2_meta_header *)rbh->b_data;
Packit Service 360c39
	char *byte;
Packit Service 360c39
	int bit;
Packit Service 360c39
	int dinodes = 0;
Packit Service 360c39
Packit Service 360c39
	if (be32_to_cpu(mh->mh_type) == GFS2_METATYPE_RG)
Packit Service 360c39
		blk = sizeof(struct gfs2_rgrp);
Packit Service 360c39
	else
Packit Service 360c39
		blk = sizeof(struct gfs2_meta_header);
Packit Service 360c39
Packit Service 360c39
	for (; blk < sbd.bsize; blk++) {
Packit Service 360c39
		byte = rbh->b_data + (blk / GFS2_NBBY);
Packit Service 360c39
		bit = (blk % GFS2_NBBY) * GFS2_BIT_SIZE;
Packit Service 360c39
		if (((*byte >> bit) & GFS2_BIT_MASK) == GFS2_BLKST_DINODE)
Packit Service 360c39
			dinodes++;
Packit Service 360c39
	}
Packit Service 360c39
	return dinodes;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void rg_repair(void)
Packit Service 360c39
{
Packit Service 360c39
	struct gfs2_buffer_head *rbh;
Packit Service 360c39
	struct rgrp_tree *rgd;
Packit Service 360c39
	struct osi_node *n;
Packit Service 360c39
	int b;
Packit Service 360c39
	int rgs_fixed = 0;
Packit Service 360c39
	int dinodes_found = 0, dinodes_total = 0;
Packit Service 360c39
Packit Service 360c39
	/* Walk through the resource groups saving everything within */
Packit Service 360c39
	for (n = osi_first(&sbd.rgtree); n; n = osi_next(n)) {
Packit Service 360c39
		rgd = (struct rgrp_tree *)n;
Packit Service 360c39
		if (gfs2_rgrp_read(&sbd, rgd) == 0) { /* was read in okay */
Packit Service 360c39
			gfs2_rgrp_relse(rgd);
Packit Service 360c39
			continue; /* ignore it */
Packit Service 360c39
		}
Packit Service 360c39
		/* If we get here, it's because we have an rgrp in the rindex
Packit Service 360c39
		   file that can't be read in. So attempt to repair it.
Packit Service 360c39
		   If we find a damaged rgrp or bitmap, fix the metadata.
Packit Service 360c39
		   Then scan all its blocks: if we find a dinode, set the
Packit Service 360c39
		   repaired bitmap to GFS2_BLKST_DINODE. Set all others to
Packit Service 360c39
		   GFS2_BLKST_USED so fsck can sort it out. If we set them
Packit Service 360c39
		   to FREE, fsck would just nuke it all. */
Packit Service 360c39
		printf("Resource group at block %llu (0x%llx) appears to be "
Packit Service 360c39
		       "damaged. Attempting to fix it (in reverse order).\n",
Packit Service 360c39
		       (unsigned long long)rgd->ri.ri_addr,
Packit Service 360c39
		       (unsigned long long)rgd->ri.ri_addr);
Packit Service 360c39
Packit Service 360c39
		for (b = rgd->ri.ri_length - 1; b >= 0; b--) {
Packit Service 360c39
			int mtype = (b ? GFS2_METATYPE_RB : GFS2_METATYPE_RG);
Packit Service 360c39
			struct gfs2_meta_header *mh;
Packit Service 360c39
Packit Service 360c39
			printf("Bitmap #%d:", b);
Packit Service 360c39
			rbh = bread(&sbd, rgd->ri.ri_addr + b);
Packit Service 360c39
			if (gfs2_check_meta(rbh, mtype)) { /* wrong type */
Packit Service 360c39
				printf("Damaged. Repairing...");
Packit Service 360c39
				/* Fix the meta header */
Packit Service 360c39
				memset(rbh->b_data, 0, sbd.bsize);
Packit Service 360c39
				mh = (struct gfs2_meta_header *)rbh->b_data;
Packit Service 360c39
				mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
Packit Service 360c39
				mh->mh_type = cpu_to_be32(mtype);
Packit Service 360c39
				if (b)
Packit Service 360c39
					mh->mh_format =
Packit Service 360c39
						cpu_to_be32(GFS2_FORMAT_RB);
Packit Service 360c39
				else
Packit Service 360c39
					mh->mh_format =
Packit Service 360c39
						cpu_to_be32(GFS2_FORMAT_RG);
Packit Service 360c39
				bmodified(rbh);
Packit Service 360c39
				/* Count the dinode blocks */
Packit Service 360c39
				dinodes_found = count_dinode_blks(rgd, b, rbh);
Packit Service 360c39
			} else { /* bitmap info is okay: tally it. */
Packit Service 360c39
				printf("Undamaged. Analyzing...");
Packit Service 360c39
				dinodes_found = count_dinode_bits(rbh);
Packit Service 360c39
			}
Packit Service 360c39
			printf("Dinodes found: %d\n", dinodes_found);
Packit Service 360c39
			dinodes_total += dinodes_found;
Packit Service 360c39
			if (b == 0) { /* rgrp itself was damaged */
Packit Service 360c39
				rgd->rg.rg_dinodes = dinodes_total;
Packit Service 360c39
				rgd->rg.rg_free = 0;
Packit Service 360c39
			}
Packit Service 360c39
			brelse(rbh);
Packit Service 360c39
		}
Packit Service 360c39
		rgs_fixed++;
Packit Service 360c39
	}
Packit Service 360c39
	if (rgs_fixed)
Packit Service 360c39
		printf("%d resource groups fixed.\n"
Packit Service 360c39
		       "You should run fsck.gfs2 to reconcile the bitmaps.\n",
Packit Service 360c39
		       rgs_fixed);
Packit Service 360c39
	else
Packit Service 360c39
		printf("All resource groups are okay. No repairs needed.\n");
Packit Service 360c39
	exit(0);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* parameterpass1 - pre-processing for command-line parameters              */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void parameterpass1(int argc, char *argv[], int i)
Packit Service 360c39
{
Packit Service 360c39
	if (!strcasecmp(argv[i], "-V")) {
Packit Service 360c39
		printf("%s version %s (built %s %s)\n",
Packit Service 360c39
		       argv[0], VERSION, __DATE__, __TIME__);
Packit Service 360c39
		printf("%s\n", REDHAT_COPYRIGHT);
Packit Service 360c39
		exit(0);
Packit Service 360c39
	}
Packit Service 360c39
	else if (!strcasecmp(argv[i], "-h") ||
Packit Service 360c39
		 !strcasecmp(argv[i], "-help") ||
Packit Service 360c39
		 !strcasecmp(argv[i], "-usage")) {
Packit Service 360c39
		usage();
Packit Service 360c39
		exit(0);
Packit Service 360c39
	}
Packit Service 360c39
	else if (!strcasecmp(argv[i], "-c")) {
Packit Service 360c39
		i++;
Packit Service 360c39
		color_scheme = atoi(argv[i]);
Packit Service 360c39
	}
Packit Service 360c39
	else if (!strcasecmp(argv[i], "-p") ||
Packit Service 360c39
		 !strcasecmp(argv[i], "-print")) {
Packit Service 360c39
		termlines = 0; /* initial value--we'll figure
Packit Service 360c39
				  it out later */
Packit Service 360c39
		dmode = GFS2_MODE;
Packit Service 360c39
	}
Packit Service 360c39
	else if (!strcasecmp(argv[i], "-d") ||
Packit Service 360c39
		 !strcasecmp(argv[i], "-details"))
Packit Service 360c39
		details = 1;
Packit Service 360c39
	else if (!strcasecmp(argv[i], "savemeta"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcasecmp(argv[i], "savemetaslow"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcasecmp(argv[i], "savergs"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcasecmp(argv[i], "printsavedmeta")) {
Packit Service 360c39
		if (dmode == INIT_MODE)
Packit Service 360c39
			dmode = GFS2_MODE;
Packit Service 360c39
		restoremeta(argv[i+1], argv[i+2], TRUE);
Packit Service 360c39
	} else if (!strcasecmp(argv[i], "restoremeta")) {
Packit Service 360c39
		if (dmode == INIT_MODE)
Packit Service 360c39
			dmode = HEX_MODE; /* hopefully not used */
Packit Service 360c39
		restoremeta(argv[i+1], argv[i+2], FALSE);
Packit Service 360c39
	} else if (!strcmp(argv[i], "rgcount"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcmp(argv[i], "rgflags"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcmp(argv[i], "rgrepair"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcmp(argv[i], "rg"))
Packit Service 360c39
		termlines = 0;
Packit Service 360c39
	else if (!strcasecmp(argv[i], "-x"))
Packit Service 360c39
		dmode = HEX_MODE;
Packit Service 360c39
	else if (device == NULL && strchr(argv[i],'/')) {
Packit Service 360c39
		device = argv[i];
Packit Service 360c39
	}
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
/* process_parameters - process commandline parameters                      */
Packit Service 360c39
/* pass - we make two passes through the parameters; the first pass gathers */
Packit Service 360c39
/*        normals parameters, device name, etc.  The second pass is for     */
Packit Service 360c39
/*        figuring out what structures to print out.                        */
Packit Service 360c39
/* ------------------------------------------------------------------------ */
Packit Service 360c39
static void process_parameters(int argc, char *argv[], int pass)
Packit Service 360c39
{
Packit Service 360c39
	int i;
Packit Service 360c39
	uint64_t keyword_blk;
Packit Service 360c39
Packit Service 360c39
	if (argc < 2) {
Packit Service 360c39
		usage();
Packit Service 360c39
		die("no device specified\n");
Packit Service 360c39
	}
Packit Service 360c39
	for (i = 1; i < argc; i++) {
Packit Service 360c39
		if (!pass) { /* first pass */
Packit Service 360c39
			parameterpass1(argc, argv, i);
Packit Service 360c39
			continue;
Packit Service 360c39
		}
Packit Service 360c39
		/* second pass */
Packit Service 360c39
		if (!strcasecmp(argv[i], "-s")) {
Packit Service 360c39
			i++;
Packit Service 360c39
			if (i >= argc - 1) {
Packit Service 360c39
				printf("Error: starting block not specified "
Packit Service 360c39
				       "with -s.\n");
Packit Service 360c39
				printf("%s -s [starting block | keyword] "
Packit Service 360c39
				       "<device>\n", argv[0]);
Packit Service 360c39
				printf("For example: %s -s \"rg 3\" "
Packit Service 360c39
				       "/dev/exxon_vg/exxon_lv\n", argv[0]);
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
			starting_blk = check_keywords(argv[i]);
Packit Service 360c39
			continue;
Packit Service 360c39
		}
Packit Service 360c39
		if (termlines || strchr(argv[i],'/')) /* if print or slash */
Packit Service 360c39
			continue;
Packit Service 360c39
Packit Service 360c39
		if (!strncmp(argv[i], "journal", 7) && isdigit(argv[i][7]) &&
Packit Service 360c39
		    strcmp(argv[i+1], "field")) {
Packit Service 360c39
			int blk = 0;
Packit Service 360c39
Packit Service 360c39
			if (i < argc - 1 && isdigit(argv[i + 1][0])) {
Packit Service 360c39
				if (argv[i + 1][0]=='0' && argv[i + 1][1]=='x')
Packit Service 360c39
					sscanf(argv[i + 1], "%x", &blk);
Packit Service 360c39
				else
Packit Service 360c39
					blk = atoi(argv[i + 1]);
Packit Service 360c39
			}
Packit Service 360c39
			dump_journal(argv[i], blk);
Packit Service 360c39
			continue;
Packit Service 360c39
		}
Packit Service 360c39
		keyword_blk = check_keywords(argv[i]);
Packit Service 360c39
		if (keyword_blk)
Packit Service 360c39
			push_block(keyword_blk);
Packit Service 360c39
		else if (!strcasecmp(argv[i], "-x"))
Packit Service 360c39
			dmode = HEX_MODE;
Packit Service 360c39
		else if (argv[i][0] == '-') /* if it starts with a dash */
Packit Service 360c39
			; /* ignore it--meant for pass == 0 */
Packit Service 360c39
		else if (!strcmp(argv[i], "identify"))
Packit Service 360c39
			identify = TRUE;
Packit Service 360c39
		else if (!strcmp(argv[i], "size")) {
Packit Service 360c39
			printf("Device size: %llu (0x%llx)\n",
Packit Service 360c39
			       (unsigned long long)max_block,
Packit Service 360c39
			       (unsigned long long)max_block);
Packit Service 360c39
			exit(EXIT_SUCCESS);
Packit Service 360c39
		} else if (!strcmp(argv[i], "rgcount"))
Packit Service 360c39
			rgcount();
Packit Service 360c39
		else if (!strcmp(argv[i], "field")) {
Packit Service 360c39
			i++;
Packit Service 360c39
			if (i >= argc - 1) {
Packit Service 360c39
				printf("Error: field not specified.\n");
Packit Service 360c39
				printf("Format is: %s -p <block> field "
Packit Service 360c39
				       "<field> [newvalue]\n", argv[0]);
Packit Service 360c39
				gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
			process_field(argv[i], argv[i + 1]);
Packit Service 360c39
		} else if (!strcmp(argv[i], "blocktype")) {
Packit Service 360c39
			find_print_block_type();
Packit Service 360c39
		} else if (!strcmp(argv[i], "blockrg")) {
Packit Service 360c39
			find_print_block_rg(0);
Packit Service 360c39
		} else if (!strcmp(argv[i], "blockbits")) {
Packit Service 360c39
			find_print_block_rg(1);
Packit Service 360c39
		} else if (!strcmp(argv[i], "blockalloc")) {
Packit Service 360c39
			if (isdigit(argv[i + 1][0])) {
Packit Service 360c39
				int newval;
Packit Service 360c39
Packit Service 360c39
				if (argv[i + 1][0]=='0' && argv[i + 1][1]=='x')
Packit Service 360c39
					sscanf(argv[i + 1], "%x", &newval);
Packit Service 360c39
				else
Packit Service 360c39
					newval = (uint64_t)atoi(argv[i + 1]);
Packit Service 360c39
				find_change_block_alloc(&newval);
Packit Service 360c39
			} else {
Packit Service 360c39
				find_change_block_alloc(NULL);
Packit Service 360c39
			}
Packit Service 360c39
		} else if (!strcmp(argv[i], "find")) {
Packit Service 360c39
			find_metablockoftype(argv[i + 1], 1);
Packit Service 360c39
		} else if (!strcmp(argv[i], "rgflags")) {
Packit Service 360c39
			int rg, set = FALSE;
Packit Service 360c39
			uint32_t new_flags = 0;
Packit Service 360c39
Packit Service 360c39
			i++;
Packit Service 360c39
			if (i >= argc - 1) {
Packit Service 360c39
				printf("Error: rg # not specified.\n");
Packit Service 360c39
				printf("Format is: %s rgflags rgnum"
Packit Service 360c39
				       "[newvalue]\n", argv[0]);
Packit Service 360c39
				gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
			if (argv[i][0]=='0' && argv[i][1]=='x')
Packit Service 360c39
				sscanf(argv[i], "%"SCNx32, &rg;;
Packit Service 360c39
			else
Packit Service 360c39
				rg = atoi(argv[i]);
Packit Service 360c39
			i++;
Packit Service 360c39
			if (i < argc - 1 &&
Packit Service 360c39
			    isdigit(argv[i][0])) {
Packit Service 360c39
				set = TRUE;
Packit Service 360c39
				if (argv[i][0]=='0' && argv[i][1]=='x')
Packit Service 360c39
					sscanf(argv[i], "%"SCNx32, &new_flags);
Packit Service 360c39
				else
Packit Service 360c39
					new_flags = atoi(argv[i]);
Packit Service 360c39
			}
Packit Service 360c39
			set_rgrp_flags(rg, new_flags, set, FALSE);
Packit Service 360c39
			gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
			exit(EXIT_SUCCESS);
Packit Service 360c39
		} else if (!strcmp(argv[i], "rg")) {
Packit Service 360c39
			int rg;
Packit Service 360c39
				
Packit Service 360c39
			i++;
Packit Service 360c39
			if (i >= argc - 1) {
Packit Service 360c39
				printf("Error: rg # not specified.\n");
Packit Service 360c39
				printf("Format is: %s rg rgnum\n", argv[0]);
Packit Service 360c39
				gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
			rg = atoi(argv[i]);
Packit Service 360c39
			if (!strcasecmp(argv[i + 1], "find")) {
Packit Service 360c39
				temp_blk = get_rg_addr(rg);
Packit Service 360c39
				push_block(temp_blk);
Packit Service 360c39
			} else {
Packit Service 360c39
				set_rgrp_flags(rg, 0, FALSE, TRUE);
Packit Service 360c39
				gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
				exit(EXIT_SUCCESS);
Packit Service 360c39
			}
Packit Service 360c39
		} else if (!strcmp(argv[i], "rgbitmaps")) {
Packit Service 360c39
			int rg, bmap;
Packit Service 360c39
			uint64_t rgblk;
Packit Service 360c39
			struct rgrp_tree *rgd;
Packit Service 360c39
Packit Service 360c39
			i++;
Packit Service 360c39
			if (i >= argc - 1) {
Packit Service 360c39
				printf("Error: rg # not specified.\n");
Packit Service 360c39
				printf("Format is: %s rgbitmaps rgnum\n",
Packit Service 360c39
				       argv[0]);
Packit Service 360c39
				gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
			rg = atoi(argv[i]);
Packit Service 360c39
			rgblk = get_rg_addr(rg);
Packit Service 360c39
			rgd = gfs2_blk2rgrpd(&sbd, rgblk);
Packit Service 360c39
			if (rgd == NULL) {
Packit Service 360c39
				printf("Error: rg # is invalid.\n");
Packit Service 360c39
				gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
				exit(EXIT_FAILURE);
Packit Service 360c39
			}
Packit Service 360c39
			for (bmap = 0; bmap < rgd->ri.ri_length; bmap++)
Packit Service 360c39
				push_block(rgblk + bmap);
Packit Service 360c39
		}
Packit Service 360c39
		else if (!strcmp(argv[i], "rgrepair"))
Packit Service 360c39
			rg_repair();
Packit Service 360c39
		else if (!strcasecmp(argv[i], "savemeta")) {
Packit Service 360c39
			getgziplevel(argv, &i);
Packit Service 360c39
			savemeta(argv[i+2], 0, gziplevel);
Packit Service 360c39
		} else if (!strcasecmp(argv[i], "savemetaslow")) {
Packit Service 360c39
			getgziplevel(argv, &i);
Packit Service 360c39
			savemeta(argv[i+2], 1, gziplevel);
Packit Service 360c39
		} else if (!strcasecmp(argv[i], "savergs")) {
Packit Service 360c39
			getgziplevel(argv, &i);
Packit Service 360c39
			savemeta(argv[i+2], 2, gziplevel);
Packit Service 360c39
		} else if (isdigit(argv[i][0])) { /* decimal addr */
Packit Service 360c39
			sscanf(argv[i], "%"SCNd64, &temp_blk);
Packit Service 360c39
			push_block(temp_blk);
Packit Service 360c39
		} else {
Packit Service 360c39
			fprintf(stderr,"I don't know what '%s' means.\n",
Packit Service 360c39
				argv[i]);
Packit Service 360c39
			usage();
Packit Service 360c39
			exit(EXIT_FAILURE);
Packit Service 360c39
		}
Packit Service 360c39
	} /* for */
Packit Service 360c39
}/* process_parameters */
Packit Service 360c39
Packit Service 360c39
int main(int argc, char *argv[])
Packit Service 360c39
{
Packit Service 360c39
	int i, j, fd;
Packit Service 360c39
Packit Service 360c39
	indirect = malloc(sizeof(struct iinfo));
Packit Service 360c39
	if (!indirect)
Packit Service 360c39
		die("Out of memory.");
Packit Service 360c39
	memset(indirect, 0, sizeof(struct iinfo));
Packit Service 360c39
	memset(start_row, 0, sizeof(start_row));
Packit Service 360c39
	memset(lines_per_row, 0, sizeof(lines_per_row));
Packit Service 360c39
	memset(end_row, 0, sizeof(end_row));
Packit Service 360c39
	memset(edit_row, 0, sizeof(edit_row));
Packit Service 360c39
	memset(edit_col, 0, sizeof(edit_col));
Packit Service 360c39
	memset(edit_size, 0, sizeof(edit_size));
Packit Service 360c39
	memset(last_entry_onscreen, 0, sizeof(last_entry_onscreen));
Packit Service 360c39
	dmode = INIT_MODE;
Packit Service 360c39
	sbd.bsize = 4096;
Packit Service 360c39
	block = starting_blk = 0x10;
Packit Service 360c39
	for (i = 0; i < BLOCK_STACK_SIZE; i++) {
Packit Service 360c39
		blockstack[i].dmode = HEX_MODE;
Packit Service 360c39
		blockstack[i].block = block;
Packit Service 360c39
		for (j = 0; j < DMODES; j++) {
Packit Service 360c39
			blockstack[i].start_row[j] = 0;
Packit Service 360c39
			blockstack[i].end_row[j] = 0;
Packit Service 360c39
			blockstack[i].edit_row[j] = 0;
Packit Service 360c39
			blockstack[i].edit_col[j] = 0;
Packit Service 360c39
			blockstack[i].lines_per_row[j] = 0;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
Packit Service 360c39
	edit_row[GFS2_MODE] = 10; /* Start off at root inode
Packit Service 360c39
				     pointer in superblock */
Packit Service 360c39
	termlines = 30;  /* assume interactive mode until we find -p */
Packit Service 360c39
	process_parameters(argc, argv, 0);
Packit Service 360c39
	if (dmode == INIT_MODE)
Packit Service 360c39
		dmode = HEX_MODE;
Packit Service 360c39
Packit Service 360c39
	fd = open(device, O_RDWR);
Packit Service 360c39
	if (fd < 0)
Packit Service 360c39
		die("can't open %s: %s\n", device, strerror(errno));
Packit Service 360c39
	max_block = lseek(fd, 0, SEEK_END) / sbd.bsize;
Packit Service 360c39
Packit Service 360c39
	read_superblock(fd);
Packit Service 360c39
	if (read_rindex())
Packit Service 360c39
		exit(-1);
Packit Service 360c39
	max_block = lseek(fd, 0, SEEK_END) / sbd.bsize;
Packit Service 360c39
	if (sbd.gfs1)
Packit Service 360c39
		edit_row[GFS2_MODE]++;
Packit Service 360c39
	else if (read_master_dir() != 0)
Packit Service 360c39
		exit(-1);
Packit Service 360c39
Packit Service 360c39
	process_parameters(argc, argv, 1); /* get what to print from cmdline */
Packit Service 360c39
Packit Service 360c39
	block = blockstack[0].block = starting_blk * (4096 / sbd.bsize);
Packit Service 360c39
Packit Service 360c39
	if (termlines)
Packit Service 360c39
		interactive_mode();
Packit Service 360c39
	else { /* print all the structures requested */
Packit Service 360c39
		i = 0;
Packit Service 360c39
		while (blockhist > 0) {
Packit Service 360c39
			block = blockstack[i + 1].block;
Packit Service 360c39
			if (!block)
Packit Service 360c39
				break;
Packit Service 360c39
			display(identify, 0, 0, 0);
Packit Service 360c39
			if (!identify) {
Packit Service 360c39
				display_extended();
Packit Service 360c39
				printf("-------------------------------------" \
Packit Service 360c39
				       "-----------------");
Packit Service 360c39
				eol(0);
Packit Service 360c39
			}
Packit Service 360c39
			block = pop_block();
Packit Service 360c39
			i++;
Packit Service 360c39
		}
Packit Service 360c39
	}
Packit Service 360c39
	close(fd);
Packit Service 360c39
	if (indirect)
Packit Service 360c39
		free(indirect);
Packit Service 360c39
	gfs2_rgrp_free(&sbd.rgtree);
Packit Service 360c39
 	exit(EXIT_SUCCESS);
Packit Service 360c39
}