/*
 * Copyright 1996-2004 by Hans Reiser, licensing governed by 
 * reiserfsprogs/README
 */

#define _GNU_SOURCE

#include "includes.h"
#include <stdarg.h>
#include <limits.h>
#include <printf.h>
#include <limits.h>
#include <time.h>

#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)
#  include <uuid/uuid.h>
#endif

#define PA_KEY		(PA_LAST)
#define PA_BUFFER_HEAD	(PA_LAST + 1)
#define PA_ITEM_HEAD	(PA_LAST + 2)
#define PA_DISK_CHILD	(PA_LAST + 3)


static int _arginfo_b (const struct printf_info *info, size_t n, int *argtypes) {
    if (n > 0)
	argtypes[0] = PA_BUFFER_HEAD | PA_FLAG_PTR;
    return 1;
}

static int _arginfo_K (const struct printf_info *info, size_t n, int *argtypes) {
    if (n > 0)
	argtypes[0] = PA_KEY | PA_FLAG_PTR;
    return 1;
}

static int _arginfo_H (const struct printf_info *info, size_t n, int *argtypes) {
    if (n > 0)
	argtypes[0] = PA_ITEM_HEAD | PA_FLAG_PTR;
    return 1;
}

static int _arginfo_y (const struct printf_info *info, size_t n, int *argtypes) {
    if (n > 0)
	argtypes[0] = PA_DISK_CHILD | PA_FLAG_PTR;
    return 1;
}

static int _arginfo_M (const struct printf_info *info, size_t n, int *argtypes) {
    if (n > 0)
	argtypes[0] = PA_INT | PA_FLAG_SHORT | PA_FLAG_PTR;
    return 1;
}

static int _arginfo_U (const struct printf_info *info, size_t n, int *argtypes) {
    if (n > 0)
	argtypes[0] = (PA_CHAR|PA_FLAG_PTR);
    return 1;
}

#define FPRINTF \
    if (len == -1) {\
	return -1;\
    }\
    len = fprintf (stream, "%*s",\
		   info->left ? -info->width : info->width, buffer);\
    free (buffer);\
    return len;\


/* %b */
static int print_block_head (FILE * stream,
			     const struct printf_info *info,
			     const void *const *args)
{
    const struct buffer_head * bh;
    char * buffer;
    int len;

    bh = *((const struct buffer_head **)(args[0]));
    len = asprintf (&buffer, "level=%d, nr_items=%d, free_space=%d rdkey",
		    B_LEVEL (bh), B_NR_ITEMS (bh), B_FREE_SPACE (bh));
    FPRINTF;
}


/* %K */
static int print_short_key (FILE * stream,
			    const struct printf_info *info,
			    const void *const *args)
{
    const struct key * key;
    char * buffer;
    int len;

    key = *((const struct key **)(args[0]));
    len = asprintf (&buffer, "[%u %u]", get_key_dirid (key),
		    get_key_objectid (key));
    FPRINTF;
}


/* %k */
static int print_key (FILE * stream,
		      const struct printf_info *info,
		      const void *const *args)
{
    const struct key * key;
    char * buffer;
    int len;

    key = *((const struct key **)(args[0]));
    len = asprintf (&buffer, "[%u %u 0x%Lx %s (%d)]",  
		    get_key_dirid (key), get_key_objectid (key),
		    (unsigned long long)get_offset (key), key_of_what (key), get_type (key));
    FPRINTF;
}


/* %H */
static int print_item_head (FILE * stream,
			    const struct printf_info *info,
			    const void *const *args)
{
    const struct item_head * ih;
    char * buffer;
    int len;

    ih = *((const struct item_head **)(args[0]));
    len = asprintf (&buffer, "%u %u 0x%Lx %s (%d), "
		    "len %u, location %u entry count %u, fsck need %u, format %s",
		    get_key_dirid (&ih->ih_key), get_key_objectid (&ih->ih_key),
		    (unsigned long long)get_offset (&ih->ih_key), key_of_what (&ih->ih_key),
		    get_type (&ih->ih_key), get_ih_item_len (ih), get_ih_location (ih),
		    get_ih_entry_count (ih), get_ih_flags (ih),
		    get_ih_key_format (ih) == KEY_FORMAT_2 ? "new" : 
		    ((get_ih_key_format (ih) == KEY_FORMAT_1) ? "old" : "BAD"));
    FPRINTF;
}


static int print_disk_child (FILE * stream,
			     const struct printf_info *info,
			     const void *const *args)
{
    const struct disk_child * dc;
    char * buffer;
    int len;

    dc = *((const struct disk_child **)(args[0]));
    len = asprintf (&buffer, "[dc_number=%lu, dc_size=%u]", get_dc_child_blocknr (dc),
		    get_dc_child_size (dc));
    FPRINTF;
}


char ftypelet (mode_t mode)
{
    if (S_ISBLK (mode))
	return 'b';
    if (S_ISCHR (mode))
	return 'c';
    if (S_ISDIR (mode))
	return 'd';
    if (S_ISREG (mode))
	return '-';
    if (S_ISFIFO (mode))
	return 'p';
    if (S_ISLNK (mode))
	return 'l';
    if (S_ISSOCK (mode))
	return 's';
    return '?';
}


