Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3153110
gfs2hex.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
gfs2hex.c
View Options
/******************************************************************************
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
** Copyright (C) 2004 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made availale to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
** of the GNU General Public License v.2.
**
*******************************************************************************
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
#include <linux/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <curses.h>
#include "hexedit.h"
#include "linux_endian.h"
#define WANT_GFS_CONVERSION_FUNCTIONS
#include <linux/gfs2_ondisk.h>
#include "gfs2hex.h"
/* from libgfs2: */
#include "libgfs2.h"
#include "ondisk.h"
extern struct gfs2_sb sb;
extern char *buf;
extern struct gfs2_dinode di;
extern uint64_t bufsize;
extern int line, termlines;
extern char edit_fmt[80];
extern char estring[1024];
extern int edit_mode INIT(0);
extern int edit_row[DMODES], edit_col[DMODES];
extern int edit_size[DMODES], last_entry_onscreen[DMODES];
extern char edit_fmt[80];
extern enum dsp_mode dmode INIT(HEX_MODE); /* display mode */
void eol(int col) /* end of line */
{
if (termlines) {
line++;
move(line, col);
}
else {
printf("\n");
for (; col > 0; col--)
printf(" ");
}
}
void print_gfs2(const char *fmt, ...)
{
va_list args;
char string[NAME_MAX];
memset(string, 0, sizeof(string));
va_start(args, fmt);
vsprintf(string, fmt, args);
if (termlines)
printw("%s", string);
else
printf("%s", string);
va_end(args);
}
void check_highlight(int highlight)
{
if (!termlines || line >= termlines) /* If printing or out of bounds */
return;
if (dmode == HEX_MODE) {
if (line == (edit_row[dmode] * lines_per_row[dmode]) + 4) {
if (highlight) {
COLORS_HIGHLIGHT;
last_entry_onscreen[dmode] = print_entry_ndx;
}
else
COLORS_NORMAL;
}
}
else {
if ((line * lines_per_row[dmode]) - 4 ==
(edit_row[dmode] - start_row[dmode]) * lines_per_row[dmode]) {
if (highlight) {
COLORS_HIGHLIGHT;
last_entry_onscreen[dmode] = print_entry_ndx;
}
else
COLORS_NORMAL;
}
}
}
void print_it(const char *label, const char *fmt, const char *fmt2, ...)
{
va_list args;
char tmp_string[NAME_MAX];
const char *fmtstring;
int decimalsize;
if (!termlines || line < termlines) {
va_start(args, fmt2);
check_highlight(TRUE);
if (termlines) {
move(line,0);
printw("%s", label);
move(line,24);
}
else {
if (!strcmp(label, " "))
printf("%-11s", label);
else
printf("%-24s", label);
}
vsprintf(tmp_string, fmt, args);
if (termlines)
printw("%s", tmp_string);
else
printf("%s", tmp_string);
check_highlight(FALSE);
if (fmt2) {
decimalsize = strlen(tmp_string);
va_end(args);
va_start(args, fmt2);
vsprintf(tmp_string, fmt2, args);
check_highlight(TRUE);
if (termlines) {
move(line, 50);
printw("%s", tmp_string);
}
else {
int i;
for (i=20 - decimalsize; i > 0; i--)
printf(" ");
printf("%s", tmp_string);
}
check_highlight(FALSE);
}
else {
if (strstr(fmt,"X") || strstr(fmt,"x"))
fmtstring="(hex)";
else if (strstr(fmt,"s"))
fmtstring="";
else
fmtstring="(decimal)";
if (termlines) {
move(line, 50);
printw("%s", fmtstring);
}
else
printf("%s", fmtstring);
}
if (termlines) {
refresh();
if (line == (edit_row[dmode] * lines_per_row[dmode]) + 4) {
strcpy(estring, tmp_string);
strcpy(edit_fmt, fmt);
edit_size[dmode] = strlen(estring);
COLORS_NORMAL;
}
last_entry_onscreen[dmode] = (line / lines_per_row[dmode]) - 4;
}
eol(0);
va_end(args);
}
}
int indirect_dirent(struct indirect_info *indir, char *ptr, int d)
{
struct gfs2_dirent de;
gfs2_dirent_in(&de, ptr);
if (de.de_rec_len < sizeof(struct gfs2_dirent) ||
de.de_rec_len > 4096 - sizeof(struct gfs2_dirent))
return -1;
if (de.de_inum.no_addr) {
indir->block = de.de_inum.no_addr;
memcpy(&indir->dirent[d].dirent, &de, sizeof(struct gfs2_dirent));
memcpy(&indir->dirent[d].filename,
ptr + sizeof(struct gfs2_dirent), de.de_name_len);
indir->dirent[d].filename[de.de_name_len] = '\0';
indir->dirent[d].block = de.de_inum.no_addr;
indir->is_dir = TRUE;
indir->dirents++;
}
return de.de_rec_len;
}
/******************************************************************************
*******************************************************************************
**
** do_dinode_extended()
**
** Description:
**
** Input(s):
**
** Output(s):
**
** Returns:
**
*******************************************************************************
******************************************************************************/
void do_dinode_extended(struct gfs2_dinode *di, char *buf)
{
unsigned int x, y;
uint64_t p, last;
int isdir = !!(S_ISDIR(di->di_mode)) ||
(gfs1 && di->__pad1 == GFS_FILE_DIR);
indirect_blocks = 0;
memset(indirect, 0, sizeof(indirect));
if (di->di_height > 0) {
/* Indirect pointers */
for (x = sizeof(struct gfs2_dinode); x < bufsize;
x += sizeof(uint64_t)) {
p = be64_to_cpu(*(uint64_t *)(buf + x));
if (p) {
indirect->ii[indirect_blocks].block = p;
indirect->ii[indirect_blocks].is_dir = FALSE;
indirect_blocks++;
}
}
}
else if (isdir && !(di->di_flags & GFS2_DIF_EXHASH)) {
int skip = 0;
/* Directory Entries: */
indirect->ii[0].dirents = 0;
indirect->ii[0].block = block;
indirect->ii[0].is_dir = TRUE;
for (x = sizeof(struct gfs2_dinode); x < bufsize; x += skip) {
skip = indirect_dirent(indirect->ii,
buf + x,
indirect->ii[0].dirents);
if (skip <= 0)
break;
}
}
else if (isdir &&
(di->di_flags & GFS2_DIF_EXHASH) &&
di->di_height == 0) {
/* Leaf Pointers: */
last = be64_to_cpu(*(uint64_t *)(buf + sizeof(struct gfs2_dinode)));
for (x = sizeof(struct gfs2_dinode), y = 0;
y < (1 << di->di_depth);
x += sizeof(uint64_t), y++) {
p = be64_to_cpu(*(uint64_t *)(buf + x));
if (p != last || ((y + 1) * sizeof(uint64_t) == di->di_size)) {
struct gfs2_buffer_head *tmp_bh;
int skip = 0, direntcount = 0;
struct gfs2_leaf leaf;
unsigned int bufoffset;
if (last >= max_block)
break;
tmp_bh = bread(&sbd, last);
gfs2_leaf_in(&leaf, tmp_bh->b_data);
indirect->ii[indirect_blocks].dirents = 0;
for (direntcount = 0, bufoffset = sizeof(struct gfs2_leaf);
bufoffset < bufsize;
direntcount++, bufoffset += skip) {
skip = indirect_dirent(&indirect->ii[indirect_blocks],
tmp_bh->b_data + bufoffset,
direntcount);
if (skip <= 0)
break;
}
brelse(tmp_bh, not_updated);
indirect->ii[indirect_blocks].block = last;
indirect_blocks++;
last = p;
} /* if not duplicate pointer */
} /* for indirect pointers found */
} /* if exhash */
}/* do_dinode_extended */
/******************************************************************************
*******************************************************************************
**
** do_indirect_extended()
**
** Description:
**
** Input(s):
**
** Output(s):
**
** Returns:
**
*******************************************************************************
******************************************************************************/
int do_indirect_extended(char *buf, struct iinfo *iinf)
{
unsigned int x, y;
uint64_t p;
int i_blocks;
i_blocks = 0;
memset(iinf, 0, sizeof(struct iinfo));
for (x = (gfs1 ? sizeof(struct gfs_indirect):
sizeof(struct gfs2_meta_header)), y = 0;
x < bufsize;
x += sizeof(uint64_t), y++) {
p = be64_to_cpu(*(uint64_t *)(buf + x));
if (p) {
iinf->ii[i_blocks].block = p;
iinf->ii[i_blocks].is_dir = FALSE;
i_blocks++;
}
}
return i_blocks;
}
/******************************************************************************
*******************************************************************************
**
** do_leaf_extended()
**
** Description:
**
** Input(s):
**
** Output(s):
**
** Returns:
**
*******************************************************************************
******************************************************************************/
void do_leaf_extended(char *buf, struct iinfo *indir)
{
int x, i;
struct gfs2_dirent de;
x = 0;
memset(indir, 0, sizeof(indir));
/* Directory Entries: */
for (i = sizeof(struct gfs2_leaf); i < bufsize;
i += de.de_rec_len) {
gfs2_dirent_in(&de, buf + i);
if (de.de_inum.no_addr) {
indir->ii[0].block = de.de_inum.no_addr;
indir->ii[0].dirent[x].block = de.de_inum.no_addr;
memcpy(&indir->ii[0].dirent[x].dirent,
&de, sizeof(struct gfs2_dirent));
memcpy(&indir->ii[0].dirent[x].filename,
buf + i + sizeof(struct gfs2_dirent),
de.de_name_len);
indir->ii[0].dirent[x].filename[de.de_name_len] = '\0';
indir->ii[0].is_dir = TRUE;
indir->ii[0].dirents++;
x++;
}
if (de.de_rec_len <= sizeof(struct gfs2_dirent))
break;
}
}
/******************************************************************************
*******************************************************************************
**
** do_eattr_extended()
**
** Description:
**
** Input(s):
**
** Output(s):
**
** Returns:
**
*******************************************************************************
******************************************************************************/
void do_eattr_extended(char *buf)
{
struct gfs2_ea_header ea;
unsigned int x;
eol(0);
print_gfs2("Eattr Entries:");
eol(0);
for (x = sizeof(struct gfs2_meta_header); x < bufsize; x += ea.ea_rec_len)
{
eol(0);
gfs2_ea_header_in(&ea, buf + x);
gfs2_ea_header_print(&ea, buf + x + sizeof(struct gfs2_ea_header));
}
}
void gfs2_inum_print2(const char *title,struct gfs2_inum *no)
{
if (termlines) {
check_highlight(TRUE);
move(line,2);
printw(title);
check_highlight(FALSE);
}
else
printf(" %s:",title);
pv2(no, no_formal_ino, "%lld", "0x%"PRIx64);
if (!termlines)
printf(" addr:");
pv2(no, no_addr, "%lld", "0x%"PRIx64);
}
/**
* gfs2_sb_print2 - Print out a superblock
* @sb: the cpu-order buffer
*/
void gfs2_sb_print2(struct gfs2_sb *sb)
{
gfs2_meta_header_print(&sb->sb_header);
pv(sb, sb_fs_format, "%u", "0x%x");
pv(sb, sb_multihost_format, "%u", "0x%x");
pv(sb, sb_bsize, "%u", "0x%x");
pv(sb, sb_bsize_shift, "%u", "0x%x");
if (gfs1) {
gfs2_inum_print2("jindex ino", &sbd1->sb_jindex_di);
gfs2_inum_print2("rindex ino", &sbd1->sb_rindex_di);
}
else
gfs2_inum_print2("master dir", &sb->sb_master_dir);
gfs2_inum_print2("root dir ", &sb->sb_root_dir);
pv(sb, sb_lockproto, "%s", NULL);
pv(sb, sb_locktable, "%s", NULL);
if (gfs1) {
gfs2_inum_print2("quota ino ", &gfs1_quota_di);
gfs2_inum_print2("license ", &gfs1_license_di);
}
}
/******************************************************************************
*******************************************************************************
**
** int display_gfs2()
**
** Description:
** This routine...
**
** Input(s):
** *buffer -
** extended -
**
** Returns:
** 0 if OK, 1 on error.
**
*******************************************************************************
******************************************************************************/
int display_gfs2(void)
{
struct gfs2_meta_header mh;
struct gfs2_rgrp rg;
struct gfs2_leaf lf;
struct gfs_log_header lh1;
struct gfs2_log_header lh;
struct gfs2_log_descriptor ld;
struct gfs2_quota_change qc;
uint32_t magic;
magic = be32_to_cpu(*(uint32_t *)buf);
switch (magic)
{
case GFS2_MAGIC:
gfs2_meta_header_in(&mh, buf);
switch (mh.mh_type)
{
case GFS2_METATYPE_SB:
print_gfs2("Superblock:");
eol(0);
gfs2_sb_in(&sbd.sd_sb, buf);
gfs2_sb_print2(&sbd.sd_sb);
break;
case GFS2_METATYPE_RG:
print_gfs2("Resource Group Header:");
eol(0);
gfs2_rgrp_in(&rg, buf);
gfs2_rgrp_print(&rg);
break;
case GFS2_METATYPE_RB:
print_gfs2("Resource Group Bitmap:");
eol(0);
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_DI:
print_gfs2("Dinode:");
eol(0);
gfs2_dinode_print(&di);
break;
case GFS2_METATYPE_LF:
print_gfs2("Leaf:");
eol(0);
gfs2_leaf_in(&lf, buf);
gfs2_leaf_print(&lf);
break;
case GFS2_METATYPE_IN:
print_gfs2("Indirect Block:");
eol(0);
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_JD:
print_gfs2("Journaled File Block:");
eol(0);
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_LH:
print_gfs2("Log Header:");
eol(0);
if (gfs1) {
gfs_log_header_in(&lh1, buf);
gfs_log_header_print(&lh1);
} else {
gfs2_log_header_in(&lh, buf);
gfs2_log_header_print(&lh);
}
break;
case GFS2_METATYPE_LD:
print_gfs2("Log descriptor");
eol(0);
gfs2_log_descriptor_in(&ld, buf);
gfs2_log_descriptor_print(&ld);
break;
case GFS2_METATYPE_EA:
print_gfs2("Eattr Block:");
eol(0);
do_eattr_extended(buf);
break;
case GFS2_METATYPE_ED:
print_gfs2("Eattr Data Block:");
eol(0);
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_LB:
print_gfs2("Log Buffer");
eol(0);
gfs2_meta_header_print(&mh);
break;
case GFS2_METATYPE_QC:
print_gfs2("Quota Change");
eol(0);
gfs2_quota_change_in(&qc, buf);
gfs2_quota_change_print(&qc);
break;
default:
print_gfs2("Unknown metadata type");
eol(0);
break;
}
break;
default:
print_gfs2("Unknown block type");
eol(0);
break;
};
return(0);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Tue, Feb 25, 10:24 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1464786
Default Alt Text
gfs2hex.c (13 KB)
Attached To
Mode
rF Fence Agents
Attached
Detach File
Event Timeline
Log In to Comment