static int rwx (FILE * stream, mode_t mode)
{
    return fprintf (stream, "%c%c%c",
		    (mode & S_IRUSR) ? 'r' : '-',
		    (mode & S_IWUSR) ? 'w' : '-',
		    (mode & S_IXUSR) ? 'x' : '-');
}


/* %M */
static int print_sd_mode (FILE * stream,
			  const struct printf_info *info,
			  const void *const *args)
{
    int len = 0;
    __u16 mode;

    mode = *(mode_t *)args[0];
    len = fprintf (stream, "%c", ftypelet (mode));
    len += rwx (stream, (mode & 0700) << 0);
    len += rwx (stream, (mode & 0070) << 3);
    len += rwx (stream, (mode & 0007) << 6);
    return len;
}

/* %U */
static int print_sd_uuid (FILE * stream,
			  const struct printf_info *info,
			  const void *const *args)
{
#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)
    const unsigned char *uuid = *((const unsigned char **)(args[0]));
    char buf[37];

    buf[36] = '\0';
    uuid_unparse(uuid, buf);
    return fprintf(stream, "%s", buf);
#else
    return fprintf(stream, "<no libuuid installed>");
#endif
}

void reiserfs_warning (FILE * fp, const char * fmt, ...) 
{
    static int registered = 0;
    va_list args;

    if (!registered) {
	registered = 1;
	
	register_printf_function ('K', print_short_key, _arginfo_K);
	register_printf_function ('k', print_key, _arginfo_K);
	register_printf_function ('H', print_item_head, _arginfo_H);
	register_printf_function ('b', print_block_head, _arginfo_b);
	register_printf_function ('y', print_disk_child, _arginfo_y);
	register_printf_function ('M', print_sd_mode, _arginfo_M);
	register_printf_function ('U', print_sd_uuid, _arginfo_U);
    }

    va_start (args, fmt);
    vfprintf (fp, fmt, args);
    va_end (args);
}


static char * vi_type (struct virtual_item * vi)
{
    static char *types[]={"directory", "direct", "indirect", "stat data"};

    if (vi->vi_type & VI_TYPE_STAT_DATA)
	return types[3];
    if (vi->vi_type & VI_TYPE_INDIRECT)
	return types[2];
    if (vi->vi_type & VI_TYPE_DIRECT)
	return types[1];
    if (vi->vi_type & VI_TYPE_DIRECTORY)
	return types[0];

    reiserfs_panic ("vi_type: 6000: unknown type (0x%x)", vi->vi_type);
    return NULL;
}


void print_virtual_node (struct virtual_node * vn)
{
    int i, j;
  
    printf ("VIRTUAL NODE CONTAINS %d items, has size %d,%s,%s, ITEM_POS=%d POS_IN_ITEM=%d MODE=\'%c\'\n",
	    vn->vn_nr_item, vn->vn_size,
	    (vn->vn_vi[0].vi_type & VI_TYPE_LEFT_MERGEABLE )? "left mergeable" : "", 
	    (vn->vn_vi[vn->vn_nr_item - 1].vi_type & VI_TYPE_RIGHT_MERGEABLE) ? "right mergeable" : "",
	    vn->vn_affected_item_num, vn->vn_pos_in_item, vn->vn_mode);


    for (i = 0; i < vn->vn_nr_item; i ++) {
	printf ("%s %d %d", vi_type (&vn->vn_vi[i]), i, vn->vn_vi[i].vi_item_len);
	if (vn->vn_vi[i].vi_entry_sizes)
	{
	    printf ("It is directory with %d entries: ", vn->vn_vi[i].vi_entry_count);
	    for (j = 0; j < vn->vn_vi[i].vi_entry_count; j ++)
		printf ("%d ", vn->vn_vi[i].vi_entry_sizes[j]);
	}
	printf ("\n");
    }
}


void print_path (struct tree_balance * tb, struct path * path)
{
    int offset = path->path_length;
    struct buffer_head * bh;

    printf ("Offset    Bh     (b_blocknr, b_count) Position Nr_item\n");
    while ( offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
	bh = PATH_OFFSET_PBUFFER (path, offset);
	printf ("%6d %10p (%9lu, %7d) %8d %7d\n", offset, 
		bh, bh ? bh->b_blocknr : 0, bh ? bh->b_count : 0,
		PATH_OFFSET_POSITION (path, offset), bh ? B_NR_ITEMS (bh) : -1);
	
	offset --;
    }
}



void print_directory_item (FILE * fp, reiserfs_filsys_t * fs,
			   struct buffer_head * bh, struct item_head * ih)
{
    int i;
    int namelen;
    struct reiserfs_de_head * deh;
    char * name;
/*    static char namebuf [80];*/

    if (!I_IS_DIRECTORY_ITEM (ih))
	return;

    //printk ("\n%2%-25s%-30s%-15s%-15s%-15s\n", "    Name", "length", "Object key", "Hash", "Gen number", "Status");
    reiserfs_warning (fp, "%3s: %-25s%s%-22s%-12s%s\n", "###", "Name", "length", "    Object key", "   Hash", "Gen number");
    deh = B_I_DEH (bh, ih);
    for (i = 0; i < get_ih_entry_count (ih); i ++, deh ++) {
	if (dir_entry_bad_location (deh, ih, i == 0 ? 1 : 0)) {
	    reiserfs_warning (fp, "%3d: wrong entry location %u, deh_offset %u\n",
			      i, get_deh_location (deh), get_deh_offset (deh));
	    continue;
	}
	if (i && dir_entry_bad_location (deh - 1, ih, ((i - 1) == 0) ? 1 : 0))
	    /* previous entry has bad location so we can not calculate entry
               length */
	    namelen = 25;
	else
	    namelen = name_in_entry_length (ih, deh, i);

	name = name_in_entry (deh, i);
	reiserfs_warning (fp, "%3d: \"%-25.*s\"(%3d)%20K%12d%5d, loc %u, state %x %s\n", 
			  i, namelen, name, namelen,
			  (struct key *)&(deh->deh2_dir_id),
			  GET_HASH_VALUE (get_deh_offset (deh)),
			  GET_GENERATION_NUMBER (get_deh_offset (deh)),
			  get_deh_location (deh), get_deh_state (deh),
			  code2name (find_hash_in_use (name, namelen, get_deh_offset (deh),
						       fs ? get_sb_hash_code (fs->fs_ondisk_sb) : UNSET_HASH)));
	/*fs ? (is_properly_hashed (fs, name, namelen, deh_offset (deh)) ? "" : "(BROKEN)") : "??");*/
    }
}


//
// printing of indirect item
//
static void start_new_sequence (__u32 * start, int * len, __u32 new)
{
    *start = new;
    *len = 1;
}


static int sequence_finished (__u32 start, int * len, __u32 new)
{
    if (le32_to_cpu (start) == INT_MAX)
	return 1;

    if (start == 0 && new == 0) {
	(*len) ++;
	return 0;
    }
    if (start != 0 && (le32_to_cpu (start) + *len) == le32_to_cpu (new)) {
	(*len) ++;
	return 0;
    }
    return 1;
}

static void print_sequence (FILE * fp, __u32 start, int len)
{
    if (start == INT_MAX)
	return;

    if (len == 1)
	reiserfs_warning (fp, " %u", le32_to_cpu (start));
    else
	reiserfs_warning (fp, " %u(%d)", le32_to_cpu (start), len);
}


void print_indirect_item (FILE * fp, struct buffer_head * bh, int item_num)
{
    struct item_head * ih;
    unsigned int j;
    __u32 * unp, prev = INT_MAX;
    int num;

    ih = B_N_PITEM_HEAD (bh, item_num);
    unp = (__u32 *)B_I_PITEM (bh, ih);

    if (get_ih_item_len (ih) % UNFM_P_SIZE)
	reiserfs_warning (fp, "print_indirect_item: invalid item len");  

    reiserfs_warning (fp, "%d pointer%s\n[", I_UNFM_NUM (ih),
                      I_UNFM_NUM (ih) != 1 ? "s" : "" );
    for (j = 0; j < I_UNFM_NUM (ih); j ++) {
	if (sequence_finished (prev, &num, d32_get(unp, j))) {
	    print_sequence (fp, prev, num);
	    start_new_sequence (&prev, &num, d32_get(unp, j));
	}
    }
    print_sequence (fp, prev, num);
    reiserfs_warning (fp, "]\n");
}


char timebuf[256];

char * timestamp (time_t t)
{
    strftime (timebuf, 256, "%d/%Y %T", localtime (&t));
    return timebuf;
}

static int print_stat_data (FILE * fp, struct buffer_head * bh, struct item_head * ih, int alltimes)
{
    int retval;
    

    /* we cannot figure out if it is new stat data or old by key_format
       macro. Stat data's key looks identical in both formats */
    if (get_ih_key_format (ih) == KEY_FORMAT_1) {
        struct stat_data_v1 * sd_v1 = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
	reiserfs_warning (fp, "(OLD SD), mode %M, size %u, nlink %u, uid %u, FDB %u, mtime %s blocks %u",
		sd_v1_mode(sd_v1), sd_v1_size(sd_v1), sd_v1_nlink(sd_v1),
                sd_v1_uid(sd_v1), sd_v1_first_direct_byte(sd_v1), timestamp
                (sd_v1_mtime(sd_v1)), sd_v1_blocks(sd_v1));
	retval = (S_ISLNK (sd_v1_mode(sd_v1))) ? 1 : 0;
        if (alltimes)
            reiserfs_warning (fp, "%s %s\n", timestamp (sd_v1_ctime(sd_v1)),
                timestamp (sd_v1_atime(sd_v1)));
    } else {
        struct stat_data * sd = (struct stat_data *)B_I_PITEM (bh, ih);
	reiserfs_warning (fp, "(NEW SD), mode %M, size %Lu, nlink %u, mtime %s blocks %u, uid %u",
		sd_v2_mode(sd), sd_v2_size(sd), sd_v2_nlink(sd),
		timestamp (sd_v2_mtime(sd)), sd_v2_blocks(sd), sd_v2_uid(sd));
	retval = (S_ISLNK (sd_v2_mode(sd))) ? 1 : 0;
        if (alltimes)
            reiserfs_warning (fp, "%s %s\n", timestamp (sd_v2_ctime(sd)),
                timestamp (sd_v2_atime(sd)));
    }

    reiserfs_warning (fp, "\n");
    return retval;
}


/* used by debugreiserfs/scan.c */
void reiserfs_print_item (FILE * fp, struct buffer_head * bh,
			  struct item_head * ih)
{
    reiserfs_warning (fp, "block %lu, item %d: %H\n",
	bh->b_blocknr, (ih - B_N_PITEM_HEAD (bh, 0))/sizeof(struct item_head), ih);
    if (is_stat_data_ih (ih)) {
	print_stat_data (fp, bh, ih, 0/*all times*/);
	return;
    }
    if (is_indirect_ih (ih)) {
	print_indirect_item (fp, bh, ih - B_N_PITEM_HEAD (bh, 0));
	return;
    }
    if (is_direct_ih (ih)) {
	reiserfs_warning (fp, "direct item: block %lu, start %d, %d bytes\n",
			  bh->b_blocknr, get_ih_location (ih), get_ih_item_len (ih));
	return;
    }

    print_directory_item (fp, 0, bh, ih);    
}


/* this prints internal nodes (4 keys/items in line) (dc_number,
   dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
   dc_size)...*/
static int print_internal (FILE * fp, struct buffer_head * bh, int first, int last)
{
    struct key * key;
    struct disk_child * dc;
    int i;
    int from, to;

    if (!is_internal_node (bh))
	return 1;

    if (first == -1) {
	from = 0;
	to = B_NR_ITEMS (bh);
    } else {
	from = first;
	to = last < B_NR_ITEMS (bh) ? last : B_NR_ITEMS (bh);
    }

    reiserfs_warning (fp, "INTERNAL NODE (%lu) contains %b\n",  bh->b_blocknr, bh);

    dc = B_N_CHILD (bh, from);
    reiserfs_warning (fp, "PTR %d: %y ", from, dc);

    for (i = from, key = B_N_PDELIM_KEY (bh, from), dc ++; i < to; i ++, key ++, dc ++) {
	reiserfs_warning (fp, "KEY %d: %20k PTR %d: %20y ", i, key, i + 1, dc);
	if (i && i % 4 == 0)
	    reiserfs_warning (fp, "\n");
    }
    reiserfs_warning (fp, "\n");
    return 0;
}



static int is_symlink = 0;
static int print_leaf (FILE * fp, reiserfs_filsys_t * fs, struct buffer_head * bh,
		       int print_mode, int first, int last)
{
    struct block_head * blkh;
    struct item_head * ih;
    int i;
    int from, to;
    int real_nr, nr;

    if (!is_tree_node (bh, DISK_LEAF_NODE_LEVEL))
	return 1;
    
    blkh = B_BLK_HEAD (bh);
    ih = B_N_PITEM_HEAD (bh,0);
    real_nr = leaf_count_ih(bh->b_data, bh->b_size);
    nr = get_blkh_nr_items((struct block_head *)bh->b_data);

    reiserfs_warning (fp,
		      "\n===================================================================\n");
    reiserfs_warning (fp, "LEAF NODE (%lu) contains %b (real items %d)\n",
		      bh->b_blocknr, bh, real_nr);

    if (!(print_mode & PRINT_TREE_DETAILS)) {
	reiserfs_warning (fp, "FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
			   &(ih->ih_key), &((ih + real_nr - 1)->ih_key));
	return 0;
    }

    if (first < 0 || first > real_nr - 1) 
	from = 0;
    else 
	from = first;

    if (last < 0 || last > real_nr)
	to = real_nr;
    else
	to = last;


    reiserfs_warning (fp,
		       "-------------------------------------------------------------------------------\n"
		       "|###|type|ilen|f/sp| loc|fmt|fsck|                   key                      |\n"
		       "|   |    |    |e/cn|    |   |need|                                            |\n");
    for (i = from; i < to; i++) {
	reiserfs_warning (fp,
			  "-------------------------------------------------------------------------------\n"
			  "|%3d|%30H|%s\n", i, ih + i, i >= nr ? " DELETED" : "");

	if (I_IS_STAT_DATA_ITEM(ih+i)) {
	    is_symlink = print_stat_data (fp, bh, ih + i, 0/*all times*/);
	    continue;
	}

	if (I_IS_DIRECTORY_ITEM(ih+i)) {
	    print_directory_item (fp, fs, bh, ih+i);
	    continue;
	}

	if (I_IS_INDIRECT_ITEM(ih+i)) {
	    print_indirect_item (fp, bh, i);
	    continue;
	}

	if (I_IS_DIRECT_ITEM(ih+i)) {
	    int j = 0;
	    if (is_symlink || print_mode & PRINT_DIRECT_ITEMS) {
		reiserfs_warning (fp, "\"");
		while (j < get_ih_item_len (&ih[i])) {
		    if (B_I_PITEM(bh,ih+i)[j] == 10)
			reiserfs_warning (fp, "\\n");
		    else
			reiserfs_warning (fp, "%c", B_I_PITEM(bh,ih+i)[j]);
		    j ++;
		}
		reiserfs_warning (fp, "\"\n");
	    }
	    continue;
	}
    }
    reiserfs_warning (fp, "===================================================================\n");
    return 0;
}


void print_journal_params (FILE * fp, struct journal_params * jp)
{
    reiserfs_warning (fp, "\tDevice [0x%x]\n", get_jp_journal_dev (jp));
    reiserfs_warning (fp, "\tMagic [0x%x]\n", get_jp_journal_magic (jp));

    reiserfs_warning (fp, "\tSize %u blocks (including 1 for journal header) (first block %u)\n",
		      get_jp_journal_size (jp) + 1,
		      get_jp_journal_1st_block (jp));
    reiserfs_warning (fp, "\tMax transaction length %u blocks\n", get_jp_journal_max_trans_len (jp));
    reiserfs_warning (fp, "\tMax batch size %u blocks\n", get_jp_journal_max_batch (jp));
    reiserfs_warning (fp, "\tMax commit age %u\n", get_jp_journal_max_commit_age (jp));
    /*reiserfs_warning (fp, "\tMax transaction age %u\n", get_jp_journal_max_trans_age (jp));*/
}

/* return 1 if this is not super block */
int print_super_block (FILE * fp, reiserfs_filsys_t * fs, char * file_name,
			      struct buffer_head * bh, int short_print)
{
    struct reiserfs_super_block * sb = (struct reiserfs_super_block *)(bh->b_data);
    dev_t rdev;
    int format = 0;
    __u16 state;
    time_t last_check = get_sb_v2_lastcheck(sb);
    char last_check_buf[26];

    if (!does_look_like_super_block (sb))
	return 1;

    rdev = misc_device_rdev(file_name);

    reiserfs_warning (fp, "Reiserfs super block in block %lu on 0x%x of ",
		      bh->b_blocknr, rdev);
    switch (get_reiserfs_format (sb)) {
    case REISERFS_FORMAT_3_5:
	reiserfs_warning (fp, "format 3.5 with ");
        format = 1;
	break;
    case REISERFS_FORMAT_3_6:
	reiserfs_warning (fp, "format 3.6 with ");
        format = 2;
	break;
    default:
	reiserfs_warning (fp, "unknown format with ");
	break;
    }
    if (is_reiserfs_jr_magic_string (sb))
	reiserfs_warning (fp, "non-");
    reiserfs_warning (fp, "standard journal\n");
    if (short_print) {
	reiserfs_warning (fp, "Blocks (total/free): %u/%u by %d bytes\n",
		get_sb_block_count (sb), get_sb_free_blocks (sb), get_sb_block_size (sb));
    } else {
	reiserfs_warning (fp, "Count of blocks on the device: %u\n", get_sb_block_count (sb));
	reiserfs_warning (fp, "Number of bitmaps: %u", get_sb_bmap_nr (sb));
	if (get_sb_bmap_nr (sb) != reiserfs_fs_bmap_nr(fs))
		reiserfs_warning (fp, " (really uses %u)", reiserfs_fs_bmap_nr(fs));
	reiserfs_warning (fp, "\nBlocksize: %d\n", get_sb_block_size (sb));
	reiserfs_warning (fp, "Free blocks (count of blocks - used [journal, "
		      "bitmaps, data, reserved] blocks): %u\n", get_sb_free_blocks (sb));
	reiserfs_warning (fp, "Root block: %u\n", get_sb_root_block (sb));
    }
    reiserfs_warning (fp, "Filesystem is %sclean\n",
		      (get_sb_umount_state (sb) == FS_CLEANLY_UMOUNTED) ? "" : "NOT ");

    if (short_print)
    	return 0;
    reiserfs_warning (fp, "Tree height: %d\n", get_sb_tree_height (sb));
    reiserfs_warning (fp, "Hash function used to sort names: %s\n",
		      code2name (get_sb_hash_code (sb)));
    reiserfs_warning (fp, "Objectid map size %d, max %d\n", get_sb_oid_cursize (sb),
		      get_sb_oid_maxsize (sb));
    reiserfs_warning (fp, "Journal parameters:\n");
    print_journal_params (fp, sb_jp (sb));
    reiserfs_warning (fp, "Blocks reserved by journal: %u\n",
		      get_sb_reserved_for_journal (sb));
    state = get_sb_fs_state (sb);
    reiserfs_warning (fp, "Fs state field: 0x%x:\n", state);
    if ((state & FS_FATAL) == FS_FATAL)
	reiserfs_warning (fp, "\tFATAL corruptions exist.\n");
    if ((state & FS_ERROR) == FS_ERROR)
	reiserfs_warning (fp, "\t some corruptions exist.\n");
    if ((state & IO_ERROR) == IO_ERROR)
	reiserfs_warning (fp, "\tI/O corruptions exist.\n");

    reiserfs_warning (fp, "sb_version: %u\n", get_sb_version (sb));
    if (format == 2) {
        reiserfs_warning (fp, "inode generation number: %u\n", get_sb_v2_inode_generation (sb));
        reiserfs_warning (fp, "UUID: %U\n", sb->s_uuid);
        reiserfs_warning (fp, "LABEL: %.16s\n", sb->s_label);
        reiserfs_warning (fp, "Set flags in SB:\n");
	if ((get_sb_v2_flag (sb, reiserfs_attrs_cleared)))
	    reiserfs_warning (fp, "\tATTRIBUTES CLEAN\n");
	reiserfs_warning(fp, "Mount count: %u\n",
			 get_sb_v2_mnt_count(sb));
	reiserfs_warning(fp, "Maximum mount count: ");
	if (get_sb_v2_max_mnt_count(sb) &&
	    get_sb_v2_max_mnt_count(sb) != USHRT_MAX)
		reiserfs_warning(fp, "%u\n", get_sb_v2_max_mnt_count(sb));
	else if (get_sb_v2_max_mnt_count(sb) == USHRT_MAX)
		reiserfs_warning(fp, "Administratively disabled.\n");
	else
		reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
	if (last_check) {
		ctime_r(&last_check, last_check_buf);
		reiserfs_warning(fp, "Last fsck run: %s", last_check_buf);
	} else
		reiserfs_warning(fp, "Last fsck run: Never with a version "
				 "that supports this feature.\n");
	reiserfs_warning(fp, "Check interval in days: ");
	if (get_sb_v2_check_interval(sb) &&
	    get_sb_v2_check_interval(sb) != UINT_MAX)
		reiserfs_warning(fp, "%u\n",
			 get_sb_v2_check_interval(sb) / (24*60*60));
	else if (get_sb_v2_check_interval(sb) == UINT_MAX)
		reiserfs_warning(fp, "Administratively disabled.\n");
	else
		reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
    }

    return 0;
}


void print_filesystem_state (FILE * fp, reiserfs_filsys_t * fs)
{
    reiserfs_warning (fp, "\nFilesystem state: ");
    if (reiserfs_is_fs_consistent (fs))
	reiserfs_warning (fp, "consistent\n\n");
    else
	reiserfs_warning (fp, "consistency is not checked after last mounting\n\n");
}



static int print_desc_block (FILE * fp, struct buffer_head * bh)
{
    if (memcmp(get_jd_magic (bh), JOURNAL_DESC_MAGIC, 8))
	return 1;

    reiserfs_warning (fp, "Desc block %lu (j_trans_id %ld, j_mount_id %ld, j_len %ld)\n",
		      bh->b_blocknr, get_desc_trans_id (bh),
		      get_desc_mount_id (bh), get_desc_trans_len (bh));

    return 0;
}


void print_block (FILE * fp, reiserfs_filsys_t * fs, 
		  struct buffer_head * bh, ...)//int print_mode, int first, int last)
{
    va_list args;
    int mode, first, last;
    char * file_name;

    va_start (args, bh);

    if ( ! bh ) {
	reiserfs_warning (stderr, "print_block: buffer is NULL\n");
	return;
    }

    mode = va_arg (args, int);
    first = va_arg (args, int);
    last = va_arg (args, int);
    file_name = (fs) ? fs->fs_file_name : NULL ;
    if (print_desc_block (fp, bh))
        if (print_super_block (fp, fs, file_name, bh, 0))
	    if (print_leaf (fp, fs, bh, mode, first, last))
		if (print_internal (fp, bh, first, last))
		    reiserfs_warning (fp, "Block %lu contains unformatted data\n", bh->b_blocknr);
}


void print_tb (int mode, int item_pos, int pos_in_item, struct tree_balance * tb, char * mes)
{
  unsigned int h = 0;
  struct buffer_head * tbSh, * tbFh;


  if (!tb)
    return;

  printf ("\n********************** PRINT_TB for %s *******************\n", mes);
  printf ("MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n", mode, item_pos, pos_in_item);
  printf ("*********************************************************************\n");

  printf ("* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n");
/*
01234567890123456789012345678901234567890123456789012345678901234567890123456789
       1        2         3         4         5         6         7         8
  printk ("*********************************************************************\n");
*/
  
  
  for (h = 0; h < sizeof(tb->insert_size) / sizeof (tb->insert_size[0]); h ++) {
    if (PATH_H_PATH_OFFSET (tb->tb_path, h) <= tb->tb_path->path_length && 
	PATH_H_PATH_OFFSET (tb->tb_path, h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
      tbSh = PATH_H_PBUFFER (tb->tb_path, h);
      tbFh = PATH_H_PPARENT (tb->tb_path, h);
    } else {
      /*      printk ("print_tb: h=%d, PATH_H_PATH_OFFSET=%d, path_length=%d\n", 
	      h, PATH_H_PATH_OFFSET (tb->tb_path, h), tb->tb_path->path_length);*/
      tbSh = 0;
      tbFh = 0;
    }
    printf ("* %u * %3lu(%2lu) * %3lu(%2lu) * %3lu(%2lu) * %5lu * %5lu * %5lu * %5lu * %5lu *\n",
	    h, 
	    tbSh ? tbSh->b_blocknr : ~0ul,
	    tbSh ? tbSh->b_count : ~0ul,
	    tb->L[h] ? tb->L[h]->b_blocknr : ~0ul,
	    tb->L[h] ? tb->L[h]->b_count : ~0ul,
	    tb->R[h] ? tb->R[h]->b_blocknr : ~0ul,
	    tb->R[h] ? tb->R[h]->b_count : ~0ul,
	    tbFh ? tbFh->b_blocknr : ~0ul,
	    tb->FL[h] ? tb->FL[h]->b_blocknr : ~0ul,
	    tb->FR[h] ? tb->FR[h]->b_blocknr : ~0ul,
	    tb->CFL[h] ? tb->CFL[h]->b_blocknr : ~0ul,
	    tb->CFR[h] ? tb->CFR[h]->b_blocknr : ~0ul);
  }

  printf ("*********************************************************************\n");


  /* print balance parameters for leaf level */
  h = 0;
  printf ("* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n");
  printf ("* %d * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
	  h, tb->insert_size[h], tb->lnum[h], tb->lbytes, tb->rnum[h],tb->rbytes, tb->blknum[h], 
	  tb->s0num, tb->s1num,tb->s1bytes,  tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[h], tb->rkey[h]);


/* this prints balance parameters for non-leaf levels */
  do {
    h++;
    printf ("* %d * %4d * %2d *    * %2d *    * %2d *\n",
    h, tb->insert_size[h], tb->lnum[h], tb->rnum[h], tb->blknum[h]);
  } while (tb->insert_size[h]);

  printf ("*********************************************************************\n");


  /* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
  for (h = 0; h < sizeof (tb->FEB) / sizeof (tb->FEB[0]); h++)
    printf("%s%p (%lu %d)", h == 0 ? "FEB list: " : ", ", tb->FEB[h], tb->FEB[h] ? tb->FEB[h]->b_blocknr : 0,
	    tb->FEB[h] ? tb->FEB[h]->b_count : 0);
  printf ("\n");

  printf ("********************** END OF PRINT_TB *******************\n\n");
}


static void print_bmap_block (FILE * fp, int i, unsigned long block, char * map, int blocks, int silent, int blocksize)
{
    int j, k;
    int bits = blocksize * 8;
    int zeros = 0, ones = 0;
  

    reiserfs_warning (fp, "#%d: block %lu: ", i, block);

    blocks = blocksize * 8;

    if (misc_test_bit (0, map)) {
	/* first block addressed by this bitmap block is used */
	ones ++;
	if (!silent)
	    reiserfs_warning (fp, "Busy (%d-", i * bits);
	for (j = 1; j < blocks; j ++) {
	    while (misc_test_bit (j, map)) {
		ones ++;
		if (j == blocks - 1) {
		    if (!silent)
			reiserfs_warning (fp, "%d)\n", j + i * bits);
		    goto end;
		}
		j++;
	    }
	    if (!silent)
		reiserfs_warning (fp, "%d) Free(%d-", j - 1 + i * bits, j + i * bits);

	    while (!misc_test_bit (j, map)) {
		zeros ++;
		if (j == blocks - 1) {
		    if (!silent)
			reiserfs_warning (fp, "%d)\n", j + i * bits);
		    goto end;
		}
		j++;
	    }
	    if (!silent)
		reiserfs_warning (fp, "%d) Busy(%d-", j - 1 + i * bits, j + i * bits);

	    j --;
	end:
	    /* to make gcc 3.2 do not sware here */;
	}
    } else {
	/* first block addressed by this bitmap is free */
	zeros ++;
	if (!silent)
	    reiserfs_warning (fp, "Free (%d-", i * bits);
	for (j = 1; j < blocks; j ++) {
	    k = 0;
	    while (!misc_test_bit (j, map)) {
		k ++;
		if (j == blocks - 1) {
		    if (!silent)
			reiserfs_warning (fp, "%d)\n", j + i * bits);
		    zeros += k;
		    goto end2;
		}
		j++;
	    }
	    zeros += k;
	    if (!silent)
		reiserfs_warning (fp, "%d) Busy(%d-", j - 1 + i * bits, j + i * bits);
	    
	    k = 0;
	    while (misc_test_bit (j, map)) {
		ones ++;
		if (j == blocks - 1) {
		    if (!silent)
			reiserfs_warning (fp, "%d)\n", j + i * bits);
		    ones += k;
		    goto end2;
		}
		j++;
	    }
	    ones += k;
	    if (!silent)
		reiserfs_warning (fp, "%d) Free(%d-", j - 1 + i * bits, j + i * bits);
	
	    j --;
	end2:
	    /* to make gcc 3.2 do not sware here */;
	}
    }

    reiserfs_warning (fp, "used %d, free %d\n", ones, zeros);
}


/* read bitmap of disk and print details */
void print_bmap (FILE * fp, reiserfs_filsys_t * fs, int silent)
{
    struct reiserfs_super_block * sb;
    int bmap_nr;
    int i;
    int bits_per_block;
    int blocks;
    unsigned long block;
    struct buffer_head * bh;


    sb = fs->fs_ondisk_sb;
    bmap_nr = reiserfs_fs_bmap_nr(fs);
    bits_per_block = fs->fs_blocksize * 8;
    blocks = bits_per_block;

    reiserfs_warning (fp, "Bitmap blocks are:\n");
    block = fs->fs_super_bh->b_blocknr + 1;
    for (i = 0; i < bmap_nr; i ++) {
	bh = bread (fs->fs_dev, block, fs->fs_blocksize);
	if (!bh) {
	    reiserfs_warning (stderr, "print_bmap: bread failed for %d: %lu\n", i, block);
	    continue;
	}
	if (i == bmap_nr - 1)
	    if (get_sb_block_count (sb) % bits_per_block)
		blocks = get_sb_block_count (sb) % bits_per_block;
	print_bmap_block (fp, i, block, bh->b_data, blocks, silent, fs->fs_blocksize);
	brelse (bh);

	if (spread_bitmaps (fs))
	    block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8);
	else
	    block ++;
	
    }
}



void print_objectid_map (FILE * fp, reiserfs_filsys_t * fs)
{
    int i;
    struct reiserfs_super_block * sb;
    __u32 * omap;


    sb = fs->fs_ondisk_sb;
    if (fs->fs_format == REISERFS_FORMAT_3_6)
	omap = (__u32 *)(sb + 1);
    else if (fs->fs_format == REISERFS_FORMAT_3_5)
	omap = (__u32 *)((struct reiserfs_super_block_v1 *)sb + 1);
    else {
	reiserfs_warning (fp, "print_objectid_map: proper signature is not found\n");
	return;
    }
	
    reiserfs_warning (fp, "Map of objectids (super block size %d)\n",
		      (char *)omap - (char *)sb);
      
    for (i = 0; i < get_sb_oid_cursize (sb); i ++) {
	if (i % 2 == 0) {
	    reiserfs_warning(fp, "busy(%u-%u) ", le32_to_cpu (omap[i]),
			     le32_to_cpu (omap[i+1]) - 1); 
	} else {
	    reiserfs_warning(fp, "free(%u-%u) ", le32_to_cpu (omap[i]),
			    ((i+1) == get_sb_oid_cursize (sb)) ? 
			    ~(__u32)0 : (le32_to_cpu (omap[i+1]) - 1));
	}
    }

    reiserfs_warning (fp, "\nObject id array has size %d (max %d):", 
		      get_sb_oid_cursize (sb), get_sb_oid_maxsize (sb));
  
    for (i = 0; i < get_sb_oid_cursize (sb); i ++)
	reiserfs_warning (fp, "%s%u ", i % 2 ? "" : "*", le32_to_cpu (omap[i])); 
    reiserfs_warning (fp, "\n");

}


void print_journal_header (reiserfs_filsys_t * fs)
{
    struct reiserfs_journal_header * j_head;


    j_head = (struct reiserfs_journal_header *)(fs->fs_jh_bh->b_data);
    reiserfs_warning (stdout, "Journal header (block #%lu of %s):\n"
		      "\tj_last_flush_trans_id %ld\n"
		      "\tj_first_unflushed_offset %ld\n"
		      "\tj_mount_id %ld\n", 
		      fs->fs_jh_bh->b_blocknr, fs->fs_j_file_name,
		      get_jh_last_flushed (j_head),
		      get_jh_replay_start_offset (j_head),
		      get_jh_mount_id (j_head));
    print_journal_params (stdout, &j_head->jh_journal);
}


static void print_trans_element (reiserfs_filsys_t * fs, reiserfs_trans_t * trans,
				 unsigned int index, unsigned long in_journal, 
				 unsigned long in_place)
{
    if (index % 8 == 0)
	reiserfs_warning (stdout, "#%d\t", index);

    reiserfs_warning (stdout, "%lu->%lu%s ",  in_journal, in_place,
		      block_of_bitmap (fs, in_place) ? "B" : "");
    if ((index + 1) % 8 == 0 || index == trans->trans_len - 1)
	reiserfs_warning (stdout, "\n");
}


void print_one_transaction (reiserfs_filsys_t * fs, reiserfs_trans_t * trans)
{
    reiserfs_warning (stdout, "Mountid %u, transid %u, desc %lu, length %u, commit %lu\n",
		      trans->mount_id, trans->trans_id,
		      trans->desc_blocknr,
		      trans->trans_len, trans->commit_blocknr);
    for_each_block (fs, trans, print_trans_element);
}


/* print all valid transactions and found dec blocks */
void print_journal (reiserfs_filsys_t * fs)
{
    if (!reiserfs_journal_opened (fs)) {
	reiserfs_warning (stderr, "print_journal: journal is not opened\n");
	return;
    }
    print_journal_header (fs);

    for_each_transaction (fs, print_one_transaction);
}

